本篇讲述小米便签中的定时提醒功能。
  便签,可以理解为一件事情,一项任务,有个定时提醒的功能,还是蛮不错的~
  
  小米便签定时功能,是当编辑便签的时候,有个菜单项,选了之后,就弹出一个“日期对话框”,
选择了日期,就设置了定时功能。

下面讲解技术实现的整体思路(很多地方我也不懂,不懂的就搜索)
  
  AndroidManifest.xml配置

<receiver android:name=".ui.AlarmInitReceiver" ><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter></receiver><receiverandroid:name="net.micode.notes.ui.AlarmReceiver"android:process=":remote" ></receiver><activityandroid:name=".ui.AlarmAlertActivity"android:label="@string/app_name"android:launchMode="singleInstance"android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" ></activity>

定义了2个receiver和1个activity。
  
  Broadcast Receiver(广播接收器)是Android中的四大组件之一。
  
  AlarmInitReceiver的配置“android.intent.action.BOOT_COMPLETED”,表明
  Android手机开机后,会发送android.intent.action.BOOT_COMPLETED广播,监听这个广播就能监听开机。
  开机之后,就处理已有的便签,逐条比较日期,如果有到期的,就用AlarmManager提醒用户。
  
  场景1.刚刚提到的,开机的时候,需要处理已有的便签。

public class AlarmInitReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {long currentDate = System.currentTimeMillis();Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,PROJECTION,NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,new String[] { String.valueOf(currentDate) },null);if (c != null) {if (c.moveToFirst()) {do {long alertDate = c.getLong(COLUMN_ALERTED_DATE);Intent sender = new Intent(context, AlarmReceiver.class);sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID)));PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0);AlarmManager alermManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);} while (c.moveToNext());}c.close();}}
}

场景2:编辑便签的时候,需要设置日期。

NodeEditActivity的菜单事件

case R.id.menu_delete_remind:mWorkingNote.setAlertDate(0, false);break;WorkingNote       public void setAlertDate(long date, boolean set) {if (date != mAlertDate) {mAlertDate = date;mNote.setNoteValue(NoteColumns.ALERTED_DATE,String.valueOf(mAlertDate));}if (mNoteSettingStatusListener != null) {mNoteSettingStatusListener.onClockAlertChanged(date, set);}}事件监听器,最终还是NodeEditActivitypublic void onClockAlertChanged(long date, boolean set) {/*** User could set clock to an unsaved note, so before setting the alert* clock, we should save the note first*/if (!mWorkingNote.existInDatabase()) {saveNote();}if (mWorkingNote.getNoteId() > 0) {Intent intent = new Intent(this, AlarmReceiver.class);intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI,mWorkingNote.getNoteId()));PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,intent, 0);AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));showAlertHeader();if (!set) {alarmManager.cancel(pendingIntent);} else {alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);}} else {/*** There is the condition that user has input nothing (the note is* not worthy saving), we have no note id, remind the user that he* should input something*/Log.e(TAG, "Clock alert setting error");showToast(R.string.error_note_empty_for_clock);}}

如果用户设置了时间,就通过AlarmManager放一个监听事项。
  
  场景3:提醒广播的最终执行者
  AlarmInitReceiver是负责,系统启动的时候,处理notes。
  AlarmReceiver一直在等待“有note需要提醒用户”的广播。

public class AlarmReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {intent.setClass(context, AlarmAlertActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}
}时间到期,提醒的活动是AlarmAlertActivity。public class AlarmAlertActivity extends Activity implements OnClickListener,OnDismissListener {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);final Window win = getWindow();win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);if (!isScreenOn()) {win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);}Intent intent = getIntent();try {mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));mSnippet = DataUtils.getSnippetById(this.getContentResolver(),mNoteId);mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, SNIPPET_PREW_MAX_LEN)+ getResources().getString(R.string.notelist_string_info): mSnippet;} catch (IllegalArgumentException e) {e.printStackTrace();return;}mPlayer = new MediaPlayer();if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId,Notes.TYPE_NOTE)) {showActionDialog();playAlarmSound();} else {finish();}}
}

