我注册监听了系统的广播,为啥收不到广播呢?

问题: 我注册了以下系统广播 ,为啥在Receiver中接受不到广播呢?

        <receiver android:name=".RebootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SCREEN_ON" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SCREEN_OFF" />
            </intent-filter>
        </receiver>

原因是: Android 7.0(API 级别 24)对系统事件的广播施加了一些限制,在Androidmanifest静态注册有无效.

android developer原文

如果应用注册为接收广播,则在每次发送广播时,应用的接收器都会消耗资源。 如果多个应用注册为接收基于系统事件的广播,则会引发问题:触发广播的系统事件会导致所有应用快速地连续消耗资源,从而降低用户体验。 为了缓解这一问题,Android 7.0(API 级别 24)对广播施加了一些限制,如后台优化中所述。 Android 8.0(API 级别 26)让这些限制更为严格。
  • 适配 Android 8.0 或更高版本的应用无法继续在其清单中为隐式广播注册广播接收器。  隐式广播是一种不专门针对该应用的广播。 例如, ACTION_PACKAGE_REPLACED 就是一种隐式广播,因为该广播将被发送给所有已注册侦听器,让后者知道设备上的某些软件包已被替换。 不过, ACTION_MY_PACKAGE_REPLACED 不是隐式广播,因为不管已为该广播注册侦听器的其他应用有多少,它都会只被发送给软件包已被替换的应用。
  • 应用可以继续在它们的清单中注册显式广播。
  • 应用可以在运行时使用  Context.registerReceiver() 为任意广播(不管是隐式还是显式)注册接收器。
  • 需要 签名权限的广播不受此限制所限,因为这些广播只会发送到使用相同证书签名的应用,而不是发送到设备上的所有应用。
  • 请注意: 很多隐式广播当前已不受此限制所限。 应用可以继续在其清单中为这些广播注册接收器,不管应用适配哪个 API 级别。 有关已豁免广播的列表,请参阅 隐式广播例外 。 

解决办法有二:

1.如果是系统应用,可以让系统指定广播对象的包名,显性广播.

2.采用动态注册的方式,Context.registerReceiver() .案例如下

public class RebootServices extends Service {

    public static final String TAG = "RebootServices";
    public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "intent.getAction():" + intent.getAction());
            if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
                Log.d(TAG, "ACTION_SCREEN_ON");
            }
            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
                Log.d(TAG, "ACTION_SCREEN_OFF");
            } 
        }
    };


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

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        intentFilter.addAction("android.intent.action.SCREEN_OFF");
        intentFilter.addAction("com.nes.intent.action.PERIODIC_REBOOT");
        registerReceiver(mReceiver, intentFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "RebootServices started");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }

}


//调用处
                Log.d(TAG, "add RebootServices");
                intent = new Intent(context,RebootServices.class);
                context.startService(intent);

 

你好!对于静态注册广播收不到的问题,可能有几个原因导致。以下是一些常见的排查步骤: 1. 检查广播的发送和接收代码:确保广播发送方发送的广播与接收方注册广播名称一致。检查发送广播的代码,确保广播已经发送成功。 2. 检查广播接收者的注册代码:确保广播接收者已经正确注册了对应的广播。在接收者的代码中,使用正确的`IntentFilter`并指定了正确的广播名称。 3. 检查接收者的权限:在AndroidManifest.xml文件中,确保接收者声明了正确的权限。如果广播需要特定的权限才能接收到,确保权限声明正确并已经在应用中授予了相应权限。 4. 检查广播接收者的优先级:如果有多个接收者监听同一个广播,优先级较低的接收者可能无法接收到广播。尝试调整接收者的优先级,确保它高于其他接收者。 5. 检查广播发送和接收的上下文:确保广播发送和接收的上下文是正确的。例如,在Activity中发送广播,则需要使用Activity的上下文;在Service中接收广播,则需要使用Service的上下文。 6. 检查其他代码逻辑:检查其他可能影响广播接收的代码逻辑,例如是否有其他地方取消了广播注册,或者是否有其他地方拦截了广播。 如果以上步骤都没有解决问题,可以尝试使用`LocalBroadcastManager`来发送和接收广播,它可以更方便地在应用内部传递广播消息。 希望这些提示能够帮助你解决问题!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值