續(xù)接上一篇文章
1.叫醒功能實(shí)現(xiàn)
-
叫醒對話框
這個(gè)對話框是不是很丑啊?這個(gè)對話框之所以丑的原因是因?yàn)槲覒衺
鬧鐘對話框.png
分析一下這個(gè)對話框的特點(diǎn),就是三點(diǎn)
- a.要根據(jù)用戶選擇的賴床指數(shù)顯示不同難度的題目
- b.要將用戶輸入的結(jié)果跟正確答案進(jìn)行對比
- c.不允許退出(這樣才能達(dá)到暴力叫醒),返回鍵也無效
a
在dialog上的代碼就是setMessage(),在AlarmReceiverzhong 根據(jù)LazyLevel生成兩個(gè)隨機(jī)數(shù)
private int youCantSleep() {
Random a=new Random();
if(lazylevel==1){
A = a.nextInt(20)+5;
B = a.nextInt(20)+5;
}else if(lazylevel==2){
A = a.nextInt(99)+1;
B = a.nextInt(99)+1;
while(B<50) B+=10;
}else if(lazylevel==3){
A = a.nextInt(200)+1;
B = a.nextInt(200)+1;
while (B<80) B+=10;
while(A<80) A+=10;
}else if(lazylevel==4){
A = a.nextInt(500)+1;
B = a.nextInt(500)+1;
while(B<80) B+=10;
while(A<200) A+=30;
}
return A*B;
}
b
這個(gè)比較簡單,positiveButton的監(jiān)聽中if判斷一下正確答案和輸入答案,正確的話就dialog.dismiss();
c
-首先Alertdialog.Builder有一個(gè)方法setCancelable(false);傳入false將不可以點(diǎn)擊取消,點(diǎn)擊Home鍵都不可以被取消,只能通過確定。當(dāng)然殺進(jìn)程是可以的~
builder.setCancelable(false);
-然后將dialog設(shè)置成為系統(tǒng)級(jí)別
AlertDialog dialog=builder.create();
WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
這里需要一個(gè)權(quán)限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- 播放鬧鐘鈴聲
啟動(dòng)一個(gè)Service來播放音樂,播放的音樂由AlarmReceiver通過Intent傳遞過去- 啟動(dòng)AlarmService
Intent service=new Intent(context, AlarmRingService.class);
service.putExtra("resid", resid);
context.startService(service);
- AlarmService在onStartCommand中獲取到數(shù)據(jù)
//拿到用戶選擇的那個(gè)鈴聲
Song=intent.getStringExtra("resid");
if (Song==null){
// 為了程序的健壯性,判斷一下,以免出現(xiàn)不必要的異常
Song="everybody.mp3";
}
ringTheAlarm(Song);
- 播放音樂(MediaManager)
核心代碼
mPlayer=new MediaPlayer();
assetFileDescriptor = this.getAssets().openFd(song);
mPlayer.reset();
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
重點(diǎn)
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
注意 該方法必須在prepare()之前調(diào)用,否則無效!
該方法將這個(gè)MediaPlayer設(shè)置成為某一個(gè)特定的媒體類型,這里設(shè)置成為STREAM_ALARM,這樣可以實(shí)現(xiàn)調(diào)節(jié)鬧鐘音量不會(huì)影響其他音量,避免用戶設(shè)置為手機(jī)靜音后鬧鐘失效。
- 開啟震動(dòng)
private void startVibrate() {
mVibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
if(mVibrator.hasVibrator()){
mVibrator.vibrate(new long[]{500, 1500, 500, 1500}, 0);//off on off on repeatmode
}
}
- 停止服務(wù)
當(dāng)用戶關(guān)閉鬧鐘時(shí)停止服務(wù),因此關(guān)閉音樂和關(guān)閉震動(dòng)的代碼寫在onDestroy中
@Overridepublic
void onDestroy() {
super.onDestroy();
stopTheAlarm();
stopVibrate();
}
結(jié)尾
簡單記錄了下開發(fā)的思路,以及一些小的,但是容易漏掉的知識(shí)點(diǎn),調(diào)試的時(shí)候會(huì)很讓人抓狂的。下一篇文章分析FragmentWeather中實(shí)現(xiàn)的邏輯
