我经常搜索,但我总是更加困惑。
我必须创建一个适用于后台的应用程序并检查电池电量。我该如何创建服务?服务应该在设备启动时启动,并且必须在电池达到一定百分比时与活动通信,因此消费者没有任何交互。
我要创建什么类型的服务?我有什么需要做的事情?
答案 0 :(得分:6)
使用AlarmManager定期触发警报,而不是使用长时间运行的服务,可以由BroadcastReceiver接收并可以调用服务(应该在某个时刻停止)或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>
答案 1 :(得分:1)
您不需要服务。在应用程序中包含侦听Intent.ACTION_BATTERY_CHANGED广播的广播接收器。在Application Manifest中定义该广播接收器,并且只要电池状态发生变化,它就会自动启动。
广播包括有关电池当前状态的信息,因此无需精心设计(且非常昂贵!)的解决方案来查询此信息。
This page 将提供所有详细信息。
该页面引人注目的一句话:
您无法轻松连续监控电池状态,但事实并非如此 需要。
一般来说,不断监测电池的影响 电平对电池的影响大于应用的正常水平 行为,所以最好只监控重大变化 电池电量 - 特别是当设备进入或退出低电平时 电池状态。下面的清单代码段是从intent filter元素中提取的 在广播接收器内。每当接收器被触发 通过收听,设备电池电量变低或退出低电量状态 ACTION_BATTERY_LOW和ACTION_BATTERY_OKAY。
<receiver android:name=".BatteryLevelReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
<action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
</intent-filter>
</receiver>
您可能希望监控的其他操作包括:ACTION_BATTERY_CHANGED
,ACTION_POWER_CONNECTED
,ACTION_POWER_DISCONNECTED