安卓10程序退出的情况下某一时间点后用户第一次解锁手机时推送消息

最近作业里面有一个需求:在每一天的固定时间点之后用户第一次解锁时进行消息推送。

本想通过AlarmManager传递PendingItent打开后台service实现,但是发现程序退出之后或者锁屏状态下service不能正常启动(不知道是不是我的方法有问题)。

经过一番摸索发现了下面的方法:

设定静态BroadcastReciver通过AlarmManager延时发送自定义的消息启动,然后在BroadcastReciver里面动态注册监听解锁。直接上代码:(大多数情况下需要申请自启动权限和无省电优化)

public class ScreenUnlockReceiver extends BroadcastReceiver {

    private static final String TAG = "Receiver";
    public static final String ACTION_FIRST_UNLOCK_REMIND_REGISTER = "action.ready_remind_service";
    static ScreenUnlockReceiver receiver = null;

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action != null && action.equals(ACTION_FIRST_UNLOCK_REMIND_REGISTER)) {
            KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            if (mKeyguardManager != null)
                if (!mKeyguardManager.inKeyguardRestrictedInputMode()) {//如果到点了是解锁状态就直接提醒
                    NotificationUtils.remindSubmit(context);
                } else {//否则注册监听
                    registerRemindReceiver(context);
                    Log.i(TAG, "register");
                }

        } else if (action != null && action.equals(Intent.ACTION_USER_PRESENT)) {//监听到解锁
            NotificationUtils.remindSubmit(context);
            unregisterRemindReceiver(context);
            Log.i(TAG, "unregister");
        } else {
            Log.i(TAG, "no equals");

        }
    }

    private void unregisterRemindReceiver(Context context) {
        if (receiver != null)
            context.getApplicationContext().unregisterReceiver(receiver);
    }

    private void registerRemindReceiver(Context context) {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
        receiver = new ScreenUnlockReceiver();
        context.getApplicationContext().registerReceiver(receiver, intentFilter);
    }

}

 定时工具类:

根据安卓版本不同需要调用不同的方法来设置提醒,由于各家系统的策略不同通常会有一两分钟的误差。

public class AlarmUtils {
    private static final int REQUEST_CODE = 1;
    private static final String TAG = "AlarmUtils";
    public static int hour,minute,second;//想设定的时间
    public static void setAlarm(Context context) {

        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent pendingIntent = getPendingIntent(context);
        
                long readyTime = getReadyTime(hour,
                        minute,
                        second).getTimeInMillis();
                multiVersionSetAlarm(readyTime, alarmManager, pendingIntent);
            
    }

    private static void multiVersionSetAlarm(long readyTime, AlarmManager alarmManager, PendingIntent pendingIntent) {
        if (alarmManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC,
                        readyTime, pendingIntent);
            else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                        readyTime, pendingIntent);
            else alarmManager.set(AlarmManager.RTC_WAKEUP,
                        readyTime, pendingIntent);
        }
    }

    private static PendingIntent getPendingIntent(Context context) {
        Intent intent = new Intent(context, ScreenUnlockReceiver.class);
        intent.setAction(ScreenUnlockReceiver.ACTION_FIRST_UNLOCK_REMIND_REGISTER);
        return PendingIntent.getBroadcast(context,//getApplicationContext(),
                REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    }

    private static Calendar getReadyTime(int hour, int minute, int second) {
        Calendar scheduledTime = Calendar.getInstance();
        Log.i(TAG, "getReadyTime: ");
        scheduledTime.set(Calendar.HOUR_OF_DAY, hour);
        scheduledTime.set(Calendar.MINUTE, minute);
        scheduledTime.set(Calendar.SECOND, second);
        if (Calendar.getInstance().after(scheduledTime))
            scheduledTime.add(Calendar.DATE, 1);//今天的预定时间已过则设置为下一天的
        Log.i(TAG, scheduledTime.toString());
        return scheduledTime;
    }
}

弹出提醒框工具类:

public class NotificationUtils {
    private static final int OPEN_MAIN_ACTIVITY_REQUEST_CODE = 1;
    private static final String REMIND_SUBMIT_CHANNEL_ID = "reminder_notification_channel";
    private static final int REMIND_SUBMIT_ID = 1;

    public static void remindSubmit(Context context) {
        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(
                    REMIND_SUBMIT_CHANNEL_ID,
                    REMIND_SUBMIT_CHANNEL_ID,
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(mChannel);
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, REMIND_SUBMIT_CHANNEL_ID)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle(context.getString(R.string.notify_title))
                .setContentText(context.getString(R.string.notify_text))
                .setDefaults(Notification.DEFAULT_VIBRATE)
                .setContentIntent(contentIntent(context));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
                && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            builder.setPriority(NotificationCompat.PRIORITY_HIGH);
        }
        notificationManager.notify(REMIND_SUBMIT_ID, builder.build());
    }


    private static PendingIntent contentIntent(Context context) {
        Intent startActivityIntent = new Intent(context, MainActivity.class);
        return PendingIntent.getActivity(
                context,
                OPEN_MAIN_ACTIVITY_REQUEST_CODE,
                startActivityIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值