Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
This page was translated by the Cloud Translation API.
Switch to English

Gestione dell'alimentazione delle app

In Android 9 e versioni successive, la piattaforma può monitorare le app per comportamenti che influiscono negativamente sulla durata della batteria dei dispositivi. La piattaforma utilizza e valuta le regole di configurazione per fornire un flusso UX che offre agli utenti la possibilità di limitare le app che violano le regole.

In Android 8.0 e versioni precedenti, c'erano restrizioni attraverso funzionalità come Doze, standby delle app, limiti di sfondo e limiti di posizione in background. Tuttavia, alcune app hanno continuato a presentare comportamenti scorretti, alcuni dei quali sono descritti in Android vitals . Android 9 ha introdotto un'infrastruttura del sistema operativo in grado di rilevare e limitare le app in base alle regole di configurazione che possono essere aggiornate nel tempo.

Restrizioni sullo sfondo

Gli utenti possono limitare le app o il sistema può suggerire che le app rilevate incidono negativamente sulla salute del dispositivo.

App limitate:

  • Può ancora essere lanciato dall'utente.
  • Impossibile eseguire lavori / allarmi o utilizzare la rete in background.
  • Impossibile eseguire i servizi in primo piano.
  • Può essere modificato in un'app senza restrizioni dall'utente.

Gli implementatori di dispositivi possono aggiungere ulteriori restrizioni alle app a:

  • Limita l'app dal riavvio automatico.
  • Limitare i servizi di essere vincolati (altamente rischioso).

Le app con restrizioni in background non consumano risorse del dispositivo, come memoria, CPU e batteria. Le app con sfondo limitato non dovrebbero influire sullo stato del dispositivo quando l'utente non sta utilizzando attivamente tali app. Tuttavia, ci si aspetta che le stesse app siano completamente funzionali quando l'utente avvia le app.

Utilizzo di implementazioni personalizzate

Gli implementatori di dispositivi possono continuare a utilizzare i loro metodi personalizzati per applicare restrizioni sulle app.

Integrazione delle restrizioni delle app

Le seguenti sezioni descrivono come definire e integrare le restrizioni delle app sul dispositivo. Se stai utilizzando metodi di limitazione delle app da Android 8.xo precedenti, consulta attentamente le seguenti sezioni per le modifiche in Android 9 e versioni successive.

Impostazione del flag AppOpsManager

Quando un'app è limitata, impostare il flag appropriato in AppOpsManager . Un frammento di codice di esempio da packages/apps/Settings/src/com/android/settings/fuelgauge/BatteryUtils.java :

   public void setForceAppStandby(int uid, String packageName,
            int mode) {
        final boolean isPreOApp = isPreOApp(packageName);
        if (isPreOApp) {
       // Control whether app could run in the background if it is pre O app
            mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName, mode);
        }
       // Control whether app could run jobs in the background
        mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
    }

Assicurarsi che isBackgroundRestricted restituisca true

Quando un'app è soggetta a restrizioni, assicurarsi che ActivityManager.isBackgroundRestricted() restituisca true .

Registrazione del motivo della restrizione

Quando un'app è soggetta a restrizioni, registra i motivi della restrizione. Un frammento di codice di esempio di registrazione da packages/apps/Settings/src/com/android/settings/fuelgauge/batterytip/actions/RestrictAppAction.java :

mBatteryUtils.setForceAppStandby(mBatteryUtils.getPackageUid(packageName), packageName,AppOpsManager.MODE_IGNORED);
if (CollectionUtils.isEmpty(appInfo.anomalyTypes)) {
  // Only log context if there is no anomaly type
  mMetricsFeatureProvider.action(mContext,
    MetricsProto.MetricsEvent.ACTION_TIP_RESTRICT_APP, packageName,
    Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,metricsKey));
            } else {
  // Log ALL the anomaly types
  for (int type : appInfo.anomalyTypes) {
    mMetricsFeatureProvider.action(mContext,
      MetricsProto.MetricsEvent.ACTION_TIP_RESTRICT_APP, packageName,
      Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey),
      Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, type));
  }

Sostituisci il type con il valore di AnomalyType .

Gli implementatori di dispositivi possono utilizzare le costanti definite in src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java :

