gpt4 book ai didi

android - 使用 Google Play 服务位置在 android 中唤醒过多的警报管理器

转载 作者:行者123 更新时间:2023-12-02 05:44:42 41 4
gpt4 key购买 nike

我在 Google Play 控制台上收到了来自 Android Vital 的关于过度警报管理器唤醒的性能报告:

https://developer.android.com/topic/performance/vitals/wakeup.html

我使用来自 Google Play 服务的 Location API 在后台请求位置更新。在报告中它表明过度唤醒唤醒是由来自 LocationListener 的 com.google.android.location.ALARM_WAKEUP_LOCATOR 引起的。

在导致警报的代码 fragment 下方:

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 服务的 Location API 相关联?

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

最佳答案

Google Location api

这是 com.google.android.location.ALARM_WAKEUP_LOCATOR 的问题每 60 秒唤醒一次设备并使它们保持唤醒状态长达 15 秒,从而导致严重的电池耗电问题。

fixes通过外部电话使用 apps并教用户如何实际撤销应用程序的权限。

解决方案

下面提供了减少应用程序电池使用量的工具。

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

时间间隔

电池性能出现问题也就不足为奇了。从以下设置:

mLocationRequest.setInterval(5 * 60000);
mLocationRequest.setFastestInterval(60000);
mLocationRequest.setMaxWaitTime(30 * 60000);

您的间隔设置为每 5 分钟更新一次(5 * 60000 毫秒)。那是一天24小时。如果每 5 分钟成功更新一次:12 次/小时 == 每天 288 次。

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

最大等待时间仅为 30 分钟。这意味着设备最多每天将被唤醒和轮询至少 48 次。

Increase these times .

setMaxWaitTime ... This can consume less battery and give more accurate locations, depending on the device's hardware capabilities. You should set this value to be as large as possible for your needs if you don't need immediate location delivery. ...



在 Android 8 中,Google 将请求数量限制为只有 few per hour .考虑将此用作设置请求间隔的指南。

限制更新次数

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

setNumUpdates (int numUpdates)

By default locations are continuously updated until the request is explicitly removed, however you can optionally request a set number of updates. For example, if your application only needs a single fresh location, then call this method with a value of 1 before passing the request to the location client.



停止位置更新

另一种选择是管理 stop locations updates当不需要它们时。这些链接提供了在 Activity 失去焦点时调用它的示例,但是它可以在应用程序中实现,当满足某些要求时(在您的业务逻辑中),或者甚至通过让用户从应用程序内打开和关闭它本身。

电池优化

确保您的应用不是 ignoring battery optimizations .

移位

还管理 setSmallestDisplacement (float smallestDisplacementMeters)将有助于微调应用程序,具体取决于业务逻辑。

以下是在更新问题之前写的。

开发人员和用户都可以设置应用程序更新的频率。 intervalspriorities .

对于 developer .

您可以在发出位置请求时设置这些,例如:
protected void createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}

PRIORITY_NO_POWER还有一个设置,这意味着应用程序只会在用户要求时获取更新。

对于用户。

您将需要 Prompt the User to Change Location Settings
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;
}
}
});

manage changes在用户设置中使用位置回调。

... you can use the new LocationCallback class in place of your existing LocationListener to receive LocationAvailability updates in addition to location updates, giving you a simple callback whenever settings might have changed which will affect the current set of LocationRequests.



谷歌 has addressed Android 8 中的这个问题。

In an effort to reduce power consumption, Android 8.0 (API level 26) limits how frequently background apps can retrieve the user's current location. Apps can receive location updates only a few times each hour.

Note: These limitations apply to all apps used on devices running Android 8.0 (API level 26) or higher, regardless of an app's target SDK version.




如果使用警报管理器。

这可能与 Alarm Manager有关.

这不是一个简单的修复,最终您需要重写您如何安排更新。
  • 为了至少减缓问题,您需要调试代码并找到警报管理器调用或创建计划并减少间隔的任何实例。
  • 之后,您将需要重写应用程序的整个位置更新计划部分。

  • Fix the Problem

    Identify the places in your app where you schedule wakeup alarms and reduce the frequency that those alarms are triggered. Here are some tips:

    • Look for calls to the various set() methods in AlarmManager that include either the RTC_WAKEUP or ELAPSED_REALTIME_WAKEUP flag.
    • We recommend including your package, class, or method name in your alarm's tag name so that you can easily identify the location in your source where the alarm was set. Here are some additional tips:
      • Leave out any personally identifying information (PII) in the name, such as an email address. Otherwise, the device logs _UNKNOWN instead of the alarm name.
      • Don't get the class or method name programmatically, for example by calling getName(), because it could get obfuscated by Proguard. Instead use a hard-coded string.
      • Don't add a counter or unique identifiers to alarm tags. The system will not be able to aggregate alarms that are set that way because they all have unique identifiers.

    After fixing the problem, verify that your wakeup alarms are working as expected by running the following ADB command:

    adb shell dumpsys alarm



    此命令提供有关警报系统状态的信息
    设备上的服务。如需更多信息,请参阅 dumpsys .

    如果您对上述任何一个有特殊问题,您需要使用 mcve 发布另一个问题。 .

    要改进该应用程序,将涉及重写 Best Practices 中提到的代码。 .不要使用闹钟管理器来安排后台任务,如果手机处于 sleep 状态,定位将被视为后台任务。另外你说这是一个后台任务。使用 JobSchedulerFirebase JobDispatcher .

    如果警报管理器是更好的选择(它不在这里)重要的是在这里好好阅读 Scheduling Repeating Alarms ,但您需要 Understand the Trade-offs

    A poorly designed alarm can cause battery drain and put a significant load on servers.

    关于android - 使用 Google Play 服务位置在 android 中唤醒过多的警报管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46115912/

    41 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com