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 ảnh hưởng của những 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.

Tác động đến thời lượng pin khi thực hiện 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

Hãy bắt đầu bằng cách xác định trạng thái sạc hiện tại. BatteryManager truyền phát tất cả thông tin chi tiết về pin và quá trình sạc trong một Intent cố định bao gồm 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à bị 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 ở phần sau nên bạn không cần làm vậy.

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ối đa tốc độ cập nhật ở chế độ nền trong trường hợp thiết bị đang đã kết nối với bộ sạc AC, hãy giảm tốc độ nếu sạc qua USB và giảm tốc độ nếu pin đang sạc.

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ư khi cắm thiết bị vào nguồn điện, vì vậy bạn phải theo dõi trạng thái sạc để biết các thay đổi và thay đổi 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 của mình để 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 ở mức thấp hơn 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 theo dõi liên tục trạng thái pin, nhưng việc này là không cần thiết.

Nói chung, tác động của việc theo dõi mức pin tới pin so với hành vi thông 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ể cung cấp các quy tắc ràng buộc đối với công việc để mô tả thời điểm nên chạy công việc, cho phép hệ thống đưa ra quyết định mà không phải tốn pin để khởi động ứng dụng của bạn.

Thông thường, bạn không nên chạy các bản cập nhật ở chế độ nền khi pin còn cực thấp. Không quan trọng độ mới của dữ liệu nếu điện thoại tự tắt trước khi bạn có thể tận dụng nó. Để 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, hành động sạc thiết bị trùng khớp với việc đặt thiết bị vào đế. Phần tiếp theo bài học này sẽ hướng dẫn bạn cách xác định trạng thái đế hiện tại và theo dõi các thay đổi trong thiết bị đang gắn vào đế sạc.