DeskClock分析文档
PendingIntent就是一个Intent的描述,我们可以把这个描述交给别的程序,别的程序根据这个描述在后面的别的时间做你安排做的事情 · PendingIntent和Intent的区别: · 区别一:
Intent 是及时启动,intent 随所在的activity 消失而消失。
PendingIntent可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例,当前activity并不能马上启动它所包含的intent,而是在外部执行pendingintent时,调用intent的。之所以他有这样的特性,正由于pendingintent中 保存有当前App的Context。 · 区别二:
Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据 Pendingintent,一般用在Notification上,可以理解为延迟执行的intent。
? AlarmManager
· Alarm manager 主要管理硬件时钟。一些与时间相关的应用,如日历,闹钟等需要使用Alarm
Manager的服务。Alarm manager功能相对比较简单,相关代码位于
· AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); · frameworks/base/core/jni/server/com_android_server_AlarmManagerService.cpp
这部分代码直接管理硬件时钟,设备名为/dev/alarm。包括打开设备,关闭设备,设置时区,设置触发时间 (timeout),以及等待时钟触
· frameworks/base/services/java/com/android/server/AlarmManagerService.java
这部分封装目录一中的代码,向上提供java接口,同时与客户端(如calendar)交互,接收来自客户端的时钟设置请求,并在时钟触发时通知客户端。
? ContentObserver
ContentObserver有点类似于BroadcastReceiver,当某类事件发生时进行调用.ContentObserver一般和系统或第三方程序提供的Provider一起使用.
· 当为某个URI注册了ContentObserver后,对其进行操作后都会调用注册的回调函数
mContext.getContentResolver().registerContentObserver( Settings.System.CONTENT_URI, true, mFormatChangeObserver); · 当 Settings.System.CONTENT_URI有改变的时候就触发
public void onChange(boolean selfChange) { setDateFormat(); updateTime(); }
? Parcelable
· Parcelable的作用:在activity之间传递对象的时候,通过Parcelable来传递
· Preference 提供了一种轻量级的存取机制,主要是可以通过关键字读取和存储某个
Preference value · ContentResolver
6
DeskClock分析文档
· ContentResolver是通过URI来查询ContentProvider中提供的数据。 · ContentResolver cr = getContentResolver(); · ContentResolver的主要方法 final uri insert(Uri url, ContentValues values)Inserts a row into a table at the given URL. final int final Cursor final int
? newView和bindView的作用
· public void bindView(View view, Context context, Cursor cursor),重用一个已有的view,
使其显示当前cursor所指向的数据。
public View newView(Context context, Cursor cursor, ViewGroup parent),为cursor所指向的数据新建一个View对象,并显示其数据。
· 举个例子:比如你一个listview在一个屏幕里一次只能显示8条数据,那么第一次显示的时
候就会newView 8次生成8个View,调用bindView绑定8条数据,而你有16条数据,但你拖动滚动条看9-16条时,此时不会再调用newView了,而只能调用了bindView去绑定新的数据而了。这样就省了空间了。
? Notification与Toast都可以起到通知、提醒的作用。但它们的实现原理和表现形式却完全
不一样。Toast其实相当于一个组件(Widget)。有些类似于没有按钮的对话 框。而Notification是显示在屏幕上方状态栏中的信息。还有就是Notification需要用NotificationManager来管理,而Toast只需要简单地创建Toast对象即可。
? Android提供了ContentProvider,一个程序可以通过实现一个Content provider的抽象接口
将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。
· 要想使应用程序的数据公开化,可通过2种方法:
创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。
? 如何通过一套标准及统一的接口获取其他应用程序暴露的数据?
delete(Uri url, String where, String[] selectionArgs)Deletes row(s) specified by a content URI. query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)Query the given URI, returning a Cursor over the result set. update(Uri uri, ContentValues values, String where, String[] selectionArgs)Update row(s) in a content URI. 7
DeskClock分析文档
· Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问
ContentProvider提供的数据。
闹铃
? 闹铃功能
在系统中闹铃服务功能不仅仅对闹钟应用程序服务,最重要的是可以利用该闹铃服务功能提供的唤醒能力来做定时器。这样即便应用程序没有运行或者是没有启动的情况下,只要其注册过闹铃,那么该闹铃到时间后,系统可以自动将该应用程序启动,这就是所谓的闹铃“唤醒“功能。
AlarmManager将应用与服务分割开来后,使得应用程序开发者不用关心具体的服务,而是直接通过AlarmManager来使用这种服务。AlarmManager与AlarmManagerServie之间是通过Binder来通信的,他们之间是多对一的关系。
· void cancel(PendingIntent operation)
// 取消已经注册的与参数匹配的闹铃
void set(int type, long triggerAtTime, PendingIntent operation) //注册一个新的闹铃
void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)
//注册一个重复类型的闹铃
void setTimeZone(String timeZone) //设置时区
· 5种闹铃类型:
public static final int ELAPSED_REALTIME
//当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是3 (0x00000003)。
public static final int ELAPSED_REALTIME_WAKEUP
//能唤醒系统,用法同ELAPSED_REALTIME,系统值是2 (0x00000002) 。
public static final int RTC
//当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是绝对时间,所用时间是UTC时间,可以通过调用 System.currentTimeMillis()获得。系统值是1 (0x00000001) 。
public static final int RTC_WAKEUP
//能唤醒系统,用法同RTC类型,系统值为 0 (0x00000000) 。
Public static final int POWER_OFF_WAKEUP
8
DeskClock分析文档
//能唤醒系统,它是一种关机闹铃,就是说设备在关机状态下也可以唤醒系统,所以我们把它称之为关机闹铃。使用方法同RTC类型,系统值为4(0x00000004)。
? AlarmKlaxon通过继承Service,来实现功能,他在后台运行。
? 闹铃模式:Vibrator(震动)VIBRATOR_SERVICE,TelephonyManager(响铃)
TELEPHONY_SERVICE private void play(Alarm alarm) {
// stop() checks to see if we are already playing. stop();
if (Log.LOGV) {
Log.v(\ }
if (!alarm.silent) {Log.e(\ Uri alert = alarm.alert;
// Fall back on the default alarm if the database does not have an // alarm stored.
if (alert == null) {Log.e(\ alert = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_ALARM); if (Log.LOGV) {Log.e(\
Log.v(\ } }
// TODO: Reuse mMediaPlayer instead of creating a new one and/or use // RingtoneManager.
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener(new OnErrorListener() { public boolean onError(MediaPlayer mp, int what, int extra) { Log.e(\ mp.stop(); mp.release(); mMediaPlayer = null; Log.e(\ return true; } });
try {
// Check if we are in a call. If we are, use the in-call alarm // resource at a low volume to not disrupt the call.
9
DeskClock分析文档
if (mTelephonyManager.getCallState()
!= TelephonyManager.CALL_STATE_IDLE) {Log.e(\ Log.v(\
mMediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME); setDataSourceFromResource(getResources(), mMediaPlayer, R.raw.in_call_alarm); } else {Log.e(\
mMediaPlayer.setDataSource(this, alert); }
startAlarm(mMediaPlayer); } catch (Exception ex) {
Log.v(\
// The alert may be on the sd card which could be busy right // now. Use the fallback ringtone. try {
// Must reset the media player to clear the error state. mMediaPlayer.reset();
setDataSourceFromResource(getResources(), mMediaPlayer, R.raw.fallbackring); startAlarm(mMediaPlayer); } catch (Exception ex2) {
// At this point we just don't play anything. Log.e(\ } } }
/* Start the vibrator after everything is ok with the media player */ if (alarm.vibrate) {Log.e(\ mVibrator.vibrate(sVibratePattern, 0); } else {Log.e(\ mVibrator.cancel(); }
enableKiller(alarm); mPlaying = true;
mStartTime = System.currentTimeMillis();
}
? AlarmClock继承Activity实现OnItemClickListener接口
· AlarmClock是一个Activity类,主要功能是将闹钟界面显示出来,并通过各种组件控件,
实现人机交互功能,其中包括listView,adapter,menu,cursor等组件。
· 这里定义一个AlarmTimeAdapter继承CursorAdapter,用来显示闹钟列表的适配器。这里
10