一、原理简介

每次向AlarmManager里写入提醒时间,当到达提醒时间激活一个广播接收器,进行相应的提醒窗口弹出或通知,并进行下一次闹钟设置。注意重启的时候需要监听系统的广播,并进行重新设置闹钟,大致原理就是这样。

设置闹钟用到如下代码:

AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent("android.alarm.demo.action");
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, timeInMillis, sender);

相应的广播接收器:

public class AlarmReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        if (("android.alarm.demo.action").equals(intent.getAction())) {
        System.out.println(System.currentTimeMillis()+":触发成功");
            //第1步中设置的闹铃时间到,这里可以弹出闹铃提示并播放响铃
        Intent i=new Intent();
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        i.setClass(context, AlarmAlert.class);
        context.startActivity(i);
       
            //可以继续设置下一次闹铃时间;
        SharedPreferences sp = context.getSharedPreferences("ALARM_DATA", Context.MODE_PRIVATE);
        if(sp.getBoolean("flag_1", false)){
        Tool.setAlarmTime(context,  
            Tool.getNextAlarmTime(sp.getString("dateValue", "1,2,3,4,5,6,7")
            ,sp.getString("startTime", "18:00")));
        }
        }
    }
}

二、截图

三、详细代码设计

1、activity_main.xml,主要布局如上面的gif首屏
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="fill_parent"android:layout_height="fill_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity" android:orientation="vertical"><LinearLayout android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextView android:id="@+id/textview1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="15sp"android:text="提醒功能" />  <RelativeLayout android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="vertical"><ToggleButtonandroid:id="@+id/toggleButton1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="true"android:textOff="关闭"android:textOn="开启" android:layout_alignParentRight="true"/></RelativeLayout></LinearLayout><LinearLayout android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextView android:id="@+id/textview2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="15sp"android:text="震动提醒" />  <RelativeLayout android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="vertical"><ToggleButtonandroid:id="@+id/toggleButton2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="true"android:textOff="关闭"android:textOn="开启" android:layout_alignParentRight="true"/></RelativeLayout></LinearLayout><LinearLayout android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextView android:id="@+id/textview3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="15sp"android:text="声音提醒" />  <RelativeLayout android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="vertical"><ToggleButtonandroid:id="@+id/toggleButton3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="true"android:textOff="关闭"android:textOn="开启" android:layout_alignParentRight="true"/></RelativeLayout></LinearLayout><Buttonandroid:id="@+id/button1"android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="vertical"android:text="设置提醒时间"/>
</LinearLayout>

2、java代码片段:MainActivity设置闹钟界面,BootReceiver系统重启广播接收器,AlarmReceiver闹钟时间到广播接收器,Tool设置闹钟工具类,AlarmAlert时间到后弹出Dialog类型Activity。

