现在工作的原因,又要重新学习android。就打算写个应用。恰好最近不想起床,创意就来了,写个闹钟,一旦开始唱歌,不唱完休想停下来。

我学这个东西的时候还是2.2,现在都4.3了,变了很多。还真有点不适应。所以花了一个晚上才搞定。

首先新建工程。不多说了。

然后写一个页面。很简单,就一个Button,一个TimePicker。



android studio闹钟功能 android studio 闹钟案例_移动开发



    1. <LinearLayout xmlns:android="http:///apk/res/android"
    2. android:orientation="vertical"
    3. android:layout_width="fill_parent"
    4. android:layout_height="fill_parent"
    5. android:gravity="center_vertical"
    6. >
    7. <TimePicker
    8. android:id="@+id/timePicker"
    9. android:layout_width="fill_parent"
    10. android:layout_height="wrap_content"
    11. />
    12. <Button
    13. android:id="@+id/timeBtn"
    14. android:layout_width="fill_parent"
    15. android:layout_height="wrap_content"
    16. android:text="@string/done"
    17. android:textSize="20sp"
    18. android:onClick="setAlarm"
    19. />
    20. </LinearLayout>


     

    就像这样,线性布局,TimePicker在上,Button在下。我们要实现的就是上边选一个时间,然后点一下button,这个闹钟就在你设定的时间响起来,想停都停不了。

    然后再onCreate里,把布局搞上去。

     

     

     



    android studio闹钟功能 android studio 闹钟案例_移动开发


    1. @Override
    2. rotected void
    3. super.onCreate(savedInstanceState);  
    4. setContentView(R.layout.activity_main);  
    5. timePicker = (TimePicker)findViewById(.timePicker);  
    6. time = (Button)findViewById(.timeBtn);  
    7. timePicker.setIs24HourView(true);

         



     然后注册Button事件



    android studio闹钟功能 android studio 闹钟案例_移动开发



      1. public void
      2. int
      3. int
      4.      Calendar cal = Calendar.getInstance();  
      5.      cal.set(Calendar.HOUR_OF_DAY, hour);  
      6.      cal.set(Calendar.MINUTE, minu);  
      7. if(cal.before(Calendar.getInstance())){  
      8. 1);  
      9.      }  
      10. this, cal.getTime().toString(), Toast.LENGTH_LONG).show();  
      11.      alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);  
      12. new Intent(this, AlarmReceiver.class);  
      13. this, 0, intent, 0);  
      14.      alarmMgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmIntent);  
      15. /*alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
      16.                 AlarmManager.INTERVAL_DAY, alarmIntent);*/
      17.  }



       

      首先从TimePicker中取到小时和分钟,分别是hour 和minu。

      创建一个Calendar对象,然后把Calendar中的hour和minu替换成我们设置的时间,然后对现在的时间比较一下,如果在现在时间之后,就设置为calendar中储存的时间,如果是在之前,就把calendar中的时间加一天。

      然后是闹钟比较重要的几个类。首先得到AlarmManager这个系统服务。然后创建一个PendingIntent,AlarmManager通过set方法设置唤醒方式,时间和到时候抛出的intent。



      android studio闹钟功能 android studio 闹钟案例_移动开发



        1. 01.alarmMgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmIntent);



         

        RTC_WAKEUP代表绝对时间方式,切手机处于休眠状态时也会fire,第二个参数得到要fire的绝对时间,就是我们刚刚设置的时间,第三个参数是到时候抛出的intent。

        代码跑到这里,intent应该能抛出来了,还得设计一个BroadcastRecevier来接这个Intent。认真看代码的应该已经看到了,这个intent已经写明白了,将被传递给AlarmReceiver.class,就是它。下面是代码:



        android studio闹钟功能 android studio 闹钟案例_移动开发


        1. @Override
        2. public void
        3. // TODO Auto-generated method stub
        4. "REC", "The time is up,start the alarm...");  
        5. "This the time", Toast.LENGTH_LONG).show();  
        6. new Intent(context, MusicService.class);            
        7.                 context.startService(serviceIntent);   
        8.     }


         

        如果细心应该发现我在上一个代码段中有一行注释



        android studio闹钟功能 android studio 闹钟案例_移动开发


        1. /*alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
        2.                 AlarmManager.INTERVAL_DAY, alarmIntent);*/

         

        这是官方的推荐方法。所以首先是用的这个,但是不知道为什么总是不成功。所以我还是得好好研究下。

        回到原来话题,认真看下上边代码发现他够简单,只是打开了一个service。恩,播放音乐就放在这个service里边。



        android studio闹钟功能 android studio 闹钟案例_移动开发


        1. public class MusicService extends Service implements
        2.   
        3. //为日志工具设置标签
        4. private static String TAG = "MusicService";  
        5. //定义音乐播放器变量
        6. private
        7.       
        8. @Override
        9. public void
        10. // TODO Auto-generated method stub
        11. "MusicSerice onCreate()");  
        12.         mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.smoke);  
        13.         mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);  
        14. super.onCreate();  
        15.     }  
        16.   
        17. @Override
        18. public int onStartCommand(Intent intent, int flags, int
        19. // TODO Auto-generated method stub
        20. "MusicSerice onStart()");  
        21.         mPlayer.start();  
        22. return super.onStartCommand(intent, flags, startId);  
        23.     }  
        24.   
        25. @Override
        26. public void
        27. // TODO Auto-generated method stub
        28. "MusicSerice onDestroy()");  
        29.         mPlayer.stop();  
        30. super.onDestroy();  
        31.     }  
        32.   
        33. public void
        34. // TODO Auto-generated method stub
        35.         stopSelf();  
        36.     }  
        37.   
        38. }


         

        onCreate的时候创建MediaPlayer对象。onStartCommand时开始播放。onCompletion在播放完毕时调用,于是在这里stop这个service。很简单。

        这么快,功能都实现了。

        在设置里看到service并没有自己停掉,这个有点奇怪,需要重新研究下。

         

        大意了。。忘记了给MediaPlayer注册Listener导致的onCompletion方法没有被调用,所以歌曲播放完毕后service并没有被停掉。修改后的service代码如下



        android studio闹钟功能 android studio 闹钟案例_移动开发


        1. @Override
        2. public void
        3. // TODO Auto-generated method stub
        4. "MusicSerice onCreate()");  
        5.     mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.smoke);  
        6.     mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);  
        7. "COLOR: #ff0000">mPlayer.setOnCompletionListener(this);  
        8. </SPAN>   super.onCreate();  
        9. }



         

        大功告成。核心功能都实现了,就剩下交互设计和UI了。慢慢丰满吧。

         

        PS:我是直接把音乐资源功能打包在apk里的,所以闹铃是不能换的,而我打包了一首Smoke on the water,每天早上都要被嘈杂的电吉他身影弄醒,痛苦不堪。

        所以最后的结果是,我用了两天,早起了两天后,把这个应用卸载了。。。。。