如何检测设备是否正在从后台充电

How do I detect if device is charging from background

我在开发人员说明中仔细搜索了 android,但无法找到如何在设备插入时执行特定操作,以及在拔出时执行另一个操作。

我尝试像下面那样设置广播接收器,但它不会 运行:

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

我了解到,从 API 26 及以上,您将无法再接收清单中注册的某些广播,必须动态注册它们。

我需要在后台运行这个 运行,但不知道怎么做?这篇文章更新于2019年(api26之后)暗示我应该可以做到。

The charging status can change as easily as a device can be plugged in, so it's important to monitor the charging state for changes and alter your refresh rate accordingly.

The BatteryManager broadcasts an action whenever the device is connected or disconnected from power. It's important to receive these events even while your app isn't running particularly as these events should impact how often you start your app in order to initiate a background update so you should register a BroadcastReceiver in your manifest to listen for both events by defining the ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED within an intent filter.

我的最终目标是在设备插入或拔出时调用广播接收器。

我将如何实施它?

您需要通过代码注册此接收器

您可以 运行 WorkManager 每 15 分钟 运行 一次(最少每 15 分钟一次) 注册接收器,检查它是否正在充电 注销接收器

实现此目的的最佳方法是在后台提供服务 运行,这样您就可以在用户不使用应用程序的情况下接收来自 android 的广播。

首先在清单文件中注册服务。

<Service android:name=".serviceName"/>

现在创建您的 class,使用与上面清单中注册的名称相同的名称,此 class 必须扩展服务。

    public class BackgroundService extends Service {
        private static final int NOTIF_ID = 1;
        private static final String NOTIF_CHANNEL_ID = "AppNameBackgroundService";

        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId){

            //Add broadcast receiver for plugging in and out here
            ChargeDetection chargeDetector = new ChargeDetection(); //This is the name of the class at the bottom of this code.

            IntentFilter filter = new IntentFilter();
            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
            filter.addAction(Intent.ACTION_POWER_CONNECTED);
            filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
            this.registerReceiver(chargeDetector, filter);

            startForeground();

            return super.onStartCommand(intent, flags, startId);
        }

        private void startForeground() {
            createNotificationChannel();
            Intent notificationIntent = new Intent(this, MainActivity.class);

            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                    notificationIntent, 0);

            startForeground(NOTIF_ID, new NotificationCompat.Builder(this,
                    NOTIF_CHANNEL_ID) // don't forget create a notification channel first
                    .setOngoing(true)
                    .setSmallIcon(R.mipmap.final_icon)
                    .setContentTitle(getString(R.string.app_name))
                    .setContentText("Background service is running")
                    .setContentIntent(pendingIntent)
                    .build());
        }

        private void createNotificationChannel() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel serviceChannel = new NotificationChannel(
                        NOTIF_CHANNEL_ID,
                        "Foreground Service Channel",
                        NotificationManager.IMPORTANCE_DEFAULT
                );
                NotificationManager manager = getSystemService(NotificationManager.class);
                manager.createNotificationChannel(serviceChannel);
            }
        }
    }

    class ChargeDetection extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //Now check if user is charging here. This will only run when device is either plugged in or unplugged.
        }
    }   
    }