今天进行了手机屏幕亮屏、暗屏、屏幕开锁、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开始,广播需要权限:
实例代码见第一代码原创文章https://www.diyidaima.com/android/111.html