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

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

Tác động đến thời lượng pin của việc 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 thực hiện cập nhật trong khi thiết bị đang sạc qua AC là không đáng kể. Vì vậy, trong hầu hết các 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ới bộ sạc tường. Ngược lại, nếu thiết bị đang xả pin, thì 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ể làm giảm tần suất (hoặc thậm chí dừng) các bản cập nhật khi sắp hết pin.

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 tính phí hiện tại. BatteryManager sẽ thông báo về tất cả thông tin về pin và thông tin sạc trong một Intent cố định có chứa trạng thái sạc.

Do đây là ý đị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ư trong đoạn mã tiếp theo, ý định về trạng thái pin hiện tại sẽ được trả về. Bạn có thể truyền một đối tượng BroadcastReceiver thực tế tại đây, nhưng chúng tôi sẽ xử lý nội dung cập nhật trong phần sau nên việc này là 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 và nếu thiết bị đang được sạc, cho dù thiết bị đó đang sạc qua bộ sạc USB hay 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ối đa hoá tốc độ cập nhật ở chế độ nền trong trường hợp thiết bị kết nối với bộ sạc AC, giảm tốc độ nếu sạc qua USB và giảm hơn nữa nếu pin sắp hết.

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 thiết bị được cắm điện. Vì vậy, bạn cần phải theo dõi trạng thái sạc để biết những thay đổi và thay đổi tốc độ làm mới cho phù hợp.

BatteryManager sẽ truyền một thao tác bất cứ khi nào thiết bị được kết nối hoặc bị ngắt kết nối khỏi nguồn điện. Bạn cần phải nhận được những sự kiện này ngay cả khi ứng dụng không chạy (đặc biệt là vì những 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 quá trình 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, việc xác định mức pin hiện tại cũng rất hữu ích. Bạn có thể chọn giảm tốc độ cập nhật ở chế độ nền nếu mức pin thấp hơn một mức nhất định.

Bạn có thể biết mức pin hiện tại bằng cách trích xuất mức pin hiện tại và tỷ lệ 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 bạn không cần.

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

Nhìn chung, bạn không nên chạy các bản cập nhật nền khi pin sắp hết. Bất kể dữ liệu của bạn mới cập nhật như thế nào 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, hãy sử dụng thư viện WorkManager với quy tắc ràng buộc BatteryNotLow để chỉ định rằng bạn sẽ không thể chạy tác vụ nếu pin yếu (ngoài các quy tắc ràng buộc NetworkType có liên quan).

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 đế. Bài học tiếp theo sẽ hướng dẫn bạn cách xác định trạng thái đế sạc hiện tại và theo dõi những thay đổi khi gắn thiết bị.