Android 11 三方应用监听关机广播ACTION_SHUTDOWN

前言

最近有项目过程中,有做app的同事反馈,三方应用无法监听关机广播。特地研究了下关机广播为啥监听不到。

1.原因:发送关机广播的类是ShutdownThread.java,添加了flag:Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY,表示只有在代码中动态注册,并且是前台服务和应用才能收到,所以在AndroidManifest.xml注册无法收到关机广播,后台服务中动态注册也无法收到。

2.前台服务注册关机广播。

(1).启动前台服务:

复制代码
public class BootCompleteReceiver extends BroadcastReceiver {
    private static final String TAG = "BootCompleteReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null) {
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
//                ComponentName powerService = new ComponentName("com.android.mytest", "com.android.mytest.PowerService");
//                Intent mIntent = new Intent();
//                mIntent.setComponent(powerService);
                Intent powerServiceIntent = new Intent(context, PowerService.class);
                context.startForegroundService(powerServiceIntent);
                Log.d(TAG, "startForegroundService");
            }
        }
    }
}

(2)、添加前台服务权限,配置相关属性:

权限:

复制代码
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

服务配置:

复制代码
 <service
            android:name=".PowerService"
            android:foregroundServiceType="mediaPlayback"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.gwm.car.PowerService"/>
            </intent-filter>
        </service>

(3).注册关机广播:

复制代码
package com.android.mytest;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class PowerService extends Service {

    private static final String TAG = "PowerService";
    public ShutdownBroadcastReceiver mShutdownBroadcastReceiver;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
        mShutdownBroadcastReceiver = new ShutdownBroadcastReceiver();
    }

    private Notification getNotification() {
        NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (manager != null) {
            manager.createNotificationChannel(channel);
        }
        return new Notification.Builder(this, "channel_id")
                .setContentTitle("shutdown")
                .setContentText("Listening for shutdown")
//                .setAutoCancel(true)
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .build();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        startForeground(1, getNotification());
        registerBroadcast();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
        unregisterBroadcast();
        stopForeground(true);
        stopSelf();
    }

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

    public void registerBroadcast() {
        Log.d(TAG, "registerBroadcast");
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction((Intent.ACTION_SHUTDOWN));
        registerReceiver(mShutdownBroadcastReceiver,intentFilter);

    }

    public void unregisterBroadcast() {
        if (mShutdownBroadcastReceiver != null) {
            unregisterReceiver(mShutdownBroadcastReceiver);
        }
    }
}

(4).关机广播实现

复制代码
package com.android.mytest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class ShutdownBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "ShutdownBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "zjy onReceive intent:"+intent);
    }
}

(5).本地验证:

相关推荐
提子拌饭1334 分钟前
开源鸿蒙跨平台Flutter开发:AR厨艺教学应用
android·flutter·华为·开源·ar·harmonyos·鸿蒙
fengci.12 分钟前
php反序列化(复习)(第四章)
android·开发语言·学习·php·android studio
XiaoLeisj12 分钟前
Android 短视频项目首页开发实战:从广场页广告轮播与网格列表,到发现页分类、播单与话题广场的数据驱动实现
android·okhttp·mvvm·recyclerview·retrofit·databinding·xbanner 轮播
whatever who cares15 分钟前
android中,全局管理数据/固定数据要不要放一起?
android·java·开发语言
冬奇Lab39 分钟前
MediaCodec 编解码基础:Buffer 队列、状态机与零拷贝的艺术
android·音视频开发·源码阅读
光影少年1 小时前
Android和iOS原生开发的基础知识对RN开发的重要性,RN打包发布时原生端需要做哪些配置?
android·前端·react native·react.js·ios
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.1 小时前
MySQL主从复制实战配置详解,以及企业级相关优化说明
android·mysql·adb
simpleeeeee1 小时前
安卓开发者应该知道的 10 个安卓性能优化秘诀
android
simpleeeeee1 小时前
Android 17:API 级别 37 的开发者指南——现在你需要构建什么
android
zhaoyufei1331 小时前
RK3566 EDP屏幕背光闪修改pwm
android·java