我发现定位服务耗尽了我的电池。但我认为这不是因为位置服务开启,而是因为某些应用程序经常使用该服务。有什么办法可以找到,哪个应用程序设置了位置服务错误(高负载)?我现在可以获取使用位置服务的应用程序列表吗?预先感谢您的任何帮助。
2 回答
据我所知,没有简单的方法来获取访问 LocationProvider 的应用程序列表。但是一个简单的诊断方法就是将请求ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION权限的App一个一个kill掉。
许多应用程序通过 onLocationChanged(...) 之类的回调获取位置数据,这使得几乎不可能在不修改 Android 系统的情况下识别您的问题。您可以修改定位服务以记录uid(通过Binder.getCallingUid())以获取当前使用定位服务的应用程序。这不是很困难,但重量很重。
编辑:
在 frameworks/base/services/java/com/android/server 下有一个 LocationManagerService.java。
一般来说,根据其Location Strategies在 Android 中有几种获取位置的方法。
LocationManager.requestLocationUpdates
您可以在 LocationManagerService.java 中查看它的实现。该方法从客户端接收 ILocationListener(Binder 对象),如果它接收到位置更新,则稍后调用此侦听器。
@Override
public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
PendingIntent intent, String packageName) {
if (request == null) request = DEFAULT_LOCATION_REQUEST;
checkPackageName(packageName);
int allowedResolutionLevel = getCallerAllowedResolutionLevel();
checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
request.getProvider());
LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel);
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
Receiver recevier = checkListenerOrIntent(listener, intent, pid, uid, packageName);
// providers may use public location API's, need to clear identity
long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
基本上,你可以通过这种方法获取应用程序的 uid,以了解有多少应用程序在请求位置更新。但是您还应该记住查看 removeUpdates 方法。
LocationManager.getLastKnownLocation
您还可以在执行此方法时注销应用程序的 uid。
修改代码后,您可以编译整个 Android 项目,安装您的应用程序,并获得您的结果。
我猜你的意思是在后台运行服务并使用 GPS?这样您就不会自己激活 GPS 但它仍在运行?在那种情况下,我无法知道所有允许在后台使用 GPS 的应用程序。您可以转到设置->应用程序并检查允许哪些应用程序使用 GPS 的权限。
一个典型的背景 GPS 用户是 facebook 应用程序(或者我猜是 google+)。希望这可以帮助。
编辑:或者,您可以在不需要 GPS 时禁用它,这样任何应用程序都无法在后台使用它。