美文网首页
AlarmManager实现定时任务

AlarmManager实现定时任务

作者: leap_ | 来源:发表于2019-08-14 14:14 被阅读0次

    AlarmManager用于创建定时任务,可以在约定的时间发送广播,开启服务等。

    用法:

    1. 创建AlarmManager实例
    private AlarmManager alarmManager;
    alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
    
    1. 创建一个Service作为定时任务
    public class AlarmService extends Service {
        public AlarmService() {
        }
        
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
        
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Toast.makeText(AlarmService.this, "闹钟来啦", Toast.LENGTH_SHORT).show();
            return super.onStartCommand(intent, flags, startId);
        }
        
    }
    

    onStartCommand()用于实现具体的闹钟逻辑,可以播放声音,震动,等等。
    不要忘记在manifest中注册service

    <service
            android:name=".service.AlarmService"
            android:enabled="true"
            android:exported="true"></service>
    
    1. 使用alarmManager创建闹钟
            Intent intent = new Intent(getContext(), AlarmService.class);
            PendingIntent pendingIntent = PendingIntent.getService(getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            alarmManager.set(AlarmManager.RTC_WAKEUP,time,pendingIntent);
    

    这里介绍一下PendingIntent,pending是延时的意思,PendingIntent 是一个延时的intent,他的功能和intent一样,只不过intent是即刻执行,而PendingIntent 是延时执行,用于Notification,alarmManager等延时操作。

    创建pendingIntent:
    • getActivity(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于启动一个Activity的PendingIntent对象,

    • getService(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于启动一个Service的PendingIntent对象

    • getBroadcast(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于向BroadcastReceiver的Intent广播的PendingIntent对象

    PendingIntent的flag:
    • FLAG_ONE_SHOT : this PendingIntent can only be used once. If set, after send() is called on it, it will be automatically canceled for you and any future attempt to send through it will fail.
    • FLAG_NO_CREATE : if the described PendingIntent does not already exist, then simply return null instead of creating it.
    • FLAG_CANCEL_CURRENT : if the described PendingIntent already exists, the current one is canceled before generating a new one. You can use this to retrieve a new PendingIntent when you are only changing the extra data in the Intent; by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT.
    • FLAG_UPDATE_CURRENT : if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.

    闹钟类型:

    • 对应的System.currentTimeMillis()(系统当前时间)时间:
      public static final int RTC_WAKEUP = 0;
      public static final int RTC = 1;
    • 对应SystemClock.elapsedRealtime()(系统运行时间)时间
      public static final int ELAPSED_REALTIME_WAKEUP = 2;
      public static final int ELAPSED_REALTIME = 3;
      带WakeUp的是能唤醒设备的

    添加系统自带的闹钟

    如果我们的app被杀死了,无论是带wakeup还是不带wakeup的闹钟,都是没用办法工作的,这时候我们可以添加一个系统闹钟,实现方式如下。

    private void createAlarm(String message, int hour, int minutes, int resId) {
            ArrayList<Integer> testDays = new ArrayList<>();
            testDays.add(Calendar.MONDAY);//周一
            testDays.add(Calendar.TUESDAY);//周二
            testDays.add(Calendar.FRIDAY);//周五
            String packageName = getActivity().getApplication().getPackageName();
            Uri ringtoneUri = Uri.parse("android.resource://" + packageName + "/" + resId);
            //action为AlarmClock.ACTION_SET_ALARM
            Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
                    //闹钟的小时
                    .putExtra(AlarmClock.EXTRA_HOUR, hour)
                    //闹钟的分钟
                    .putExtra(AlarmClock.EXTRA_MINUTES, minutes)
                    //响铃时提示的信息
                    .putExtra(AlarmClock.EXTRA_MESSAGE, message)
                    //用于指定该闹铃触发时是否振动
                    .putExtra(AlarmClock.EXTRA_VIBRATE, true)
                    //一个 content: URI,用于指定闹铃使用的铃声,也可指定 VALUE_RINGTONE_SILENT 以不使用铃声。
                    //如需使用默认铃声,则无需指定此 extra。
                    .putExtra(AlarmClock.EXTRA_RINGTONE, ringtoneUri)
                    //一个 ArrayList,其中包括应重复触发该闹铃的每个周日。
                    // 每一天都必须使用 Calendar 类中的某个整型值(如 MONDAY)进行声明。
                    //对于一次性闹铃,无需指定此 extra
                    .putExtra(AlarmClock.EXTRA_DAYS, testDays)
                    //如果为true,则调用startActivity()不会进入手机的闹钟设置界面
                    .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
            if (intent.resolveActivity(getContext().getPackageManager()) != null) {
                startActivity(intent);
            }
        }
    

    不要忘记权限

        <!--设置闹钟-->
        <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    

    这个思路的重点是intent:

    Action:

    ACTION_SET_ALARM

    Extra:

    EXTRA_HOUR:小时

    EXTRA_MINUTES:分钟

    EXTRA_MESSAGE:闹钟msg

    EXTRA_DAYS:An ArrayList including each week day on which this alarm should be repeated. Each day must be declared with an integer from the Calendar class such as MONDAY. For a one-time alarm, do not specify this extra.

    EXTRA_RINGTONE:A content: URI specifying a ringtone to use with the alarm, or VALUE_RINGTONE_SILENT for no ringtone. To use the default ringtone, do not specify this extra.

    EXTRA_VIBRATE:是否震动

    EXTRA_SKIP_UI:A boolean specifying whether the responding app should skip its UI when setting the alarm. If true, the app should bypass any confirmation UI and simply set the specified alarm.如果true不会进入系统闹钟页面,直接创建一个闹钟。

    相关文章

      网友评论

          本文标题:AlarmManager实现定时任务

          本文链接:https://www.haomeiwen.com/subject/rlqgjctx.html