【网学网提醒】:网学会员为您提供android闹钟参考,解决您在android闹钟学习中工作中的难题,参考学习。
ADROID2.1架构解析——闹钟架构解析——闹钟——
1设置定时时间文件:packages/apps/alarmclock/src/com/android/alarmclock/Alarms.javaprivatestaticvoidenableAlert(Contextcontext,finalAlarmalarm,finallongatTimeInMillis){AlarmManageram=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);...am.set(AlarmManager.RTC_WAKEUP,atTimeInMillis,sender);...}由闹钟管理器设置定时时间。2闹钟管理器2.1定时设置文件:frameworks/base/core/java/android/app/AlarmManager.javapublicstaticfinalintRTC_WAKEUP=0;publicstaticfinalintRTC=1;publicstaticfinalintELAPSED_REALTIME_WAKEUP=2;publicstaticfinalintELAPSED_REALTIME=3;AlarmManager(IAlarmManagerservice){mService=service;}publicvoidset(inttype,longtriggerAtTime,PendingIntentoperation){try{mService.set(type,triggerAtTime,operation);}catch(RemoteExceptionex){}}将type,triggerAtTime,operation等参数转向闹钟管理器服务。3闹钟管理器服务文件:frameworks/base/services/java/com/android/server/AlarmManagerService.java3.1定时设置publicAlarmManagerService(Contextcontext){mDescriptor=init();...}publicvoidset(inttype,longtriggerAtTime,PendingIntentoperation){setRepeating(type,triggerAtTime,0,operation);}publicvoidsetRepeating(inttype,longtriggerAtTime,longinterval,PendingIntentoperation){
if(operation==null){Log.w(TAG,"set/setRepeatingignoredbecausethereisnointent");return;}synchronized(mLock){Alarmalarm=newAlarm();alarm.type=type;alarm.when=triggerAtTime;alarm.repeatInterval=interval;alarm.operation=operation;//Removethisalarmifalreadyscheduled.removeLocked(operation);if(localLOGV)Log.v(TAG,"set:"+alarm);intindex=addAlarmLocked(alarm);if(index==0){setLocked(alarm);}}}privatevoidsetLocked(Alarmalarm){if(mDescriptor!=-1){set(mDescriptor,alarm.type,(alarm.when*1000*1000));}else{Messagemsg=Message.obtain();msg.what=ALARM_EVENT;mHandler.removeMessages(ALARM_EVENT);mHandler.sendMessageAtTime(msg,alarm.when);}}Init,set为底层操作函数,set(mDescriptor,alarm.type,(alarm.when*1000*1000));由底层来完成定时设置。3.2等待计时结束privateclassAlarmThreadextendsThread{publicvoidrun(){...
while(true){intresult=waitForAlarm(mDescriptor);...if((result&;RTC_WAKEUP_MASK)!=0)triggerAlarmsLocked(mRtcWakeupAlarms,triggerList,nowRTC);if((result&;RTC_MASK)!=0)triggerAlarmsLocked(mRtcAlarms,triggerList,nowRTC);if((result&;ELAPSED_REALTIME_WAKEUP_MASK)!=0)triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms,triggerList,nowELAPSED);if((result&;ELAPSED_REALTIME_MASK)!=0)triggerAlarmsLocked(mElapsedRealtimeAlarms,triggerList,nowELAPSED);...}}}在服务里采用线程来处理计时结束返回的信息,根据等待计时结束返回的信息触发不同的操作。4硬
件调用(JNI机制)硬件调用(机制)文件:frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp4.1定时设置staticjintandroid_server_AlarmManagerService_init(JNIEnv*env,jobjectobj){#ifHAVE_ANDROID_OSreturnopen("/dev/alarm",O_RDWR);#elsereturn-1;#endif}staticvoidandroid_server_AlarmManagerService_close(JNIEnv*env,jobjectobj,jintfd){#ifHAVE_ANDROID_OSclose(fd);#endif}staticvoidandroid_server_AlarmManagerService_set(JNIEnv*env,jobjectobj,jintfd,jinttype,jlongnanoseconds){#ifHAVE_ANDROID_OS
structtimespects;ts.tv_sec=NANOSECONDS_TO_SECONDS(nanoseconds);ts.tv_nsec=nanoseconds-SECONDS_TO_NANOSECONDS(ts.tv_sec);intresult=ioctl(fd,ANDROID_ALARM_SET(type),&;ts);if(result<0){LOGE("Unabletosetalarmto%lld:%s\n",nanoseconds,strerror(errno));}#endif}以上函数的绑定如下:{"init","()I",(void*)android_server_AlarmManagerService_init},{"close","(I)V",(void*)android_server_AlarmManagerService_close},{"set","(IIJ)V",(void*)android_server_AlarmManagerService_set},由上可知,通过ioctl接口,设置定时时间。4.2等待计时结束staticjintandroid_server_AlarmManagerService_waitForAlarm(JNIEnv*env,jobjectobj,jintfd){#ifHAVE_ANDROID_OSintresult=0;do{result=ioctl(fd,ANDROID_ALARM_WAIT);}while(result<0&;&;errno==EINTR);if(result<0){LOGE("Unabletowaitonalarm:%s\n",strerror(errno));return0;}returnresult;#endif}以上函数的绑定如下:{"waitForAlarm","(I)I",(void*)android_server_AlarmManagerService_waitForAlarm},由上可知,代码阻塞方式等待计时结束或由意外中断结束。4杂项4.1闹钟类型publicstaticfinalintELAPSED_REALTIME//当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该
闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是3(0x00000003)。publicstaticfinalintELAPSED_REALTIME_WAKEUP//能唤醒系统,用法同ELAPSED_REALTIME,系统值是2(0x00000002)。publicstaticfinalintRTC//当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是绝对时间,所用时间是UTC时间,可以通过调用System.currentTimeMillis()获得。系统值是1(0x00000001)。publicstaticfinalintRTC_WAKEUP//能唤醒系统,用法同RTC类型,系统值为0(0x00000000)。PublicstaticfinalintPOWER_OFF_WAKEUP//能唤醒系统,它是一种关机闹铃,就是说设备在关机状态下也可以唤醒系统,所以我们把它称之为关机闹铃。使用方法同RTC类型,系统值为4(0x00000004)。4.2底层实现在IOCTL中ANDROID_ALARM_SET(0)设置闹钟;在IOCTL中ANDROID_ALARM_WAIT:等待闹钟时间,其中rv
=wait_event_interruptible(alarm_wait_queue,alarm_pending);会阻塞,在xxmins后alarm_timer_triggered函数中改变alarm_pending值为真,并唤醒等待队列。wake_up(&;alarm_wait_queue);在ANDROID_ALARM_WAIT的最后释放alarm_rtc_wake_lock。