在后台服务中使用Google Play服务的LocationClient

38

我的应用程序旨在定期跟踪用户的位置并将其发送到服务器,最近我使用Google Play服务位置API更改了我的代码。

我在onStartCommand中创建了locationclient并连接到服务。

public int onStartCommand(Intent intent, int flags, int startId) {
    setUpLocationClientIfNeeded();
    if(!mLocationClient.isConnected() || !mLocationClient.isConnecting())
    mLocationClient.connect();
    return START_STICKY;

}

而在onConnected方法中,我发送了一个位置请求。

@Override
public void onConnected(Bundle arg0) {
    System.out.println("Connected ...");
    mLocationClient.requestLocationUpdates(REQUEST, this);

}

REQUEST对象是指:

 private static final LocationRequest REQUEST = LocationRequest.create()
      .setInterval(5*60*1000)      // 5 minutes
      .setFastestInterval(3*60*1000) // 3 minutes
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

现在的问题是:

  1. onLocationChanged方法没有按照给定的间隔时间(5分钟或最快间隔3分钟)被调用。从日志中可以看到,它只被调用了两到三次,之后就再也没有被调用过了(我检查了一个小时后)。

这段代码有什么问题?(我也找不到任何“disconnected”的日志)

  1. 为了解决这个问题,我尝试使用AlarmManager来定期调用任务。现在如何通过BroadcastReceiver从LocationClient中获取单个位置更新?(locationClient.getLastLocation()只会返回上一次存储的位置,而不会请求新的位置)

我遇到了非常类似的问题。我写了一个快速而简单的服务,使用AlarmManager定期运行,并每次调用getLastLocation方法。该调用显然返回一个位置,但是这个位置从未更新过。我发现打开Google Maps应用程序(可能适用于其他位置感知应用程序)会突然使我的服务接收到的位置更新正常。有什么想法吗? - Miguel Prada
2
getlastlocation 总是使用被动提供程序而不是 GPS 或网络提供程序,这意味着只有当其他应用程序(如 Google 地图)获取最新位置时,我们的应用程序才会被动地使用相同的位置。 - Thiyaga B
你是想在应用程序运行时还是在后台运行时跟踪用户位置? - ddewaele
要获取单个新的位置更新,您可以创建一个位置请求,并将setNumUpdates设置为1,如下所示:http://developer.android.com/reference/com/google/android/gms/location/LocationRequest.html#setNumUpdates(int)但是,如果由于某种原因您根本没有收到“回调”,那么这可能并不是非常有用。 - Erik Vest Zielke
你已经检查过你的服务是否还活着而没有被销毁了吗? - Kai
1个回答

35

这里提供了一个后台服务的完整源代码:

https://gist.github.com/blackcj/20efe2ac885c7297a676

尝试在你的onStartCommand方法中添加super调用。

/**
 * Keeps the service running even after the app is closed.
 * 
 */
public int onStartCommand (Intent intent, int flags, int startId)
{
    super.onStartCommand(intent, flags, startId);

    setUpLocationClientIfNeeded();
    if(!mLocationClient.isConnected() || !mLocationClient.isConnecting())
    {
        mLocationClient.connect();
    }

    return START_STICKY;
}

不错的代码片段和服务。感谢分享。快速问题 - 你是否一直保持LocationClient连接?如果是,你有遇到过任何问题或强制断开连接吗? - Java Guy
2
我没有注意到任何强制断开连接的问题。平衡电源的一个缺点是,如果用户进入了一个无法接收蜂窝信号的区域,应用程序会停止跟踪位置,直到用户再次拥有蜂窝服务。这就是它的文档所描述的工作方式,但在选择高精度和平衡电源之间进行决策时应考虑到这一点。 - blackcj
@blackcj 在你的 Github 上看了你的代码,有一个疑问。我该如何在活动中启动和停止后台服务?我的意思是,如果活动被重新启动,我想要引用已经运行的服务。谢谢。 - ggauravr
我从没想过会这么容易。locationClient = new LocationClient(this, this, this); - danny117
!mLocationClient.isConnected() || !mLocationClient.isConnecting() 总是返回 true(我认为)。我相信应该使用 && 吗? - Tony Wickham
那个链接很棒。看起来有很多建议可以改进服务。 - Zapnologica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接