当前位置: 首页 > news >正文

android 关于闹钟

以下是我发现的几点闹钟中重要的点,分享一下:

(1)在闹钟中有AudioManager管理机制,这个机制可以申请和释放OnAudioFocusChangeListener监听。

还有mTelephonyManager对象,处理在闹钟响的时候,来电铃声的切换。

(2)广播接收闹钟,通过广播启动AlarmKlaxon这个Service,隐式启动service:

public static final String ALARM_INTENT_EXTRA = "intent.extra.alarm";

[java] view plain copy print ?
  1. //Playthealarmalertandvibratethedevice.
  2. IntentplayAlarm=newIntent(Alarms.ALARM_ALERT_ACTION);
  3. playAlarm.putExtra(Alarms.ALARM_INTENT_EXTRA,alarm);
  4. context.startService(playAlarm);

在mainfest中,AlarmKlaxon这个服务的定义如下:

[java] view plain copy print ?
  1. <serviceandroid:name="AlarmKlaxon"
  2. android:description="@string/alarm_klaxon_service_desc"
  3. >
  4. <intent-filter>
  5. <actionandroid:name="com.cn.daming.deskclock.ALARM_ALERT"/>
  6. </intent-filter>
  7. </service>

这个service做的是允许别的Activity打断正在响铃的铃声,播放其他的铃声,例如,闹钟响的时候来电话了。

(3)在listview中包含checkbox,这时候闹钟的处理时,activity实现一个OnItemClickListener的监听,点击每一项的监听。然后在checkbox单独拿出去写一个类,继承LinearLayout,重写setPressed()这个方法,以实现“当点击checkbox的时候不触发parent的click事件”。关键代码如下:

[java] view plain copy print ?
  1. <spanstyle="font-size:18px;">@Override
  2. publicvoidsetPressed(booleanpressed){
  3. //Iftheparentispressed,donotsettopressed.
  4. if(pressed&&((View)getParent()).isPressed()){
  5. return;
  6. }
  7. super.setPressed(pressed);
  8. }</span>


点击新建闹钟出现的界面 设置好时间弹出的toast。

下面我把我的主要入口类的代码贴出来

DeskClockMainActivity.java

