Android在锁屏状态下实现消息提醒(震动+提示音)

您所在的位置:网站首页 androidstudio弹窗提醒功能 Android在锁屏状态下实现消息提醒(震动+提示音)

Android在锁屏状态下实现消息提醒(震动+提示音)

2023-10-15 00:47| 来源: 网络整理| 查看: 265

导读:

最近在开发一个定时提醒业务,类似于闹钟,然后遇到了一个问题,当APP应用在后台运行时,用户关闭了手机屏幕(手机进入灭屏休眠状态),这个时候使用系统震动和闹钟没有起到作用。why? 同样是灭屏休眠状态,为什么QQ、微信等都可以有消息提醒,我的APP却不行呢,真是百思不得其姐,百度了一番才找到解决方法。

解决思路:

1、APP应用退到后台,我们想继续做些什么,当然是使用Service服务了。

2、在Activity活动里定义一个广播接收器(BroadcastReceiver),用于接收Service服务的命令。

3、在Activity活动里添加标志位(必须添加),允许锁屏状态下显示消息(解锁屏幕)。

4、Service服务在需要给用户进行消息提醒时,向广播接收器发送命令,然后由广播接收器来执行即可。

具体步骤:

一、在MainActivity.class活动的onCreate()方法里添加标志位,代码如下:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 添加标志位,允许锁屏状态下显示消息,四个标志位分别是: * 1.锁屏状态下显示 * 2.解锁 * 3.保持屏幕长亮(可选) * 4.打开屏幕 * 当Activity启动的时候,它会解锁并亮屏显示 */ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED //锁屏状态下显示 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD //解锁 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON //保持屏幕长亮 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); //打开屏幕 }

二、在MainActivity.class活动里定义一个内部类广播接收器,代码如下:

/** * 定义广播接收器,用于执行Service服务的需求(内部类) */ private class ServiceNeedBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { /*------------这里是要在Activity活动里执行的代码----------*/ //手机震动 ToolUtils.playVibrate(MainActivity.this, true); //播放系统默认闹钟铃声 ToolUtils.defaultAlarmMediaPlayer(MainActivity.this); /*------------这里是要在Activity活动里执行的代码----------*/ } }

这里提供一下ToolUtils.java工具类里的震动和闹铃代码:

package com.xiao7.pump.Utils; import android.annotation.SuppressLint; import android.app.KeyguardManager; import android.app.Service; import android.content.Context; import android.media.AudioAttributes; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Build; import android.os.PowerManager; import android.os.Vibrator; public class ToolUtils { private static Vibrator vibrator; private static PowerManager.WakeLock wakeLock; /** * 唤醒手机屏幕并解锁 * * @param context */ @SuppressLint("InvalidWakeLockTag") public static void acquire(Context context) { try { //获取电源管理器对象 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); //获取PowerManager.WakeLock对象 wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "bright"); //点亮屏幕30秒 wakeLock.acquire(30 * 1000); //灭屏(释放锁) if (null != wakeLock) { wakeLock.release(); } KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); //这里参数”unLock”作为调试时LogCat中的Tag KeyguardManager.KeyguardLock kl = km.newKeyguardLock("unLock"); //解锁 kl.disableKeyguard(); } catch (Exception ex) { } } /** * 手机震动 * * @param context * @param isRepeat 是否重复震动 */ public static void playVibrate(Context context, boolean isRepeat) { /* * 设置震动,用一个long的数组来表示震动状态(以毫秒为单位) * 如果要设置先震动1秒,然后停止0.5秒,再震动2秒则可设置数组为:long[]{1000, 500, 2000}。 * 别忘了在AndroidManifest配置文件中申请震动的权限 */ try { vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); long[] patern = new long[]{1000, 500, 2000}; AudioAttributes audioAttributes = null; /** * 适配android7.0以上版本的震动 * 说明:如果发现5.0或6.0版本在app退到后台之后也无法震动,那么只需要改下方的Build.VERSION_CODES.N版本号即可 */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_ALARM) //key .build(); vibrator.vibrate(patern, isRepeat ? 1 : -1, audioAttributes); }else { vibrator.vibrate(patern, isRepeat ? 1 : -1); } } catch (Exception ex) { } } /** * 关闭震动 */ public static void closeVibrate() { if (vibrator != null) { vibrator.cancel(); vibrator = null; } } /** * 播放系统默认提示音 * * @return MediaPlayer对象 * @throws Exception */ public static void defaultMediaPlayer(Context mContext) { try { Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); Ringtone r = RingtoneManager.getRingtone(mContext, notification); r.play(); } catch (Exception ex) { } } /** * 播放系统默认来电铃声 * * @return MediaPlayer对象 * @throws Exception */ public static void defaultCallMediaPlayer(Context mContext) { try { Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); Ringtone r = RingtoneManager.getRingtone(mContext, notification); r.play(); } catch (Exception ex) { } } /** * 播放系统默认闹钟铃声 * * @return MediaPlayer对象 * @throws Exception */ public static void defaultAlarmMediaPlayer(Context mContext) { try { Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); Ringtone r = RingtoneManager.getRingtone(mContext, notification); r.play(); } catch (Exception ex) { } } }

三、在MainActivity.class活动的onCreate()方法里注册广播实例,代码如下:

public class MainActivity extends AppCompatActivity { //声明一个操作常量字符串 public static final String ACTION_SERVICE_NEED = "action.ServiceNeed"; //声明一个内部广播实例 public ServiceNeedBroadcastReceiver broadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 添加标志位,允许锁屏状态下显示消息,四个标志位分别是: * 1.锁屏状态下显示 * 2.解锁 * 3.保持屏幕长亮(可选) * 4.打开屏幕 * 当Activity启动的时候,它会解锁并亮屏显示 */ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED //锁屏状态下显示 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD //解锁 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON //保持屏幕长亮 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); //打开屏幕 /** * 注册广播实例(在初始化的时候) */ IntentFilter filter = new IntentFilter(); //给意图过虑器增加一个Action(用来区分广播来源,相当于是广播的身份证) filter.addAction(ACTION_SERVICE_NEED); broadcastReceiver = new ServiceNeedBroadcastReceiver(); registerReceiver(broadcastReceiver, filter); }

四、Service服务里给广播接口器发送指令(关于Service服务的用法,我就直接省略了,不懂的可以看我其他的博文),代码如下:

public class taskService extends Service { /** * 调用startService()启动服务时的回调 */ @Override public int onStartCommand(Intent intent, int flags, int startId) { /在Service服务类中发送广播消息给Activity活动界面 Intent intentBroadcastReceiver = new Intent(); //设置意图过虑器Action(用来区分广播来源,相当于是广播的身份证) intentBroadcastReceiver.setAction(MainActivity.ACTION_SERVICE_NEED); //添加NEW_TASK标志位(必须加这个,否则不能在锁屏下实现消息提醒) intentBroadcastReceiver.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //发送无序广播 sendBroadcast(intentBroadcastReceiver); return super.onStartCommand(intent, flags, startId); } /** * 通过bindService()绑定到服务的客户端 */ @Override public IBinder onBind(Intent intent) { return null; } }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3