public @interface AnomalyType {
        // This represents an error condition in the anomaly detection.
        int NULL = -1;
         // The anomaly type does not match any other defined type.
        int UNKNOWN_REASON = 0;
         // The application held a partial (screen off) wake lock for a period of time that
         // exceeded the threshold with the screen off when not charging.
        int EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF = 1;
         // The application exceeded the maximum number of wakeups while in the background
         // when not charging.
        int EXCESSIVE_WAKEUPS_IN_BACKGROUND = 2;
         // The application did unoptimized Bluetooth scans too frequently when not charging.
        int EXCESSIVE_UNOPTIMIZED_BLE_SCAN = 3;
         // The application ran in the background for a period of time that exceeded the
         // threshold.
        int EXCESSIVE_BACKGROUND_SERVICE = 4;
         // The application exceeded the maximum number of wifi scans when not charging.
        int EXCESSIVE_WIFI_SCAN = 5;
         // The application exceed the maximum number of flash writes
        int EXCESSIVE_FLASH_WRITES = 6;
         // The application used more than the maximum memory, while not spending any time
         // in the foreground.
        int EXCESSIVE_MEMORY_IN_BACKGROUND = 7;
         // The application exceeded the maximum percentage of frames with a render rate of
         // greater than 700ms.
        int EXCESSIVE_DAVEY_RATE = 8;
         // The application exceeded the maximum percentage of frames with a render rate
         // greater than 16ms.
        int EXCESSIVE_JANKY_FRAMES = 9;
         // The application exceeded the maximum cold start time - the app has not been
         // launched since last system start, died or was killed.
        int SLOW_COLD_START_TIME = 10;
         // The application exceeded the maximum hot start time - the app and activity are
         // already in memory.
        int SLOW_HOT_START_TIME = 11;
         // The application exceeded the maximum warm start time - the app was already in
         // memory but the activity wasn't created yet or was removed from memory.
        int SLOW_WARM_START_TIME = 12;
         // The application exceeded the maximum number of syncs while in the background.
        int EXCESSIVE_BACKGROUND_SYNCS = 13;
         // The application exceeded the maximum number of gps scans while in the background.
        int EXCESSIVE_GPS_SCANS_IN_BACKGROUND = 14;
         // The application scheduled more than the maximum number of jobs while not charging.
        int EXCESSIVE_JOB_SCHEDULING = 15;
         // The application exceeded the maximum amount of mobile network traffic while in
         // the background.
        int EXCESSIVE_MOBILE_NETWORK_IN_BACKGROUND = 16;
         // The application held the WiFi lock for more than the maximum amount of time while
         // not charging.
        int EXCESSIVE_WIFI_LOCK_TIME = 17;
         // The application scheduled a job that ran longer than the maximum amount of time.
        int JOB_TIMED_OUT = 18;
         // The application did an unoptimized Bluetooth scan that exceeded the maximum
         // time while in the background.
        int LONG_UNOPTIMIZED_BLE_SCAN = 19;
         // The application exceeded the maximum ANR rate while in the background.
        int BACKGROUND_ANR = 20;
         // The application exceeded the maximum crash rate while in the background.
        int BACKGROUND_CRASH_RATE = 21;
         // The application exceeded the maximum ANR-looping rate.
        int EXCESSIVE_ANR_LOOPING = 22;
         // The application exceeded the maximum ANR rate.
        int EXCESSIVE_ANRS = 23;
         // The application exceeded the maximum crash rate.
        int EXCESSIVE_CRASH_RATE = 24;
         // The application exceeded the maximum crash-looping rate.
        int EXCESSIVE_CRASH_LOOPING = 25;
         // The application crashed because no more file descriptors were available.
        int NUMBER_OF_OPEN_FILES = 26;
    }

Quando l'utente o il sistema rimuove le restrizioni di un'app, è necessario registrare i motivi della rimozione delle restrizioni. Un frammento di codice di esempio di registrazione da packages/apps/Settings/src/com/android/settings/fuelgauge/batterytip/actions/UnrestrictAppAction.java :

public void handlePositiveAction(int metricsKey) {
        final AppInfo appInfo = mUnRestrictAppTip.getUnrestrictAppInfo();
        // Clear force app standby, then app can run in the background
        mBatteryUtils.setForceAppStandby(appInfo.uid, appInfo.packageName,
                AppOpsManager.MODE_ALLOWED);
        mMetricsFeatureProvider.action(mContext,
                MetricsProto.MetricsEvent.ACTION_TIP_UNRESTRICT_APP, appInfo.packageName,
                Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey));
    }

Test delle restrizioni dell'app

Per testare il comportamento delle restrizioni dell'app in Android 9 e versioni successive, utilizzare uno dei seguenti comandi:

  • Metti un'app in limitazione:
    appops set package-name RUN_ANY_IN_BACKGROUND ignore
  • Rimuovi un'app dalle restrizioni e ripristina il comportamento predefinito:
    appops set package-name RUN_ANY_IN_BACKGROUND allow
  • Rendi immediatamente inattiva un'app in background:
    am make-uid-idle [--user user-id | all | current] package-name 
  • Aggiungi un pacchetto alla tempwhitelist per un breve periodo:
    cmd deviceidle tempwhitelist [-u user ] [-d duration ] [package package-name ]
  • Aggiungi / rimuovi un pacchetto dalla whitelist utente:
    cmd deviceidle whitelist [+/-] package-name 
  • Controllare lo stato interno del jobscheduler e del gestore allarmi:
     dumpsys jobscheduler
    dumpsys alarm 

Stand-by dell'app

L'app standby prolunga la durata della batteria differendo l'attività di rete in background e i lavori per le app che l'utente non sta attivamente utilizzando.

Ciclo di vita dell'app standby

La piattaforma rileva le app inattive e le mette in standby dell'app finché l'utente non inizia a interagire attivamente con l'app.

Durante la fase di rilevamento , la piattaforma rileva che un'app è inattiva quando il dispositivo non si sta caricando e l'utente non ha avviato l'app direttamente o indirettamente per un determinato periodo di tempo, nonché per un determinato periodo di tempo di screen-on . (I lanci indiretti si verificano quando un'app in primo piano accede a un servizio in una seconda app.)

Durante lo standby delle app , la piattaforma impedisce alle app di accedere alla rete più di una volta al giorno, rinviando le sincronizzazioni delle app e altri processi.

La piattaforma esce dall'app standby quando:

  • L'app diventa attiva.
  • Il dispositivo è collegato e in carica.

Le app attive non sono interessate dallo standby dell'app. Un'app è attiva quando ha:

  • Un processo attualmente in primo piano (come attività o servizio di primo piano o in uso da un'altra attività o servizio di primo piano), come listener di notifica, servizi di accessibilità, live wallpaper, ecc.
  • Una notifica visualizzata dall'utente, ad esempio nella schermata di blocco o nell'area di notifica
  • Stato esplicitamente lanciato dall'utente

Un'app è inattiva se nessuna delle attività di cui sopra si è verificata per un periodo di tempo.

Test dello standby dell'app

Puoi testare manualmente lo standby dell'app usando i seguenti comandi adb :

adb shell dumpsys battery unplug
adb shell am set-idle package-name true
adb shell am set-idle package-name false
adb shell am get-idle package-name