[java] view plain copy print ?
  1. <spanstyle="font-size:18px;">packagecom.cn.daming.deskclock;
  2. importjava.util.Calendar;
  3. importandroid.app.Activity;
  4. importandroid.app.AlertDialog;
  5. importandroid.content.Context;
  6. importandroid.content.DialogInterface;
  7. importandroid.content.Intent;
  8. importandroid.content.SharedPreferences;
  9. importandroid.database.Cursor;
  10. importandroid.graphics.Typeface;
  11. importandroid.os.Bundle;
  12. importandroid.view.LayoutInflater;
  13. importandroid.view.Menu;
  14. importandroid.view.MenuItem;
  15. importandroid.view.View;
  16. importandroid.view.ContextMenu;
  17. importandroid.view.ContextMenu.ContextMenuInfo;
  18. importandroid.view.View.OnClickListener;
  19. importandroid.view.ViewGroup;
  20. importandroid.widget.AdapterView;
  21. importandroid.widget.AdapterView.AdapterContextMenuInfo;
  22. importandroid.widget.AdapterView.OnItemClickListener;
  23. importandroid.widget.CheckBox;
  24. importandroid.widget.CursorAdapter;
  25. importandroid.widget.ImageButton;
  26. importandroid.widget.ImageView;
  27. importandroid.widget.ListView;
  28. importandroid.widget.TextView;
  29. publicclassDeskClockMainActivityextendsActivityimplementsOnItemClickListener{
  30. staticfinalStringPREFERENCES="AlarmClock";
  31. /**Thismustbefalseforproduction.Iftrue,turnsonlogging,
  32. testcode,etc.*/
  33. staticfinalbooleanDEBUG=false;
  34. privateSharedPreferencesmPrefs;
  35. privateLayoutInflatermFactory;
  36. privateListViewmAlarmsList;
  37. privateCursormCursor;
  38. @Override
  39. publicvoidonCreate(BundlesavedInstanceState){
  40. super.onCreate(savedInstanceState);
  41. //取自定义布局的LayoutInflater
  42. mFactory=LayoutInflater.from(this);
  43. //取getSharedPreferences中key==“AlarmClock”的值
  44. mPrefs=getSharedPreferences(PREFERENCES,0);
  45. //获取闹钟的cursor
  46. mCursor=Alarms.getAlarmsCursor(getContentResolver());
  47. //更新布局界面
  48. updateLayout();
  49. }
  50. //加载更新界面布局
  51. privatevoidupdateLayout(){
  52. setContentView(R.layout.alarm_clock);
  53. mAlarmsList=(ListView)findViewById(R.id.alarms_list);
  54. AlarmTimeAdapteradapter=newAlarmTimeAdapter(this,mCursor);
  55. mAlarmsList.setAdapter(adapter);
  56. mAlarmsList.setVerticalScrollBarEnabled(true);
  57. mAlarmsList.setOnItemClickListener(this);
  58. mAlarmsList.setOnCreateContextMenuListener(this);
  59. ViewaddAlarm=findViewById(R.id.add_alarm);
  60. addAlarm.setOnClickListener(newView.OnClickListener(){
  61. publicvoidonClick(Viewv){
  62. addNewAlarm();
  63. }
  64. });
  65. //Maketheentireviewselectedwhenfocused.
  66. addAlarm.setOnFocusChangeListener(newView.OnFocusChangeListener(){
  67. publicvoidonFocusChange(Viewv,booleanhasFocus){
  68. v.setSelected(hasFocus);
  69. }
  70. });
  71. ImageButtondeskClock=
  72. (ImageButton)findViewById(R.id.desk_clock_button);
  73. deskClock.setOnClickListener(newView.OnClickListener(){
  74. publicvoidonClick(Viewv){
  75. }
  76. });
  77. }
  78. privatevoidaddNewAlarm(){
  79. startActivity(newIntent(this,SetAlarm.class));
  80. }
  81. /**
  82. *listview的适配器继承CursorAdapter
  83. *@authorwangxianming
  84. *也可以使用BaseAdapter
  85. */
  86. privateclassAlarmTimeAdapterextendsCursorAdapter{
  87. publicAlarmTimeAdapter(Contextcontext,Cursorcursor){
  88. super(context,cursor);
  89. }
  90. publicViewnewView(Contextcontext,Cursorcursor,ViewGroupparent){
  91. Viewret=mFactory.inflate(R.layout.alarm_time,parent,false);
  92. DigitalClockdigitalClock=
  93. (DigitalClock)ret.findViewById(R.id.digitalClock);
  94. digitalClock.setLive(false);
  95. returnret;
  96. }
  97. //把view绑定cursor的每一项
  98. publicvoidbindView(Viewview,Contextcontext,Cursorcursor){
  99. finalAlarmalarm=newAlarm(cursor);
  100. Viewindicator=view.findViewById(R.id.indicator);
  101. //Settheinitialresourceforthebarimage.
  102. finalImageViewbarOnOff=
  103. (ImageView)indicator.findViewById(R.id.bar_onoff);
  104. barOnOff.setImageResource(alarm.enabled?
  105. R.drawable.ic_indicator_on:R.drawable.ic_indicator_off);
  106. //Settheinitialstateoftheclock"checkbox"
  107. finalCheckBoxclockOnOff=
  108. (CheckBox)indicator.findViewById(R.id.clock_onoff);
  109. clockOnOff.setChecked(alarm.enabled);
  110. //Clickingoutsidethe"checkbox"shouldalsochangethestate.
  111. //对checkbox设置监听,使里外一致
  112. indicator.setOnClickListener(newOnClickListener(){
  113. publicvoidonClick(Viewv){
  114. clockOnOff.toggle();
  115. updateIndicatorAndAlarm(clockOnOff.isChecked(),
  116. barOnOff,alarm);
  117. }
  118. });
  119. DigitalClockdigitalClock=
  120. (DigitalClock)view.findViewById(R.id.digitalClock);
  121. //setthealarmtext
  122. finalCalendarc=Calendar.getInstance();
  123. c.set(Calendar.HOUR_OF_DAY,alarm.hour);
  124. c.set(Calendar.MINUTE,alarm.minutes);
  125. digitalClock.updateTime(c);
  126. digitalClock.setTypeface(Typeface.DEFAULT);
  127. //Settherepeattextorleaveitblankifitdoesnotrepeat.
  128. TextViewdaysOfWeekView=
  129. (TextView)digitalClock.findViewById(R.id.daysOfWeek);
  130. finalStringdaysOfWeekStr=
  131. alarm.daysOfWeek.toString(DeskClockMainActivity.this,false);
  132. if(daysOfWeekStr!=null&&daysOfWeekStr.length()!=0){
  133. daysOfWeekView.setText(daysOfWeekStr);
  134. daysOfWeekView.setVisibility(View.VISIBLE);
  135. }else{
  136. daysOfWeekView.setVisibility(View.GONE);
  137. }
  138. //Displaythelabel
  139. TextViewlabelView=
  140. (TextView)view.findViewById(R.id.label);
  141. if(alarm.label!=null&&alarm.label.length()!=0){
  142. labelView.setText(alarm.label);
  143. labelView.setVisibility(View.VISIBLE);
  144. }else{
  145. labelView.setVisibility(View.GONE);
  146. }
  147. }
  148. };
  149. //更新checkbox
  150. privatevoidupdateIndicatorAndAlarm(booleanenabled,ImageViewbar,
  151. Alarmalarm){
  152. bar.setImageResource(enabled?R.drawable.ic_indicator_on
  153. :R.drawable.ic_indicator_off);
  154. Alarms.enableAlarm(this,alarm.id,enabled);
  155. if(enabled){
  156. SetAlarm.popAlarmSetToast(this,alarm.hour,alarm.minutes,
  157. alarm.daysOfWeek);
  158. }
  159. }
  160. /*
  161. *(non-Javadoc)
  162. *@seeandroid.app.Activity#onContextItemSelected(android.view.MenuItem)
  163. *创建上下文菜单
  164. */
  165. @Override
  166. publicbooleanonContextItemSelected(finalMenuItemitem){
  167. finalAdapterContextMenuInfoinfo=
  168. (AdapterContextMenuInfo)item.getMenuInfo();
  169. finalintid=(int)info.id;
  170. //Errorcheckjustincase.
  171. if(id==-1){
  172. returnsuper.onContextItemSelected(item);
  173. }
  174. switch(item.getItemId()){
  175. caseR.id.delete_alarm:
  176. //Confirmthatthealarmwillbedeleted.
  177. newAlertDialog.Builder(this)
  178. .setTitle(getString(R.string.delete_alarm))
  179. .setMessage(getString(R.string.delete_alarm_confirm))
  180. .setPositiveButton(android.R.string.ok,
  181. newDialogInterface.OnClickListener(){
  182. publicvoidonClick(DialogInterfaced,
  183. intw){
  184. Alarms.deleteAlarm(DeskClockMainActivity.this,id);
  185. }
  186. })
  187. .setNegativeButton(android.R.string.cancel,null)
  188. .show();
  189. returntrue;
  190. caseR.id.enable_alarm:
  191. finalCursorc=(Cursor)mAlarmsList.getAdapter()
  192. .getItem(info.position);
  193. finalAlarmalarm=newAlarm(c);
  194. Alarms.enableAlarm(this,alarm.id,!alarm.enabled);
  195. if(!alarm.enabled){
  196. SetAlarm.popAlarmSetToast(this,alarm.hour,alarm.minutes,
  197. alarm.daysOfWeek);
  198. }
  199. returntrue;
  200. caseR.id.edit_alarm:
  201. Intentintent=newIntent(this,SetAlarm.class);
  202. intent.putExtra(Alarms.ALARM_ID,id);
  203. startActivity(intent);
  204. returntrue;
  205. default:
  206. break;
  207. }
  208. returnsuper.onContextItemSelected(item);
  209. }
  210. /*
  211. *(non-Javadoc)
  212. *@seeandroid.app.Activity#onCreateContextMenu(android.view.ContextMenu,android.view.View,android.view.ContextMenu.ContextMenuInfo)
  213. *创建菜单
  214. */
  215. @Override
  216. publicvoidonCreateContextMenu(ContextMenumenu,Viewview,
  217. ContextMenuInfomenuInfo){
  218. //Inflatethemenufromxml.
  219. getMenuInflater().inflate(R.menu.context_menu,menu);
  220. //Usethecurrentitemtocreateacustomviewfortheheader.
  221. finalAdapterContextMenuInfoinfo=(AdapterContextMenuInfo)menuInfo;
  222. finalCursorc=
  223. (Cursor)mAlarmsList.getAdapter().getItem((int)info.position);
  224. finalAlarmalarm=newAlarm(c);
  225. //ConstructtheCalendartocomputethetime.
  226. finalCalendarcal=Calendar.getInstance();
  227. cal.set(Calendar.HOUR_OF_DAY,alarm.hour);
  228. cal.set(Calendar.MINUTE,alarm.minutes);
  229. finalStringtime=Alarms.formatTime(this,cal);
  230. //InflatethecustomviewandseteachTextView'stext.
  231. finalViewv=mFactory.inflate(R.layout.context_menu_header,null);
  232. TextViewtextView=(TextView)v.findViewById(R.id.header_time);
  233. textView.setText(time);
  234. textView=(TextView)v.findViewById(R.id.header_label);
  235. textView.setText(alarm.label);
  236. //Setthecustomviewonthemenu.
  237. menu.setHeaderView(v);
  238. //Changethetextbasedonthestateofthealarm.
  239. if(alarm.enabled){
  240. menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm);
  241. }
  242. }
  243. /*
  244. *(non-Javadoc)
  245. *@seeandroid.app.Activity#onOptionsItemSelected(android.view.MenuItem)
  246. *设置菜单的点击事件的处理
  247. */
  248. @Override
  249. publicbooleanonOptionsItemSelected(MenuItemitem){
  250. switch(item.getItemId()){
  251. caseR.id.menu_item_settings:
  252. startActivity(newIntent(this,SettingsActivity.class));
  253. returntrue;
  254. caseR.id.menu_item_desk_clock:
  255. //modifybywangxianmingin2012-4-14
  256. //startActivity(newIntent(this,DeskClock.class));
  257. returntrue;
  258. caseR.id.menu_item_add_alarm:
  259. addNewAlarm();
  260. returntrue;
  261. default:
  262. break;
  263. }
  264. returnsuper.onOptionsItemSelected(item);
  265. }
  266. /*
  267. *(non-Javadoc)
  268. *@seeandroid.app.Activity#onCreateOptionsMenu(android.view.Menu)
  269. *创建菜单
  270. */
  271. @Override
  272. publicbooleanonCreateOptionsMenu(Menumenu){
  273. getMenuInflater().inflate(R.menu.alarm_list_menu,menu);
  274. returnsuper.onCreateOptionsMenu(menu);
  275. }
  276. /*
  277. *(non-Javadoc)
  278. *@seeandroid.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView,android.view.View,int,long)
  279. *创建菜单的点击事件响应
  280. */
  281. publicvoidonItemClick(AdapterView<?>adapterView,Viewv,intpos,longid){
  282. Intentintent=newIntent(this,SetAlarm.class);
  283. intent.putExtra(Alarms.ALARM_ID,(int)id);
  284. startActivity(intent);
  285. }
  286. @Override
  287. protectedvoidonDestroy(){
  288. super.onDestroy();
  289. ToastMaster.cancelToast();
  290. mCursor.close();
  291. }
  292. }</span>

