Gestionnaire D'alarme Excessive wakeups dans android avec Google Play Services emplacement

j'ai reçu un rapport de performance à partir d'Android Vitaux sur Google Play Console Excessive d'Alarme Gestionnaire de réveils:

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

j'utilise L'API de localisation des services Google Play pour demander des mises à jour de localisation en arrière-plan. En ce qui concerne le rapport, il montre que le réveil excessif a été causé par la com.Google.Android.emplacement.Alarme _WAKEUP_LOCATOR de LocationListener.

en dessous de l'extrait de code qui provoque les alarmes:

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

ce réveil d'alarme est-il lié à l'API de localisation des services google play?

quelqu'un sait-il comment régler ce problème?

25
demandé sur poiuytrez 2017-09-08 14:53:30
la source

1 ответов

Localisation de Google api

C'est un problème avec le com.Google.Android.emplacement.ALARM_WAKEUP_LOCATOR réveiller les appareils toutes les 60 secondes et les maintenir éveillés pendant une période pouvant aller jusqu'à 15 secondes, ce qui cause d'importants problèmes de drainage de la batterie.

Il y a eu fixe pour les utilisations par téléphone viaapplications et apprendre aux utilisateurs comment révoquer la permission d'une application.

le Solution

ce qui suit fournit les outils pour réduire l'utilisation de la batterie de l'application.

il est impossible de fournir une solution personnalisée pour l'application, car la solution dépend du cas d'utilisation et de la logique commerciale de l'application et d'une analyse coûts-avantages de ce que vous souhaitez réaliser avec les mises à jour de localisation.

intervalles de Temps

il n'est pas surprenant qu'il y ait des problèmes de performance de la batterie. À partir de la suivante paramètres:

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

Votre intervalle est mis à jour toutes les 5 minutes (5 * 60000ms). C'est 24 heures sur 24. Si cette mise à jour est réussie toutes les 5 minutes: 12 fois/heure == 288 fois par jour.

l'intervalle le plus rapide étant réglé à 1 minute (60000). Bien que disponible parce que l'endroit est accessible ailleurs sur l'appareil, il sera toujours utiliser la puissance de votre application).

Le maxwaittime est à seulement 30 minutes. Ce qui signifie, au mieux, l'appareil sera réveillé et sondé un minimum de 48 fois par jour.

augmentez ces temps.

setMaxWaitTime ... Cela peut consommer moins de batterie et donner des emplacements plus précis, selon les capacités matérielles de l'appareil. Vous devez définir cette la valeur doit être aussi grande que possible pour vos besoins si vous n'avez pas besoin emplacement immédiat livraison. ...

dans Android 8 Google a limité le nombre de requêtes à seulement quelques par heure. Envisagez d'utiliser cette ligne directrice pour établir des intervalles pour les demandes.

limitation du nombre de mises à jour

le nombre de mises à jour dans un certain délai peut être limité. Soit en annulant activement la requête de localisation Une fois que le nombre de mises à jour a été utilisé, soit en définissant un expiration sur la demande. De cette façon, l'application peut être gérée en créant une demande sur un déclencheur dans l'application et soigneusement géré de sorte que ça ne continue pas sans fin. Il est difficile de créer un flux, car je ne connais pas le cas d'utilisation de l'application.

setNumUpdates (int numUpdates)

par défaut les localisations sont mises à jour en continu jusqu'à ce que la requête soit explicitement supprimé, mais vous pouvez éventuellement demander un nombre défini de mettre. Par exemple, si votre application n'a besoin que d'une seule emplacement, puis d'appeler cette méthode avec une valeur de 1 avant de passer le demande à le client de localisation.

emplacement de l'Arrêt des mises à jour

une Autre option est de gérer arrêt emplacements des mises à jour quand ils ne sont pas nécessaires. Les liens donnent des exemples d'appeler cela quand une activité perd de sa focalisation, cependant il pourrait être mis en œuvre dans l'application, quand certaines exigences sont satisfaites (c'est dans votre logique d'affaires) ou même en donnant à l'utilisateur de l'allumer et de l'éteindre à partir de l'application elle-même.

Batterie optimisation

assurez-vous que votre application n'est pas ignorant la batterie optimisations.

Déplacement

gérer setSmallestDisplacement (float smallestdisplacement meters) aideront à affiner l'application, en fonction de la logique métier.

ce qui suit a été écrit avant la question mise à jour.

