Google Play Servicesの位置情報を使用したAndroidでのアラームマネージャーの過度の起動 質問する

Google Play Servicesの位置情報を使用したAndroidでのアラームマネージャーの過度の起動 質問する

Google Play Console の Android Vital から、アラーム マネージャーの過度なウェイクアップに関するパフォーマンス レポートを受け取りました。

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

Google Play サービスの Location API を使用して、バックグラウンドで位置情報の更新をリクエストしています。レポートには、過度のウェイクアップ ウェイクアップは LocationListener の com.google.android.location.ALARM_WAKEUP_LOCATOR によって発生したことが示されています。

アラームの原因となるコード スニペットは以下の通りです。

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 にリンクされていますか?

この問題を解決する方法を知っている人はいますか?

ベストアンサー1

Google ロケーション API

これは、com.google.android.location.ALARM_WAKEUP_LOCATORデバイスを 60 秒ごとに起動し、最大 15 秒間起動したままにするため、バッテリーの消耗が著しく増加します。

これまで修正外部経由の電話使用の場合アプリ実際にアプリの権限を取り消す方法をユーザーに教えます。

ソリューション

以下では、アプリのバッテリー使用量を削減するためのツールを紹介します。

アプリにカスタマイズされたソリューションを提供することは不可能です。ソリューションは、アプリのユースケースとビジネス ロジック、および位置情報の更新で何を達成したいかという費用対効果分析によって決まるためです。

時間間隔

バッテリーのパフォーマンスに問題が発生するのは当然です。次の設定から:

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

間隔は 5 分 (5 * 60000 ミリ秒) ごとに更新するように設定されています。つまり、1 日 24 時間です。これが 5 分ごとに正常に更新されると、1 時間あたり 12 回 == 1 日あたり 288 回になります。

最速の間隔は 1 分 (60000) に設定されています。これは、デバイス上の他の場所から位置情報にアクセスできるため利用可能ですが、それでもアプリの電力は消費されます。

最大待機時間はわずか 30 分です。つまり、デバイスは 1 日に最低 48 回起動され、ポーリングされることになります。

これらの時間を増やす

最大待機時間を設定する... デバイスのハードウェア機能に応じて、バッテリーの消費を抑え、より正確な位置情報を提供できます。位置情報をすぐに提供する必要がない場合は、この値を必要に応じてできるだけ大きく設定する必要があります。...

Android 8ではGoogleはリクエスト数を1時間あたり数個リクエストの間隔を設定する際のガイドラインとしてこれを使用することを検討してください。

更新回数の制限

一定時間内の更新回数を制限することができます。更新回数が使い果たされたら位置情報のリクエストを積極的にキャンセルするか、有効期限リクエストに応じて。この方法では、アプリ内の何らかのトリガーでリクエストを作成することでアプリを管理し、無限に続かないように注意深く管理できます。アプリのユースケースがわからないため、フローを作成するのは困難です。

setNumUpdates (int numUpdates)

デフォルトでは、リクエストが明示的に削除されるまでロケーションは継続的に更新されますが、オプションで更新回数を設定することもできます。たとえば、アプリケーションに必要な新しいロケーションが 1 つだけの場合は、ロケーション クライアントにリクエストを渡す前に、値 1 でこのメソッドを呼び出します。

位置情報の更新を停止

もう一つの選択肢は管理することだ停車場所の更新必要ではないときにこれを呼び出す例がリンクに示されていますが、これは、特定の要件が満たされたとき (ビジネス ロジック内) にアプリ内で実装することも、ユーザーがアプリ自体からオンとオフを切り替えられるようにすることもできます。

バッテリーの最適化

アプリがバッテリーの最適化を無視する

変位

管理もsetSmallestDisplacement (float 最小変位メーター)ビジネス ロジックに応じてアプリを微調整するのに役立ちます。

以下は質問が更新される前に書かれたものです。

アプリのアップデート頻度は開発者とユーザーの両方が設定できます。間隔そして優先事項

