在与服务后台检查电池水平在与、后台、电池、水平

2023-09-07 09:53:39 作者:默泪-

我已经搜查了很多,但我总是更糊涂了。

I've searched a lot but I'm always more confused.

我要创建一个可在后台运行,并检查电池电量的应用程序。如何创建服务?服务应该开始对设备引导和当电池达到一定的比例与活性必须进行通信,所以不存在从消费者的任何相互作用

I have to create an app that works on background and checks the battery level. How can I create the Service? The Service should start on the device boot and must communicate with the Activity when the battery reaches a certain percentage, so there isn't any interaction from the consumer.

我已创建什么类型的服务?什么事情,我有什么关系?

What type of Service have I to create? What are the things I have to do?

推荐答案

,而不是使用一个长期运行的服务,使用一个AlarmManager定时触发报警器,其可以通过一个BroadcastReceiver接收并可以调用一个服务(应停止本身在某些点)或IntentService来执行电池检查。这将导致至少悲痛的用户,因为它会使用更少的资源,让您的应用程序做什么需要做的,和你少悲伤,因为系统将不太可能杀死你无休止地运行应用程序。

Rather than using a long-running service, use an AlarmManager to trigger alarms periodically, which can be received by a BroadcastReceiver and can call a Service (which should stop itself at some point) or an IntentService to perform your battery check. This will cause the least grief for the user, since it will use less resources to keep your application doing what it needs to do, and less grief for you, since the system will be less likely to kill your endlessly-running app.

例如,对于报警接收机:

For example, for an Alarm Receiver:

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();
        }
    }
}

在你的清单,你需要加入:

In your manifest, you'll need to add in:

<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>