也可以到我的csdn资源中下载:http://download.csdn.net/detail/wdaming1986/4226174

转载:http://blog.csdn.net/wdaming1986/article/details/7461043

相关文章:

  • CSS中首字母大写怎么实现?
  • android环境下解决java.io.IOException: Malformed ipv6异常的方法
  • Scatter“秒传”的速度秒杀了云存储
  • 腾讯移动游戏平台发布了《天天酷跑》游戏
  • 黑马程序员_String练习
  • android下基本json串的生成与解析
  • FileZilla无法连接ftp服务器的解决方案
  • nginx编译安装报错src/os/unix/ngx_files.c: In function 鈔gx_write_chain_to_file?
  • WiFi基本知识
  • nginx配置DocumentRoot
  • 黑马程序员_StringBuffer,包装类
  • 【Android病毒分析报告】 - ZooTiger “集恶意推广、隐私窃取、恶意吸费于一体”...
  • windows下如何用wireshark抓本地回路抓包
  • 知道版本对于出0day后批量攻击dedecms有非常大的帮助,先判断版本再选择相应exp,效率大增...
  • 如何让Windows Server 2008服务器支持被动模式
  • 【Amaple教程】5. 插件
  • 【mysql】环境安装、服务启动、密码设置
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Git同步原始仓库到Fork仓库中
  • Hibernate【inverse和cascade属性】知识要点
  • JavaScript创建对象的四种方式
  • leetcode388. Longest Absolute File Path
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • tab.js分享及浏览器兼容性问题汇总
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 对象管理器(defineProperty)学习笔记
  • 番外篇1:在Windows环境下安装JDK
  • 基于 Babel 的 npm 包最小化设置
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 每天一个设计模式之命令模式
  • 如何编写一个可升级的智能合约
  • 使用 Docker 部署 Spring Boot项目
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 用element的upload组件实现多图片上传和压缩
  • 用jQuery怎么做到前后端分离
  • 运行时添加log4j2的appender
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ![CDATA[ ]] 是什么东东
  • $jQuery 重写Alert样式方法
  • (03)光刻——半导体电路的绘制
  • (2)STL算法之元素计数
  • (6)STL算法之转换
  • (编译到47%失败)to be deleted
  • (分布式缓存)Redis哨兵
  • (一)VirtualBox安装增强功能
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)memcache、redis缓存
  • (转)nsfocus-绿盟科技笔试题目
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .NET 材料检测系统崩溃分析
  • .Net(C#)自定义WinForm控件之小结篇
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证