类似于手机锁屏状态下QQ来消息然后点亮屏幕并弹窗,如图。
相信QQ的这个功能大家都是很熟悉的了,下面就开始讲具体的实现步骤。
一、新建一个Activity并在OnCreate中添加四个标识
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_handler);
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
//下面就是根据自己的跟你需求来写,跟写一个Activity一样的
//拿到传过来的数据
String msg = getIntent().getStringExtra("msg");
textview = (TextView) findViewById(R.id.textview);
textview.setText("收到消息:" + msg);
}
四个标识的意思分别是:
- 锁屏状态下显示
- 解锁
- 保持屏幕常量
- 打开屏幕
然后在AndroidManifest.xml中对该Activity加上如下属性。
<activity
android:name=".AlarmHandlerActivity"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:taskAffinity=""
android:theme="@android:style/Theme.Wallpaper.NoTitleBar" />
Android:excludeFromRecents控制在不在recent列表中显示。true时不显示;false显示,默认。
这个Activity其实就是我们需要的弹窗,类似于上图中的弹出的QQ消息,只不过是把Acitivity设置为不显示标题以及背景设置为屏幕桌面壁纸或者设置成透明的都行,然后中间的View就自己按需要来写。把Activity的背景设置为屏幕桌面壁纸只需要在AndroidManifest.xml中对应的Activity的标签下的theme属性设置为@android:style/Theme.Wallpaper.NoTitleBar就可以。
注意,设置了上面这个theme属性后,这个Activity要继承Activity,继承AppCompatActivity会报错。
二、新建一个广播,并在广播中启动弹窗Activity
重写onReceiver方法,并在方法中写上如下语句。收到需要的广播就类似于QQ收到新消息,然后判断是否需要弹出。
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: 收到广播");
Log.d(TAG, intent.getAction());
//拿到传来过来数据
String msg = intent.getStringExtra("msg");
//拿到锁屏管理者
KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.isKeyguardLocked()) { //为true就是锁屏状态下
//启动Activity
Intent alarmIntent = new Intent(context, AlarmHandlerActivity.class);
//携带数据
alarmIntent.putExtra("msg", msg);
//activity需要新的任务栈
alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmIntent);
}
}
在广播中启动Activity的context可能不是Activity对象,所以需要添加NEW_TASK的标志,否则启动时可能会报错
别忘了在AndroidManifest.xml中声明receiver,并添加过滤器,用来过滤广播,这接受我们需要的。
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="com.fu" />
</intent-filter>
</receiver>
三、添加权限
在AndroidManifest.xml中添加权限。
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
其实以上的差不多就已经实现了我们需要的功能。下面为了方便测试,演示下过,加的其他的步骤。
四、模拟演示
1.新建一个Service,并在里面实现延迟发送广播
@Override
public void onCreate() {
Log.d(TAG, "onCreate: ");
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.setAction("com.fu");
intent.putExtra("msg", "新消息1");
MyService.this.sendBroadcast(intent);
Log.d(TAG, "第一次发送广播");
}
}, 10000);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.setAction("com.fu");
intent.putExtra("msg", "新消息2");
MyService.this.sendBroadcast(intent);
Log.d(TAG, "第二次发送广播");
}
}, 20000);
}
上面代码是在service中的onCreate中,延迟10发送一次广播,延迟20秒又发送了一次广播,目的是为了让手机出于锁屏界面下收到广播,然后点亮屏幕弹出提示窗。
别忘了在AndroidManifest.xml中声明service
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" />
2.开启service
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
3.锁屏等待亮屏弹窗
这是锁屏界面下的截图
五、补充说明
如果弹窗的Activity没有被销毁,也就是说,第一次亮屏有弹窗,但我们没有去关闭它,而是又按下了锁屏键,这时第二次来消息的时候,就会调用onNewIntent()方法,那我们就重写onNewIntent()方法。
/**
* 这个方法是当这个activity没有销毁的时候,人为的按下锁屏键,然后再启动这个Activity的时候会去调用
*
* @param intent
*/
@Override
protected void onNewIntent(Intent intent) {
Log.i(TAG, "onNewIntent: 调用");
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) {
String msg = intent.getStringExtra("msg");
textview.setText("又收到消息:" + msg);
//点亮屏幕
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
wl.acquire();
wl.release();
}
}
- 弹窗activity的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.fu.notifydemo.AlarmHandlerActivity">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@android:color/white"
android:text="收到消息:"
android:textColor="@android:color/holo_red_dark"
android:textSize="25sp" />
</RelativeLayout>
以上就是本人对锁屏状态下点亮屏幕并弹窗提醒一些初步理解,如有错误的地方,还望指正。
参考文献: