Giám sát mức pin và trạng thái sạc

Khi bạn thay đổi tần suất cập nhật nền để giảm hiệu quả của những lần cập nhật đó cập nhật về thời lượng pin, bạn nên kiểm tra mức pin hiện tại và trạng thái sạc đầu.

Mức tác động đến thời lượng pin của việc cập nhật ứng dụng phụ thuộc vào mức pin và trạng thái sạc của thiết bị. Tác động của việc cập nhật trong khi thiết bị đang sạc qua nguồn AC không đáng kể, vì vậy trong hầu hết trường hợp, bạn có thể tăng tối đa tốc độ làm mới bất cứ khi nào thiết bị được kết nối vào bộ sạc cắm tường. Ngược lại, nếu thiết bị đang sạc, việc giảm tốc độ cập nhật sẽ giúp kéo dài thời lượng pin.

Tương tự, bạn có thể kiểm tra mức pin, có thể giảm tần suất của—hoặc thậm chí dừng lại — cập nhật khi pin sắp hết.

Xác định trạng thái sạc hiện tại

Bắt đầu bằng cách xác định trạng thái sạc hiện tại. BatteryManager sẽ truyền tất cả thông tin chi tiết về pin và trạng thái sạc trong một Intent cố định, bao gồm cả trạng thái sạc.

Vì đây là một ý định cố định, nên bạn không cần đăng ký BroadcastReceiver – chỉ cần gọi registerReceiver truyền vào null làm trình nhận như minh hoạ trong đoạn mã tiếp theo, ý định về trạng thái pin hiện tại là đã trả lại. Bạn có thể truyền vào một đối tượng BroadcastReceiver thực tế tại đây, nhưng chúng tôi sẽ xử lý thông tin cập nhật trong phần sau nên bạn không cần thiết.

Kotlin

val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
    context.registerReceiver(null, ifilter)
}

Java

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

Bạn có thể trích xuất cả trạng thái sạc hiện tại lẫn trạng thái sạc nếu thiết bị đang được sạc, cho dù thiết bị đang sạc qua USB hoặc bộ sạc AC:

Kotlin

val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING
        || status == BatteryManager.BATTERY_STATUS_FULL

// How are we charging?
val chargePlug: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
val usbCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB
val acCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_AC

Java

// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

Thông thường, bạn nên tăng tốc độ cập nhật ở chế độ nền trong trường hợp thiết bị được kết nối với bộ sạc AC, giảm tốc độ nếu sạc qua USB và giảm tốc độ hơn nữa nếu pin đang xả.

Theo dõi các thay đổi về trạng thái sạc

Trạng thái sạc có thể thay đổi dễ dàng như việc cắm thiết bị. Vì vậy, điều quan trọng là bạn phải theo dõi trạng thái sạc để biết các thay đổi và điều chỉnh tốc độ làm mới cho phù hợp.

BatteryManager truyền phát một thao tác bất cứ khi nào thiết bị được kết nối hoặc đã ngắt kết nối khỏi nguồn. Bạn cần nhận được các sự kiện này ngay cả khi ứng dụng của bạn không hoạt động cụ thể là vì các sự kiện này sẽ ảnh hưởng đến tần suất bạn khởi động ứng dụng để bắt đầu cập nhật ở chế độ nền, vì vậy, bạn nên đăng ký BroadcastReceiver trong tệp kê khai để theo dõi cả hai sự kiện bằng cách xác định ACTION_POWER_CONNECTEDACTION_POWER_DISCONNECTED trong bộ lọc ý định.

<receiver android:name=".PowerConnectionReceiver">
  <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
  </intent-filter>
</receiver>

Xác định mức pin hiện tại

Trong một số trường hợp, bạn cũng nên xác định mức pin hiện tại. Bạn có thể chọn giảm tốc độ cập nhật trong nền nếu pin sạc dưới một mức nhất định.

Bạn có thể tìm mức pin hiện tại bằng cách trích xuất mức pin và quy mô hiện tại từ ý định về trạng thái pin như minh hoạ dưới đây:

Kotlin

val batteryPct: Float? = batteryStatus?.let { intent ->
    val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
    val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
    level * 100 / scale.toFloat()
}

Java

int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

float batteryPct = level * 100 / (float)scale;

Phản ứng với những thay đổi đáng kể về mức pin

Bạn không thể dễ dàng liên tục theo dõi trạng thái pin, nhưng bạn không cần phải làm vậy.

Nói chung, việc theo dõi mức pin sẽ ảnh hưởng nhiều hơn đến pin so với hành vi bình thường của ứng dụng. Ví dụ: đăng ký BroadcastReceiver trong tệp kê khai để huỷ công việc đang chờ xử lý khi pin yếu sẽ chủ yếu làm tiêu hao pin hơn nữa (và do đó sẽ không thể kể từ Android 8.0). Thay vào đó, bạn có thể đưa ra các quy tắc ràng buộc về công việc mô tả thời điểm chạy công việc đó, cho phép hệ thống đưa ra quyết định mà không cần tiêu tốn năng lượng để khởi động ứng dụng.

Nhìn chung, bạn không nên chạy bản cập nhật ở chế độ nền khi pin yếu. Dữ liệu của bạn mới đến đâu cũng không quan trọng nếu điện thoại tự tắt trước khi bạn có thể sử dụng dữ liệu đó. Để thực hiện việc này, dùng thư viện WorkManagerPhạm vi BatteryNotLow để chỉ định rằng không nên chạy công việc nếu pin yếu (ngoài các NetworkType quy tắc ràng buộc).

Trong nhiều trường hợp, việc sạc thiết bị trùng với việc đặt thiết bị vào đế sạc. Để tìm hiểu thêm, hãy xem Xác định và theo dõi trạng thái và loại đế sạc.