在 GPS 芯片长时间处于活动状态后,Android 设备需要重启/重启才能获取 GPS 位置
Posted
技术标签:
【中文标题】在 GPS 芯片长时间处于活动状态后,Android 设备需要重启/重启才能获取 GPS 位置【英文标题】:Android device needs restart/reboot to get GPS locations after having GPS chip active a long time 【发布时间】:2015-04-09 18:05:51 【问题描述】:我正在为 android 开发另一个 GPS 跟踪应用程序,我正在使用 Android 4.3 在 Sony Xperia SP c5302 中测试我的代码。
我创建了一个后台服务,它使用 Google Play Services 的 GoogleApiClient 来获取融合位置。我能够很好地获取位置,但几个小时后,我意识到我的 GPS 芯片停止返回位置,因为它们的精度从 10 提高到 30 或 50(这意味着除了 GPS 之外的其他提供商正在返回新位置)。
考虑到我在室内,我认为 API 决定只听网络提供商的声音,然后我走到街上(关闭了 wifi 和数据连接)并完全停止获取融合位置(我没有得到网络修复正如预期的那样,GPS芯片已经死了)。甚至谷歌地图也无法追踪到我。然后我决定在那一刻重新启动我的手机,我的应用程序和谷歌地图上的 GPS 芯片更新都很好(wifi 和数据连接仍然关闭)。
我对使用 LocationManager 的原始 Location API 尝试了相同的方法,结果相同......我必须重新启动手机才能让 GPS 芯片再次工作。
这是我使用 GoogleApiClient 的基本代码:
public class MyService extends Service
private final static String TAG = MyService.class.getSimpleName();
//GPS
private GoogleApiClient miGoogleApiClient = null;
private LocationRequest miLocationRequest = null;
private LocationRequest currLocation = null;
@Override
public void onCreate()
super.onCreate();
Log.i(TAG, "onCreate MY SERVICE");
startGPS();
@Override
public void onDestroy()
super.onDestroy();
Log.d(TAG, "onDestroy");
stopGPS();
public boolean startGPS()
Log.d(TAG, "startGPS");
try
miGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(miConnectionCallbacks)
.addOnConnectionFailedListener(miOnConnectionFailedListener)
.build();
miGoogleApiClient.connect();
return true;
catch(Exception e)
Log.d(TAG, "can't start GPS:"+e);
return false;
finallyreturn false;
public void stopGPS()
Log.d(TAG, "stopGPS");
miGoogleApiClient.disconnect();
private LocationListener miLocationListener = new LocationListener()
@Override public void onLocationChanged(Location location)
Log.d(TAG, "onLocationChanged:"+new Date(location.getTime())+", "+ location);
//...more work
currLocation = location;
;
private GoogleApiClient.ConnectionCallbacks miConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks()
@Override public void onConnected(Bundle bundle)
Log.d(TAG, "onConnected:"+bundle);
currLocation = LocationServices.FusedLocationApi.getLastLocation(miGoogleApiClient); //may be old
miLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
//.setSmallestDisplacement(10) //Won't use this for now
.setInterval(30000)
.setFastestInterval(30000);
LocationServices.FusedLocationApi.requestLocationUpdates(
miGoogleApiClient, miLocationRequest, miLocationListener);
@Override public void onConnectionSuspended(int i)
Log.d(TAG, "onConnectionSuspended:"+i);
;
private GoogleApiClient.OnConnectionFailedListener miOnConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener()
@Override public void onConnectionFailed(ConnectionResult connectionResult)
Log.d(TAG, "onConnectionFailed:"+connectionResult);
;
我知道这种方法会更快地消耗电池电量,但此应用程序是针对特定客户而非普通公众的,所以没关系。
¿这种行为是应该发生的还是我的手机有问题或我的代码有问题?我觉得特别奇怪的是,即使是 Google 地图也无法获取位置,所以我想知道我的应用程序是不是在弄乱手机本身。
编辑。
我必须重新启动手机,因为从 Android 设置菜单中关闭和打开 GPS 没有任何区别。 (我的服务日志显示,如果我停止并重新启动 GPS,它会正常启动)
【问题讨论】:
虽然它应该做同样的事情,但你可以尝试使用github.com/mcharmas/Android-ReactiveLocation,无论如何它可以为你节省很多代码行 @cYrixmorten 谢谢。这是一个有趣的图书馆。正如您所说,它使用相同的代码来处理 GoogleApiClient 但样板代码可能是一个因素。我想知道在服务上下文中使用 GoogleApi 的注意事项。我会尝试根据您的建议制作一个测试项目。 记得在我知道的onDestroy()
中退订。我自己在服务中使用它。只是为了加入另一个库,然后我使用 EventBus github.com/greenrobot/EventBus 来广播,只要有新的位置可用于更新 UI。这几乎像常规广播一样工作,但不限于可序列化的数据,而是适用于任何复杂的对象,而且它比设置广播接收器等需要更少的代码。
@cYrixmorten 事件 EventBus 似乎很棒。我以前读过它,但忘记了它的名字,从未使用过它。很高兴看到该项目仍在进行中。
@cYrixmorten 我不知道该怎么想。我只是在用 ReactiveLocation 做几个测试。我修改了示例项目并添加了与此问题中的服务类似的服务。我离开了原始设置(500 毫秒的更新时间)并工作了一个小时(时间不多,但工作)。然后我只是将设置更改为 30 秒 = 30000 毫秒,它在半小时内就被杀死了,但由于 START_STICKY 再次开始,但没有更多的位置。我将项目重新构建回 500 毫秒并重新启动手机。 5 小时后,它仍然提供 GPS 芯片位置。
【参考方案1】:
经过长时间的测试,我可以看出“问题”与设备有关。我的应用在朋友的 Nexus 4 上运行良好很长时间。
我还通过更改更新间隔让它在我的 Xperia SP 中工作
miLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5000)
也许我可以将它设置为更高的间隔。我只是确定 30 秒太多了。
为了覆盖我客户的设备,我最好的猜测是设置一些共享偏好,以便在 GPS 芯片停止提供位置的情况下设置此间隔。
【讨论】:
以上是关于在 GPS 芯片长时间处于活动状态后,Android 设备需要重启/重启才能获取 GPS 位置的主要内容,如果未能解决你的问题,请参考以下文章
许多长时间运行的 Apache 进程处于 READ 状态,一段时间后没有请求
如果 Android 设备长时间处于空闲状态,则不会收到推送通知