需要特别学习的Android机制和类库。
  a.AlarmManager
  AlarmManager,顾名思义,就是“提醒”,是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent。
  简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent。
  通常我们使用PendingIntent,PendingIntent可以理解为Intent的封装包,简单的说就是在Intent上在加个指定的动作。
  在使用Intent的时候,我们还需要在执行startActivity、startService或sendBroadcast才能使Intent有用。
  而PendingIntent的话就是将这个动作包含在内了。
  b.MediaPlayer播放声音。
  c.RingtoneManager铃声。
  d.PowerManager和WindowManager。
  播放铃声的时候,首先判断PowerManager.isScreenOn判断屏幕是否"亮",如果没亮需要做一些处理。
  WindowManager允许app和窗口交互(The interface that apps use to talk to the window manager. )。
  应该就是在锁屏等情况,做一点特殊处理,还没有具体去细看。
  
  PowerManager,电源管理~
  
  写在最后:
  研究过程中,遇到很多不很懂的代码,网上搜索学习下,基本就知道怎么回事了。
  2011年,4年前就有过2个月时间的学习。
  现在工作好几年了,各种技术都研究或者了解过。
  现在,重新看Android应用开发,难度不是很大。
  对Android有了整体的了解,看了几本书,就可以自己研究写代码了。
  不懂的,网上找找资料,然后自己总结,时间长了,估计1~2年,就算是了熟练工了。
  预计,到2016年下半年,我的Android水平就很不错了。
  在武汉这种二线城市,如果让我搞Android开发,薪资在8k~15k左右吧~
  也许~
  
  
  参考资料
  Android开机广播android.intent.action.BOOT_COMPLETED
  http://my.oschina.net/onlytwo/blog/281892
  
  AndroidManifest.xml文件详解(receiver)
  http://blog.csdn.net/think_soft/article/details/7583047
  
  Android中Broadcast Receiver组件详解
  http://blog.csdn.net/zuolongsnail/article/details/6450156
  
  Android中的AlarmManager的使用
  http://blog.csdn.net/wangxingwu_314/article/details/8060312
  
  【Android笔记】MediaPlayer基本使用方式
  http://blog.csdn.net/ddna/article/details/5176233#reply
  
  Media开发之铃声设置(RingtoneManager)
  http://rocking-kaan-126-com.iteye.com/blog/1228215
  
  Android判断屏幕锁屏的方法总结
  http://www.2cto.com/kf/201404/296615.html
  
  android 之 PowerManager 与电源管理
  http://blog.csdn.net/xieqibao/article/details/6562256