package com.example.alarmdemo;
import java.util.Calendar;
import android.os.Bundle;
import android.app.Activity;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TimePicker;
import android.widget.ToggleButton;public class MainActivity extends Activity {private ToggleButton tb1,tb2,tb3;private Button bt;private boolean flag_1=false,flag_2=false,flag_3=false;private String startTime=null,dateValue=null;private Context context;private SharedPreferences sp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tb1=(ToggleButton)findViewById(R.id.toggleButton1);tb2=(ToggleButton)findViewById(R.id.toggleButton2);tb3=(ToggleButton)findViewById(R.id.toggleButton3);bt=(Button)findViewById(R.id.button1);context = MainActivity.this;       sp = context.getSharedPreferences("ALARM_DATA",MODE_PRIVATE);flag_1=sp.getBoolean("flag_1", false);flag_2=sp.getBoolean("flag_2", false);flag_3=sp.getBoolean("flag_3", false);startTime=sp.getString("startTime", "18:00");dateValue=sp.getString("dateValue", "1,2,3,4,5,6,7");tb1.setChecked(flag_1);tb2.setChecked(flag_2);tb3.setChecked(flag_3);setAlarm();System.out.println(startTime+":读出闹钟数据");System.out.println("flag_1:"+flag_1+"|flag_2:"+flag_2+"|flag_3:"+flag_3);tb1.setOnCheckedChangeListener(new OnCheckedChangeListener() {           @Overridepublic void onCheckedChanged(CompoundButton arg0, boolean arg1) {flag_1=arg1;savedFlag("flag_1",flag_1);  setAlarm();}});tb2.setOnCheckedChangeListener(new OnCheckedChangeListener() {            @Overridepublic void onCheckedChanged(CompoundButton arg0, boolean arg1) {//flag_2可以不使用flag_2=arg1;savedFlag("flag_2",flag_2);}});tb3.setOnCheckedChangeListener(new OnCheckedChangeListener() {            @Overridepublic void onCheckedChanged(CompoundButton arg0, boolean arg1) {//flag_3可以不使用flag_3=arg1;savedFlag("flag_3",flag_3);}});bt.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){showTimePickerDialog();}});}//设置闹钟private void setAlarm(){if(flag_1){Tool.setAlarmTime(context,  Tool.getNextAlarmTime(dateValue,startTime)); }else{Tool.cancelAlarmTime(context);} }/*** 显示选择时间对话框*/private void showTimePickerDialog(){Calendar c = Calendar.getInstance();int hourOfDay = c.get(Calendar.HOUR_OF_DAY);int minute = c.get(Calendar.MINUTE);TimePickerDialog time = new TimePickerDialog(context, new OnTimeSetListener(){       @Overridepublic void onTimeSet(TimePicker view, int hourOfDay, int minute) {// TODO Auto-generated method stubstartTime=hourOfDay+":"+minute;//存入数据Editor editor = sp.edit();editor.putString("startTime", hourOfDay+":"+minute);editor.commit();System.out.println(startTime+":闹钟已设置");setAlarm();}}, hourOfDay, minute, true);time.show();}//保存状态private void savedFlag(String flag,boolean check){//存入数据Editor editor = sp.edit();editor.putBoolean(flag, check);editor.commit();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}
package com.example.alarmdemo;import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;public class Tool {/*** 按星期提醒,如星期一、星期三 ,  参数dateValue格式:1,3* startTime:为当天开始时间,如上午9点, 参数格式为09:00*/public static long getNextAlarmTime(String dateValue,String startTime) {final SimpleDateFormat fmt = new SimpleDateFormat();final Calendar c = Calendar.getInstance();final long now = System.currentTimeMillis();//设置开始时间try {fmt.applyPattern("HH:mm");Date d = fmt.parse(startTime);c.set(Calendar.HOUR_OF_DAY, d.getHours());c.set(Calendar.MINUTE, d.getMinutes());c.set(Calendar.SECOND, 0);c.set(Calendar.MILLISECOND, 0);} catch (Exception e) {e.printStackTrace();}long nextTime = 0;final long[] checkedWeeks = parseDateWeeks(dateValue);if (null != checkedWeeks) {for (long week : checkedWeeks) {c.set(Calendar.DAY_OF_WEEK, (int) (week + 1));long triggerAtTime = c.getTimeInMillis();if (triggerAtTime <= now) { // 下周triggerAtTime += AlarmManager.INTERVAL_DAY * 7;}// 保存最近闹钟时间if (0 == nextTime) {nextTime = triggerAtTime;} else {nextTime = Math.min(triggerAtTime, nextTime);}}} return nextTime;}public static long[] parseDateWeeks(String value) {long[] weeks = null;try {final String[] items = value.split(",");weeks = new long[items.length];int i = 0;for (String s : items) {weeks[i++] = Long.valueOf(s);}} catch (Exception e) {e.printStackTrace();}return weeks;}public static void setAlarmTime(Context context,  long timeInMillis) {AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent("android.alarm.demo.action");PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);am.set(AlarmManager.RTC_WAKEUP, timeInMillis, sender);System.out.println(System.currentTimeMillis()+":闹钟已设置");}public static void cancelAlarmTime(Context context) {AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent("android.alarm.demo.action");PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);am.cancel(sender);System.out.println(System.currentTimeMillis()+":闹钟已取消");}
}
package com.example.alarmdemo;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;public class AlarmReceiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {if (("android.alarm.demo.action").equals(intent.getAction())) {System.out.println(System.currentTimeMillis()+":触发成功");//第1步中设置的闹铃时间到,这里可以弹出闹铃提示并播放响铃Intent i=new Intent();i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setClass(context, AlarmAlert.class);context.startActivity(i);//可以继续设置下一次闹铃时间;SharedPreferences sp = context.getSharedPreferences("ALARM_DATA", Context.MODE_PRIVATE);if(sp.getBoolean("flag_1", false)){Tool.setAlarmTime(context,  Tool.getNextAlarmTime(sp.getString("dateValue", "1,2,3,4,5,6,7"),sp.getString("startTime", "18:00")));}}}
}
package com.example.alarmdemo;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;public class BootReceiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {//重新计算闹铃时间,并调第一步的方法设置闹铃时间及闹铃间隔时间SharedPreferences sp = context.getSharedPreferences("ALARM_DATA", Context.MODE_PRIVATE);if(sp.getBoolean("flag_1", false)){Tool.setAlarmTime(context,  Tool.getNextAlarmTime(sp.getString("dateValue", "1,2,3,4,5,6,7"),sp.getString("startTime", "18:00")));}}}
}
package com.example.alarmdemo;import java.io.IOException;import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Vibrator;public class AlarmAlert extends Activity {private boolean shouldPlayBeep=true;private MediaPlayer mediaPlayer=null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SharedPreferences sp = this.getSharedPreferences("ALARM_DATA", Context.MODE_PRIVATE);//铃声模式开启if(sp.getBoolean("flag_2", false)){this.setVolumeControlStream(AudioManager.STREAM_MUSIC); //如果当前是铃音模式,则继续准备下面的 蜂鸣提示音操作,如果是静音或者震动模式。就不要继续了。因为用户选择了无声的模式,我们就也不要出声了。 AudioManager audioService = (AudioManager) this .getSystemService(Context.AUDIO_SERVICE); if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { shouldPlayBeep = false; }if(shouldPlayBeep){mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);// When the beep has finished playing, rewind to queue up another one. mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer player) { } });AssetFileDescriptor file = this.getResources().openRawResourceFd( R.raw.alert); try { mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength()); file.close(); mediaPlayer.setVolume(1.0f, 1.0f); mediaPlayer.prepare(); } catch (IOException ioe) { ioe.printStackTrace(); mediaPlayer = null; }if (shouldPlayBeep && mediaPlayer != null) { mediaPlayer.start(); } }}//震动模式开启if(sp.getBoolean("flag_3", false)){Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);//震动一次 vibrator.vibrate(2000); //第一个参数,指代一个震动的频率数组。每两个为一组,每组的第一个为等待时间,第二个为震动时间。 // 比如 [2000,500,100,400],会先等待2000毫秒,震动500,再等待100,震动400 //第二个参数,repest指代从 第几个索引(第一个数组参数) 的位置开始循环震动。 //会一直保持循环,我们需要用 vibrator.cancel()主动终止 //vibrator.vibrate(new long[]{2000,500,100,400},0); }new AlertDialog.Builder(AlarmAlert.this).setTitle("重要提示").setMessage("到点了!").setPositiveButton("确认",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int whichButton) {if(mediaPlayer!=null){mediaPlayer.stop();}finish();}}).show();}
}

3、AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.alarmdemo"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="15" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@android:style/Theme.NoTitleBar" ><activityandroid:name="com.example.alarmdemo.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name="com.example.alarmdemo.AlarmAlert"android:theme="@android:style/Theme.Dialog" /><receiver android:name="com.example.alarmdemo.AlarmReceiver"><intent-filter><action android:name="android.alarm.demo.action" /></intent-filter></receiver><receiver android:name="com.example.alarmdemo.BootReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter></receiver></application><!-- 震动权限 --><uses-permission android:name="android.permission.VIBRATE"/><!-- 访问系统开机权限 --><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
</manifest>

四、DEMO下载

点此下载

软件内每日提醒功能,可整合到工程中相关推荐

  1. android 日历没有提醒功能,如何在Android 4中无提示地将日历事件添加到默认日历中而无任何提示?...

    小编典典 这是我最终成功的一个工作示例: ContentResolver cr = ctx.getContentResolver(); ContentValues values = new Conte ...

  2. java 创建日程到期提醒_在便签提醒类APP排行中哪个软件可以定时提醒每日日程待办?...

    在网络上搜索提醒类APP排行时,我们不难发现提醒类的APP是比较多的,使用提醒类APP时,大家可以将比较重要的工作计划.待办事项以及纪念日一一记录在提醒软件上,然后设置提醒时间,在到达提醒时间时软件会 ...

  3. 在便签提醒类APP排行中哪个软件可以定时提醒每日日程待办?

    在网络上搜索提醒类APP排行时,我们不难发现提醒类的APP是比较多的,使用提醒类APP时,大家可以将比较重要的工作计划.待办事项以及纪念日一一记录在提醒软件上,然后设置提醒时间,在到达提醒时间时软件会 ...

  4. 提醒事项 android,每日提醒 Pro-提醒事项、时间管理待办清单

    编辑点评 叫人提醒我不如叫APP提醒我 每日提醒 Pro-提醒事项.时间管理&待办清单 介绍 每日提醒 Pro-提醒事项.时间管理&待办清单 [每日提醒]是您贴心的提醒管家! 生活中总 ...

  5. 有什么软件能每天提醒自己坚持吗?每日定时提醒做某事的便签

    对于上班族来说,每天都有处理不完的事情,上班时间忙工作,下了班还要通过学习提高自己.有时候下班想玩一下,结果一玩就好几个小时,原本的学习计划也泡汤了.那么有没有什么软件,能每日定时提醒自己做某事,帮助 ...

  6. android 桌面提醒功能,安卓手机桌面上使用的工作提醒软件选择哪个?

    原标题:安卓手机桌面上使用的工作提醒软件选择哪个? 安卓手机可以说是目前手机市场的主力军,很多人的手机都是安卓系统,在辅助办公方面,手机上的工具也是比较多的.比如经常出差的人会将一些比较重要的备忘事项 ...

  7. 电脑桌面便签_电脑上哪些便签有提醒功能?求一款好用的电脑桌面提醒便签软件...

    对Windows操作系统比较熟悉的小伙伴,很多人都知道:Win7及其以上版本的电脑上有系统自带的Windows便签小工具.这个小工具虽然很不起眼,但是却很实用:因为它支持以彩色的背景将记录内容展示在电 ...

  8. 微信小程序消息推送,实现未完成计划的在微信内的定时提醒功能

    微信小程序消息提醒(微信内提醒) 提示:此处仅是小程序消息提醒的一个小例子,希望能够为大家抛砖引玉 目录 微信小程序消息提醒(微信内提醒) 需求及效果展示 一.实现思路 二.实现步骤 1.获取模板ID ...

  9. 苹果x来电闪光灯怎么设置_手机上使用的记事备忘便签软件怎么设置来电提醒功能?...

    在选择使用记事备忘便签软件时,很多人都希望便签软件支持设置来电提醒功能,毕竟一忙碌起来很容易错过便签软件的提醒,手机是大家在日常生活和工作中离不开的工具,可在手机上使用的记事备忘便签软件中,哪些可以设 ...

最新文章

  1. Python 调试:step into/step out/step over 的区别
  2. Atitit.论垃圾文件的识别与清理 文档类型垃圾文件 与api概要设计pa6.doc
  3. CRM和C4C里的组织架构 - Organizational Structure
  4. Teams App设备的地理位置能力
  5. ubuntu/wireshark --Lua: Error during loading: [string /usr/share/wireshark/init.lua]:45问题解决
  6. mysql罏在十三_MySQL高级知识(十三)——表锁
  7. 手机驱动开发_新加坡科学家开发由智能手机驱动的无电池“智能服装”
  8. Python 简写操作(for、if简写、匿名函数)
  9. 谷歌浏览器主页_谷歌浏览器客服人工服务电话怎样查询-客服人工服务电话查询方法...
  10. 2016级算法第四次上机-B ModricWang的序列问题
  11. Vue实现pdf、docx、jpg在线预览功能
  12. 独家对话阿里巴巴副总裁华先胜: 基础科研的突破,是大浪的源头
  13. 电压调整率和负载调整率 简单易懂
  14. 晶振的负载电容、寄生电容和动态电容及参考值
  15. 大学竞赛经历分享之微信小程序应用开发赛(1)
  16. for循环判定质数合数
  17. 举个栗子!Tableau技巧(59):学做两个集合的维恩图(文氏图)Venn diagram
  18. 百度Java二面面经
  19. 图像处理---亚像素
  20. 关于计算机培训策划案,2019年计算机培训策划书.docx

热门文章

  1. MAC OS 配置ATOM 编写python
  2. 在家也能健身(08):后腰和臀
  3. android饿了么购物车,Android仿饿了么加入购物车旋转控件自带闪转腾挪动画的按钮效果(实例详解)...
  4. OpenCV三角测量重建triangulatePoints原理解析
  5. 从零开发区块链应用(八)--结构体初识
  6. 投资科技的大厂里,竟是这家冲在了前面
  7. 最佳Linux笔记本电脑编程
  8. Drools WorkBench安装
  9. Mac 终端解压缩命令大全
  10. 2021海豚百度指数批量查询软件【急速】