のために開発者

たとえば、位置情報のリクエストを行うときにこれらを設定できます。

protected void createLocationRequest() {
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}

設定もあります優先度_電源なしつまり、ユーザーが要求した場合にのみアプリは更新を取得します。

ユーザー向け。

必要となるのはユーザーに位置情報設定の変更を促す

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;
        }
    }
});

変更を管理するユーザー設定では、位置情報のコールバックを使用します。

...新しいロケーションコールバック既存のクラスの代わりにロケーションリスナー受け取る場所空き状況位置情報の更新に加えて更新も行われるため、設定が変更されて現在の LocationRequests セットに影響する可能性があるときはいつでも、簡単なコールバックが提供されます。

グーグル対処したAndroid 8 でこの問題が発生します。

Android 8.0 (API レベル 26) では、電力消費を抑えるために、バックグラウンド アプリがユーザーの現在地を取得できる頻度が制限されています。アプリは 1 時間に数回のみ位置情報の更新を受信できます。

注: これらの制限は、アプリのターゲット SDK バージョンに関係なく、Android 8.0 (API レベル 26) 以上を実行しているデバイスで使用されるすべてのアプリに適用されます。


アラーム マネージャーを使用する場合。

これは、アラームマネージャー

これは簡単な修正ではありません。最終的には、更新のスケジュール方法を書き直す必要があります。

  1. 少なくとも問題を遅くするには、コードをデバッグし、アラーム マネージャーがスケジュールを呼び出したり作成したりするインスタンスを見つけて、間隔​​を短くする必要があります。

  2. その後、アプリの位置情報更新スケジュール部分全体を書き直す必要があります。

問題を解決します

アプリ内で目覚ましアラームをスケジュールする場所を特定し、それらのアラームがトリガーされる頻度を減らします。次にいくつかのヒントを示します。

  • さまざまな電話を探してくださいセット()方法アラームマネージャー次のいずれかを含むRTC_ウェイクアップまたは ELAPSED_REALTIME_WAKEUP フラグ。
  • アラームが設定されたソース内の場所を簡単に識別できるように、アラームのタグ名にパッケージ、クラス、またはメソッド名を含めることをお勧めします。次に、追加のヒントをいくつか示します。
    • 名前には、電子メール アドレスなどの個人を特定できる情報 (PII) を含めないでください。そうしないと、デバイスはアラーム名の代わりに _UNKNOWN をログに記録します。
    • クラス名やメソッド名をプログラム的に取得しないでください。たとえば、名前を取得する()、Proguard によって難読化される可能性があるためです。代わりに、ハードコードされた文字列を使用してください。
    • アラーム タグにカウンターや一意の識別子を追加しないでください。すべてのアラームに一意の識別子があるため、そのように設定されたアラームをシステムは集約できなくなります。

問題を修正した後、次のコマンドを実行して目覚ましアラームが期待どおりに動作していることを確認します。アジア開発銀行指示:

adb シェル dumpsys アラーム

このコマンドは、デバイス上のアラームシステムサービスのステータスに関する情報を提供します。詳細については、ダンプシス

上記のいずれかに特に問題がある場合は、別の質問を投稿する必要があります。マクベ

アプリを改善するには、ここで述べたようにコードを書き直す必要があります。ベストプラクティスアラームマネージャーを使用してバックグラウンドタスクをスケジュールしないでください、そして位置情報は、携帯電話がスリープ状態の場合、バックグラウンドタスクと見なされます。さらに、バックグラウンドタスクだと言っています。ジョブスケジューラまたはFirebase ジョブディスパッチャ

アラームマネージャがより良い選択である場合(それはここにはない)ここでよく読むことが重要です繰り返しアラームのスケジュール設定、しかし、トレードオフを理解する

アラームの設計が適切でないと、バッテリーの消耗を引き起こし、サーバーに大きな負荷をかける可能性があります。

おすすめ記事