小米开源便签Notes-源码研究(2)-定时提醒的便签相关推荐

  1. WebRTC源码研究(4)web服务器工作原理和常用协议基础

    文章目录 WebRTC源码研究(4)web服务器工作原理和常用协议基础 前言 做WebRTC 开发为啥要懂服务器开发知识 1. Web 服务器简介 2. Web 服务器的类型 3. Web 服务器的工 ...

  2. WebRTC源码研究(4)web服务器工作原理和常用协议基础(转载)

    前言 前面3篇博客分别对WebRTC框架的介绍,WebRTC源码目录,WebRTC的运行机制进行了介绍,接下来讲解一点关于服务器原理的知识.后面博客会写关于WebRTC服务器相关的开发,目前git上面 ...

  3. 生成对抗网络(GANs)的资料小结,另附:资源|17类对抗网络经典论文及开源代码(附源码)

    1.GANs的一些资料链接 ************************************************** *********************************** ...

  4. 产线数字化软件源码_软件生产线技术、开源软件声明、源码下载地址

    软件生产线技术.开源软件声明.源码下载地址 软件生产线指生产软件的软件,先利用建模工具软件用图解的形式给出应用系统的系统模型,之后自动生成应用系统可执行程序,自动完成建立应用系统的工作.它能有效提高应 ...

  5. 轻触开源(三)-Gson项目源码解析_贰

    2019独角兽企业重金招聘Python工程师标准>>> 转载请注明出处:https://my.oschina.net/u/874727/blog/750473 Q:102525062 ...

  6. WebRTC源码研究(1)WebRTC架构

    文章目录 WebRTC源码研究(1)WebRTC架构 1. WebRTC简介 2. WebRTC的能力 2.1 抓住属于WebRTC的5G时代风口 2.1.1 浏览器的支持情况 2.1.2 大厂的加入 ...

  7. 二、Neo4j源码研究系列 - 单步调试

    二.Neo4j源码研究系列 - 单步调试 一.背景介绍 上一篇我们已经把了neo4j的源码准备以及打包流程完成了,本篇将讲解如何对neo4j进行单步调试.对于不了解如何编译打包neo4j的读者,请阅读 ...

  8. 图集php源码,「亲测」2020最新开源php图床源码v2.1.3 免授权无后门+搭建教程

    「亲测」2020最新开源php图床源码v2.1.3 免授权无后门+搭建教程 一款php图床源码,v2.1.3为当前最新版本,它是我目前为止看到的唯一一款开源的既可爱又简洁的图床程序了,基于烟雨写的QA ...

  9. 一起谈.NET技术,.NET Framework源码研究系列之---万法归宗Object

    经过前面三篇关于.NET Framework源码研究系列的随笔,相信大家都发现其实.NET Framework的实现其实并不复杂,也许跟我们自己做的项目开发差不多.本人也是这样的看法.不过,经过仔细深 ...

  10. Apache Jackrabbit源码研究(五)

    上文最后提到jackrabbit的检索默认实现类QueryImpl,先熟悉一下该类的继承层次 QueryImpl继承自抽象类AbstractQueryImpl,而抽象类实现了Query接口(JCR的接 ...

最新文章

  1. 5 年提速 500 倍,英伟达 GPU 创纪录突破与技术有哪些?
  2. Scrapy入门教程
  3. Android Studio 单刷《第一行代码》系列 07 —— Broadcast 广播
  4. 看我如何跨虚拟机实现Row Hammer攻击和权限提升
  5. 在CentOS6.x下安装Compiz——桌面立方体,特效种种
  6. 在Spring Boot使用H2内存数据库
  7. eclipse:解决修改文件需要重启tomcat问题
  8. python数据科学-多变量数据分析
  9. maven 父maven_Maven的春天
  10. dorado 7 怎么样_一点点奶茶怎么样?消费者眼中的网红奶茶
  11. java虚拟机-d参数配置_Java虚拟机(五):常用JVM配置参数
  12. ASCII码查询及简单说明
  13. macos ntfs插件_NTFS for Mac 助手 - Mac读写NTFS磁盘工具
  14. matlab中画花瓣,matlab花瓣图的编程原理是什么,向天下大侠求解!!!!给力的? 爱问知识人...
  15. halcon轮廓擦除_【Halcon】轮廓处理
  16. 关于Asterisk的传真以及ForIP的概念
  17. 2022年中国国债收益率走势(附一年期、二年期、三年期、七年期、十年期、二十年期、三十年期)[图
  18. Either类java_在Java 8中有相当于Scala的Either吗?
  19. 【微信小程序】用户授权及getUserProfile接口使用
  20. 服务器响应状态码statusCode

热门文章

  1. 计算机桌面软件图标没了,手把手教你电脑桌面图标都不见了怎么办
  2. 基于vhdl的分频器设计
  3. WordPress社交网络菜单图标更改——SVG图标
  4. 社交网络分析的 R 基础:(一)初探 R 语言
  5. 信息化知识-1.1信息化知识
  6. python 报警声音的实现
  7. 加载配置文件(xml文件,properties文件)demo
  8. win10计算机性能设置,巧设置让Win10运行更流畅
  9. 专利交底书怎么写 -
  10. Java中解密微信加密数据工具类