Combien de fois les mises à jour des applications peuvent être définies par le développeur et l'utilisateur. Le intervalles et les priorités.

pour le développeur.

vous pouvez les définir lors d'une requête de localisation par exemple:

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

il y a aussi un paramètre pour PRIORITY_NO_POWER, ce qui signifie que l'application ne recevra des mises à jour que si l'utilisateur les demande.

Pour l'utilisateur.

Vous aurez besoin d' demander à L'utilisateur de changer D'emplacement Les paramètres

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

gérer les changements dans le réglage de l'utilisateur, utilisez un appel de localisation.

... vous pouvez utiliser la nouvelle LocationCallback classe à la place de votre existant LocationListener recevoir Locationavitability mises à jour en plus pour les mises à jour d'emplacement, vous donnant un rappel simple chaque fois que les paramètres pourrait avoir changé ce qui affectera l'ensemble actuel de LocationRequests.

Google a adressé cette question dans Android 8.

dans un effort pour réduire la consommation D'énergie, Android 8.0 (niveau API 26) limite la fréquence à laquelle les applications en arrière-plan peuvent récupérer le courant de l'utilisateur emplacement. Les applications ne peuvent recevoir des mises à jour de localisation que quelques fois chacune heure.

Remarque: Ces restrictions s'appliquent à toutes les applications utilisées sur les appareils exécutant Android 8.0 (niveau API 26) ou plus, indépendamment de l'application cible Version SDK.


Si vous utilisez le Gestionnaire d'Alarme.

ceci peut être relié au Gestionnaire D'Alarme.

ce n'est pas une simple correction, en fin de compte, vous aurez besoin de réécrire la façon dont vous planifiez vos mises à jour.

  1. pour au moins ralentir le problème, vous aurez besoin de déboguer votre code et trouver toutes les instances où le Gestionnaire D'alarme appelle ou crée planifiez et réduisez les intervalles.

  2. après cela, vous aurez besoin de réécrire la totalité de la mise à jour de l'emplacement de la partie de la programmation de l'application.

Résoudre le Problème

identifiez les endroits dans votre application où vous programmez des alarmes de réveil et réduire la fréquence de ces alarmes sont déclenchées. Voici quelques conseils:

  • rechercher les appels vers les différents set () méthodes AlarmManager qui comprennent l' RTC_WAKEUP or ELAPSED_REALTIME_WAKEUP flag.
  • nous vous recommandons d'inclure votre nom de paquet, de classe ou de méthode dans le nom de l'étiquette de votre alarme afin que vous puissiez facilement identifier l'emplacement dans votre source où l'alarme a été réglée. Voici quelques conseils supplémentaires:
    • omettez tout renseignement d'identification personnelle (PII) dans le nom, tel qu'une adresse de courriel. Autrement, L'appareil se connecte _UNKNOWN au lieu du nom de l'alarme.
    • N'obtenez pas le nom de la classe ou de la méthode par programmation, par exemple en appelant getName (), parce qu'il pourrait être brouillé par Proguard. Utilisez plutôt une chaîne codée.
    • n'ajoutez pas de compteur ou d'identificateurs uniques aux étiquettes d'alarme. Le système ne pourra pas regrouper les alarmes qui sont réglées de cette façon parce qu'ils ont tous des identificateurs uniques.

après avoir réglé le problème, vérifiez que vos alarmes de réveil fonctionnent comme prévu en exécutant la commande suivante ADB commande:

adb shell dumpsys alarm

Cette commande fournit des informations sur l'état du système d'alarme service sur l'appareil. Pour plus d'informations, voir dumpsys.

si vous avez des problèmes particuliers avec de ce qui précède, vous aurez besoin de poster une autre question avec un mcve.

pour améliorer l'application, il faudrait réécrire le code comme mentionné ici dans Meilleures Pratiques. N'utilisez pas le gestionnaire d'alarme pour planifier les tâches de fond, et l'emplacement serait considéré comme une tâche de fond, si le téléphone est endormi. En plus, vous dites que c'est une tâche de fond. Utilisez JobScheduler ou Firebase JobDispatcher.

si le Gestionnaire D'alarme est le meilleur choix (c'est pas ici), il est important d'avoir une bonne lecture ici Planification De La Répétition Des Alarmes, mais vous devez vous Comprendre les compromis

une alarme mal conçue peut causer l'épuisement de la batterie et imposer une charge importante aux serveurs.

27
répondu Yvette Colomb 2017-09-14 15:26:01
la source