Android静态注册的屏幕开启和屏幕关闭的广播捕捉不到的原因
今天进行了手机屏幕亮屏、暗屏、屏幕开锁、WIFI和移动网络状态改变、开机等广播的功能实现,其中遇到了一个问题,就是无论如何,屏幕亮屏、暗屏的广播都接收不到。这是因为我在AndroidManifest.xml采用了静态 注册的缘故。事实上,对应屏幕亮屏、暗屏的广播,必须通过代码动态注册 才可以获取到广播,这是系统做出的限制。下面贴出实例代码:
MainActivity.java类:
package com.diyidaima.selfstartaappdemo;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
ControllCenterReceiver controllCenterReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
controllCenterReceiver=new ControllCenterReceiver();
registerScreenActionReceiver();
}
//屏幕亮屏广播和屏幕灭屏广播限制只能有register到代码中的receiver才能接收。
private void registerScreenActionReceiver(){
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(controllCenterReceiver, filter);
}
}
ControllCenterReceiver.java广播实现类:
package com.diyidaima.selfstartaappdemo;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class ControllCenterReceiver extends BroadcastReceiver {
public static String TAG = "ControllCenterReceiver";
private NotificationManager mManager;
private NotificationCompat.Builder mBuilder;
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive");
String action = intent.getAction();
if (Intent.ACTION_SCREEN_ON.equals(action)) { // 屏幕亮屏广播
Log.d(TAG, "screen on");
showNotification(context, "screen on");
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {// 屏幕灭屏广播
Log.d(TAG, "screen off");
showNotification(context, "screen off");
} else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 屏幕解锁广播
Log.d(TAG, "screen unlock");
showNotification(context, "screen unlock");
} else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
// 当长按电源键弹出“关机”对话或者锁屏时系统会发出这个广播
// example:有时候会用到系统对话框,权限可能很高,会覆盖在锁屏界面或者“关机”对话框之上,
// 所以监听这个广播,当收到时就隐藏自己的对话,如点击pad右下角部分弹出的对话框
Log.i(TAG, " receive Intent.ACTION_CLOSE_SYSTEM_DIALOGS");
showNotification(context, "按电源键");
} else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action) ||
WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action) ||
ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
//监听wifi广播
Log.d(TAG, "监听wifi广播");
showNotification(context, "监听wifi广播");
} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
//开机广播
Log.d(TAG, "开机广播");
showNotification(context, "开机广播");
}
}
private void showNotification(Context context, String beizhu) {
mManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("设置通知栏标题 " + beizhu)//设置通知栏标题
.setContentText("设置通知栏显示内容") //设置通知栏显示内容
.setContentIntent(getDefalutIntent(context, PendingIntent.FLAG_ONE_SHOT)) //设置通知栏点击意图
.setTicker("设置通知栏显示内容") //通知首次出现在通知栏,带上升动画效果的
.setWhen(System.currentTimeMillis())//通知产生的时间,会在通知信息里显示,一般是系统获取到的时间
.setPriority(Notification.PRIORITY_DEFAULT) //设置该通知优先级
.setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
.setOngoing(false)//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
.setDefaults(Notification.DEFAULT_VIBRATE)//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合
//Notification.DEFAULT_ALL Notification.DEFAULT_SOUND 添加声音 // requires VIBRATE permission
.setSmallIcon(R.mipmap.ic_launcher);//设置通知小ICON
mManager.notify(0, mBuilder.build());
}
public PendingIntent getDefalutIntent(Context context, int flags) {
Intent intent = new Intent(context, MainActivity.class);
//注意问题:Context中有一个startActivity方法,Activity继承自Context,
// 重载了startActivity方法。如果使用 Activity的startActivity方法,
// 不会有任何限制,而如果使用Context的startActivity方法的话,
// 就需要开启一个新的task,解决办法是,加一个flag,
// 也就是这句intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);的作用。
// 如果不添加这句,就会报android.util.AndroidRuntimeException
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.putExtra("content",""+content);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, flags);
return pendingIntent;
}
}
AndroidManifest.xml文件,android7.0开始,广播需要权限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.diyidaima.selfstartaappdemo">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".ControllCenterReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<!--监听wifi广播-->
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
<!--<intent-filter android:priority="1000">-->
<!--屏幕亮屏广播;限制只能有register到代码中的receiver才能接收-->
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
<!--</intent-filter>-->
<!--<intent-filter android:priority="1000">-->
<!--屏幕灭屏广播;限制只能有register到代码中的receiver才能接收-->
<!--<action android:name="android.intent.action.SCREEN_OFF" />-->
<!--</intent-filter>-->
<intent-filter android:priority="1000">
<!--屏幕解锁广播-->
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
<intent-filter android:priority="1000">
<!--当长按电源键弹出“关机”对话或者锁屏时系统会发出这个广播-->
<action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
</intent-filter>
<intent-filter android:priority="1000">
<!--开机接收广播-->
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
</application>
</manifest>
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。