使用谷歌Play Services Location的android系统中出现过多的Alarm Manager唤醒

使用谷歌Play Services Location的android系统中出现过多的Alarm Manager唤醒,android,memory,location,google-play-services,Android,Memory,Location,Google Play Services,我在Google Play控制台上收到了Android Vital的一份性能报告,报告中提到过多的Alarm Manager唤醒: 我使用Google Play Services的位置API在后台请求位置更新。报告显示,过度唤醒是由LocationListener中的com.google.android.location.ALARM_WAKEUP_定位器引起的 下面是导致报警的代码段: private synchronized void buildGoogleApiClient() {

我在Google Play控制台上收到了Android Vital的一份性能报告,报告中提到过多的Alarm Manager唤醒:

我使用Google Play Services的位置API在后台请求位置更新。报告显示,过度唤醒是由LocationListener中的com.google.android.location.ALARM_WAKEUP_定位器引起的

下面是导致报警的代码段:

private synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(context)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}

/**
 * Runs when a GoogleApiClient object successfully connects.
 */
@Override
public void onConnected(Bundle connectionHint) {
    try {
        // Set location request
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5 * 60000);
        mLocationRequest.setFastestInterval(60000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mLocationRequest.setMaxWaitTime(30 * 60000);

        // Create a pending intent to listening on location service when the update become available
        Intent mIntent = new Intent(context, LocationReceiver.class);
        mIntent.setAction(LocationReceiver.LOCATION_EXTRA);
        mPendingIntent = PendingIntent.getBroadcast(context, 42, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        // Permission check before launching location services
        if (ContextCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
此警报唤醒是否链接到google play services的位置API

有人知道如何解决这个问题吗?

这是一个每60秒唤醒一次设备,并使其保持唤醒状态长达15秒的问题,会导致严重的电池放电问题

通过外部用户使用手机,并教用户如何实际撤销应用程序的权限,已经出现了一些问题

解决方案 以下提供了减少应用程序电池使用量的工具

不可能为应用程序提供定制的解决方案,因为该解决方案取决于应用程序的用例和业务逻辑,以及您希望通过位置更新实现的成本效益分析

时间间隔 电池性能问题也就不足为奇了。通过以下设置:

mLocationRequest.setInterval(5 * 60000);
mLocationRequest.setFastestInterval(60000);
mLocationRequest.setMaxWaitTime(30 * 60000);
您的间隔设置为每5分钟(5*60000毫秒)更新一次。那是一天24小时。如果每5分钟更新一次:12次/小时==288次/天

最快的时间间隔设置为1分钟(60000)。虽然这是可用的,因为位置在设备上的其他地方可以访问,但它仍将在应用程序中使用电源)

最大等待时间只有30分钟。这意味着,最多该设备每天会被唤醒和轮询至少48次

设置MaxWaitTime。。。这样可以消耗更少的电池,并提供更准确的位置, 取决于设备的硬件功能。你应该设置这个 如果您不需要,则价值应尽可能大,以满足您的需求 立即地点交货

在安卓8中,谷歌将请求数量限制在一个小时之内。考虑使用此作为设置请求间隔的准则。

限制更新的数量 特定时间范围内的更新数量可能会受到限制。通过在使用更新次数后主动取消位置请求,或在请求上设置一个。通过这种方式,应用程序可以通过在应用程序内的某个触发器上创建请求进行管理,并小心地进行管理,以使其不会无休止地继续。创建流很困难,因为我不知道应用程序的用例

默认情况下,位置会不断更新,直到请求被删除 显式删除,但是您可以选择请求一组 更新。例如,如果您的应用程序只需要一个 位置,然后在传递 请求到位置客户端

停止位置更新 另一种选择是在不需要时进行管理。这些链接给出了在活动失去焦点时调用此功能的示例,但它可以在应用程序中实现,也可以在满足某些要求(在您的业务逻辑中)时实现,甚至可以让用户在应用程序本身中打开和关闭

电池优化 确保您的应用程序未被删除

取代 此外,管理将有助于根据业务逻辑对应用程序进行微调

以下内容是在更新问题之前编写的

开发者和用户可以设置应用程序更新的频率。和

对于。 您可以在发出位置请求时设置这些参数,例如:

protected void createLocationRequest() {
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
还有一个设置,这意味着应用程序将仅在用户请求更新时获取更新

对于用户。 你需要

task.addOnSuccessListener(这个,新的OnSuccessListener(){
@凌驾
成功时公共无效(位置设置响应位置设置响应){
//满足所有位置设置。客户端可以初始化
//这里有位置请求。
// ...
}
});
task.addOnFailureListener(这是新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常e){
int statusCode=((ApiException)e).getStatusCode();
开关(状态代码){
案例CommonStatusCodes.RESOLUTION_要求:
//不满足位置设置,但可以修复此问题
//通过向用户显示一个对话框。
试一试{
//通过调用startResolutionForResult()显示对话框,
//并在onActivityResult()中检查结果。
ResolvableApiException resolvable=(ResolvableApiException)e;
可解析。开始解决结果(main activity.this,
请求检查设置);
}catch(IntentSender.SendIntentException sendEx){
//忽略错误。
}
打破
案例位置设置StatusCodes.SETTINGS\u CHANGE\u不可用:
//位置设置不满意。但是,我们没有办法
//修复设置,使我们不会显示对话框。
打破
}
}
});
要在用户设置中使用位置回拨,请执行以下操作

。。。您可以使用新类代替现有类 除此之外还接收更新 要更新位置,请在设置时为您提供一个简单的回调 可能已更改,这将影响当前的 位置请求

谷歌在安卓8上发布了这个问题。 为了降低功耗,Android 8.0(API级别26) 限制后台应用程序检索用户当前文件的频率 地点。应用程序每次只能接收几次位置更新 小时

注:这些是l
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...
    }
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        int statusCode = ((ApiException) e).getStatusCode();
        switch (statusCode) {
            case CommonStatusCodes.RESOLUTION_REQUIRED:
                // Location settings are not satisfied, but this can be fixed
                // by showing the user a dialog.
                try {
                    // Show the dialog by calling startResolutionForResult(),
                    // and check the result in onActivityResult().
                    ResolvableApiException resolvable = (ResolvableApiException) e;
                    resolvable.startResolutionForResult(MainActivity.this,
                            REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException sendEx) {
                    // Ignore the error.
                }
                break;
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                // Location settings are not satisfied. However, we have no way
                // to fix the settings so we won't show the dialog.
                break;
        }
    }
});