与其使用长时间运行的服务,不如使用 AlarmManager 定期触发警报,这可以由 BroadcastReceiver 接收,并可以调用 Service(它应该在某个时候自行停止)或 IntentService 来执行电池检查。这将给用户带来最小的痛苦,因为它将使用更少的资源来让您的应用程序执行它需要做的事情,并且对您来说更少的痛苦,因为系统不太可能杀死您无休止地运行的应用程序。
例如,对于警报接收器:
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG = "AlarmReceiver";
private static final int REQUEST_CODE = 777;
public static final long ALARM_INTERVAL = DateUtils.MINUTE_IN_MILLIS;
// Call this from your service
public static void startAlarms(final Context context) {
final AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// start alarm right away
manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, ALARM_INTERVAL,
getAlarmIntent(context));
}
/*
* Creates the PendingIntent used for alarms of this receiver.
*/
private static PendingIntent getAlarmIntent(final Context context) {
return PendingIntent.getBroadcast(context, REQUEST_CODE, new Intent(context, AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onReceive(final Context context, final Intent intent) {
if (context == null) {
// Somehow you've lost your context; this really shouldn't happen
return;
}
if (intent == null){
// No intent was passed to your receiver; this also really shouldn't happen
return;
}
if (intent.getAction() == null) {
// If you called your Receiver explicitly, this is what you should expect to happen
Intent monitorIntent = new Intent(context, YourService.class);
monitorIntent.putExtra(YourService.BATTERY_UPDATE, true);
context.startService(monitorIntent);
}
}
}
对于您的引导接收器:
public class BootReceiver extends BroadcastReceiver{
private static final String TAG = "BootReceiver";
private static final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(ACTION_BOOT)) {
// This intent action can only be set by the Android system after a boot
Intent monitorIntent = new Intent(context, YourService.class);
monitorIntent.putExtra(YourService.HANDLE_REBOOT, true);
context.startService(monitorIntent);
}
}
}
为了您的服务:
public class YourService extends Service {
private static final String TAG = "YourService";
public static final String BATTERY_UPDATE = "battery";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.hasExtra(BootReceiver.ACTION_BOOT)){
AlarmReceiver.startAlarms(YourService.this.getApplicationContext());
}
if (intent != null && intent.hasExtra(BATTERY_UPDATE)){
new BatteryCheckAsync().execute();
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class BatteryCheckAsync extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... arg0) {
//Battery State check - create log entries of current battery state
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = YourService.this.registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
Log.i("BatteryInfo", "Battery is charging: " + isCharging);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
Log.i("BatteryInfo", "Battery charge level: " + (level / (float)scale));
return null;
}
protected void onPostExecute(){
YourService.this.stopSelf();
}
}
}
在您的清单中,您需要添加:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Services -->
<service
android:name="com.your.package.YourService"
android:enabled="true"
android:exported="false"
android:label="@string/app_name" >
</service>
<!-- Receivers -->
<receiver
android:name="com.your.package.AlarmReceiver"
android:enabled="true" />
<receiver
android:name="com.your.package.BootReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>