Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Quản lý nguồn ứng dụng

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Trong Android 9 trở lên, nền tảng này có thể theo dõi các ứng dụng để tìm hành vi ảnh hưởng tiêu cực đến tuổi thọ pin của thiết bị. Nền tảng sử dụng và đánh giá các quy tắc thiết lập để cung cấp luồng UX cung cấp cho người dùng tùy chọn hạn chế các ứng dụng vi phạm quy tắc.

Trong Android 8.0 trở xuống, có những hạn chế thông qua các tính năng như Ngủ gật, chế độ chờ ứng dụng, giới hạn nền và giới hạn vị trí nền. Tuy nhiên, một số ứng dụng tiếp tục thể hiện các hành vi xấu, một số trong số đó được mô tả trong Android vitals . Android 9 đã giới thiệu một cơ sở hạ tầng hệ điều hành có thể phát hiện và hạn chế các ứng dụng dựa trên các quy tắc thiết lập có thể được cập nhật theo thời gian.

Hạn chế nền

Người dùng có thể hạn chế các ứng dụng hoặc hệ thống có thể đề xuất các ứng dụng mà hệ thống phát hiện đang ảnh hưởng tiêu cực đến sức khỏe của thiết bị.

Các ứng dụng bị hạn chế:

  • Vẫn có thể được khởi chạy bởi người dùng.
  • Không thể chạy công việc / báo thức hoặc sử dụng mạng trong nền.
  • Không thể chạy các dịch vụ nền trước.
  • Người dùng có thể thay đổi thành ứng dụng không hạn chế.

Người triển khai thiết bị có thể thêm các hạn chế bổ sung cho ứng dụng để:

  • Hạn chế ứng dụng tự khởi động lại.
  • Hạn chế các dịch vụ bị ràng buộc (rủi ro cao).

Các ứng dụng bị hạn chế chạy trong nền sẽ không tiêu tốn bất kỳ tài nguyên thiết bị nào, chẳng hạn như bộ nhớ, CPU và pin. Các ứng dụng bị giới hạn trong nền sẽ không ảnh hưởng đến tình trạng của thiết bị khi người dùng không tích cực sử dụng các ứng dụng đó. Tuy nhiên, các ứng dụng tương tự được mong đợi sẽ hoạt động đầy đủ khi người dùng khởi chạy ứng dụng.

Sử dụng triển khai tùy chỉnh

Người triển khai thiết bị có thể tiếp tục sử dụng các phương pháp tùy chỉnh của họ để áp dụng các hạn chế trên ứng dụng.

Tích hợp các hạn chế ứng dụng

Các phần sau đây trình bày cách xác định và tích hợp các hạn chế ứng dụng trên thiết bị của bạn. Nếu bạn đang sử dụng các phương pháp hạn chế ứng dụng từ Android 8.x trở xuống, hãy xem xét kỹ các phần sau để biết các thay đổi trong Android 9 trở lên.

Đặt cờ AppOpsManager

Khi một ứng dụng bị hạn chế, hãy đặt cờ thích hợp trong AppOpsManager . Một đoạn mã mẫu từ 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);
    }

Đảm bảo trả về isBackgroundRestricted true

Khi một ứng dụng bị hạn chế, hãy đảm bảo rằng ActivityManager.isBackgroundRestricted() trả về true .

Ghi nhật ký lý do hạn chế

Khi một ứng dụng bị hạn chế, hãy ghi lại lý do hạn chế. Đoạn mã ví dụ về ghi nhật ký từ 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));
  }

Thay thế type bằng giá trị từ AnomalyType .

Người triển khai thiết bị có thể sử dụng các hằng số được xác định trong 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;
    }

Khi người dùng hoặc hệ thống xóa các hạn chế của ứng dụng, bạn phải ghi lại lý do xóa các hạn chế. Một đoạn mã ví dụ về ghi nhật ký từ 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));
    }

Thử nghiệm các hạn chế của ứng dụng

Để kiểm tra hành vi của các hạn chế ứng dụng trong Android 9 trở lên, hãy sử dụng một trong các lệnh sau:

  • Đặt ứng dụng vào tình trạng hạn chế:
    appops set package-name RUN_ANY_IN_BACKGROUND ignore
  • Đưa ứng dụng ra khỏi giới hạn và khôi phục hành vi mặc định:
    appops set package-name RUN_ANY_IN_BACKGROUND allow
  • Làm cho một ứng dụng trong nền không hoạt động ngay lập tức:
    am make-uid-idle [--user user-id | all | current] package-name
  • Thêm một gói vào tempwhitelist trong một thời gian ngắn:
    cmd deviceidle tempwhitelist [-u user] [-d duration] [package package-name]
  • Thêm / xóa gói khỏi danh sách trắng của người dùng:
    cmd deviceidle whitelist [+/-]package-name
  • Kiểm tra trạng thái nội bộ của bộ lập lịch công việc và trình quản lý cảnh báo: jobscheduler
    dumpsys jobscheduler
    dumpsys alarm

Chế độ chờ ứng dụng

Chế độ chờ ứng dụng kéo dài tuổi thọ pin bằng cách trì hoãn hoạt động mạng nền và công việc cho các ứng dụng mà người dùng không tích cực sử dụng.

Vòng đời ở chế độ chờ của ứng dụng

Nền tảng phát hiện các ứng dụng không hoạt động và đặt chúng ở chế độ chờ ứng dụng cho đến khi người dùng bắt đầu tương tác tích cực với ứng dụng.

Trong giai đoạn phát hiện , nền tảng phát hiện một ứng dụng không hoạt động khi thiết bị không sạc người dùng chưa khởi chạy ứng dụng đó một cách trực tiếp hoặc gián tiếp trong một khoảng thời gian cụ thể cũng như một lượng thời gian bật màn hình cụ thể . (Khởi chạy gián tiếp xảy ra khi một ứng dụng nền trước truy cập vào một dịch vụ trong một ứng dụng thứ hai.)

Trong thời gian chờ ứng dụng , nền tảng ngăn các ứng dụng truy cập mạng nhiều hơn một lần mỗi ngày, trì hoãn đồng bộ hóa ứng dụng và các công việc khác.

Nền tảng thoát ứng dụng khỏi chế độ chờ khi:

  • Ứng dụng sẽ hoạt động.
  • Thiết bị đã được cắm và sạc.

Các ứng dụng đang hoạt động không bị ảnh hưởng bởi chế độ chờ của ứng dụng. Một ứng dụng hoạt động khi nó có:

  • Một quy trình hiện đang ở chế độ nền trước (dưới dạng một hoạt động hoặc dịch vụ nền trước hoặc đang được một hoạt động hoặc dịch vụ nền khác sử dụng), chẳng hạn như trình nghe thông báo, dịch vụ trợ năng, hình nền động, v.v.
  • Thông báo được người dùng xem, chẳng hạn như trong màn hình khóa hoặc khay thông báo
  • Được người dùng khởi chạy một cách rõ ràng

Ứng dụng không hoạt động nếu không có hoạt động nào ở trên xảy ra trong một khoảng thời gian.

Thử nghiệm ứng dụng ở chế độ chờ

Bạn có thể kiểm tra thủ công chế độ chờ của ứng dụng bằng các adb sau:

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