我們利用AlarmManager實作一個鬧鐘,
讓他在開機後1分鐘後,發出鈴響。
只要利用PendingIntent及AlarmManager就可以做到這樣的功能。
1. MainActivity.java
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, PlayReceiver.class);
intent.putExtra("msg", "play_voice");
intent.addCategory(String.valueOf(SystemClock.elapsedRealtime()));
//SystemClock.elapsedRealtime()會回傳從開機到現在當下所花的時間,手機進入睡眠時間也算在內(單位milliseconds)
long elapsed = SystemClock.elapsedRealtime() + 60 * 1000; //60秒
// 發送一個broadcast,類似 Context.sendBroadcast()
// PendingIntent.FLAG_UPDATE_CURRENT參數表示,如果已存在 PendingIntent,就更新 extra data.
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsed , pi);
}
});
}
}
那Intent,和PendingIntent有什麼不同呢?
一般的Intent,用startActivity(intent)就會直接去啟動和intent。
PendingIntent可以想成延遲Intent,它則是先把某個Intent包好,丟給某個程式,等到一段時間後再去執行Intent。
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsed , pi);
等到第二個參數(elapsed)所設定的時間到達時,就會執行pi這個PendingIntent
這裡有一點要注意,當 AlarmManager 執行 set() 時,Android 系統會比對已註冊的其他 Intent 的 action、data、type、class、category,
如果這幾個屬性完全相同,則系統會將這兩個 Intent 視為一樣,
這時系統會視 PendingIntent.FLAG_xxx 參數以決定如何處理這個新註冊的 Intent
。
2.接下來建立接收廣播的class:
PlayReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
public class PlayReceiver extends BroadcastReceiver {
private SoundPool sp;
private int sourceid;
@Override
public void onReceive(Context context, Intent intent) {
Bundle bData = intent.getExtras();
if (bData.get("msg").equals("play_voice")) {
sp = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
sourceid = sp.load(context, R.raw.harm, 1);
playSounds(1, context);
}
}
public void playSounds(int repeatTime, Context context) {
AudioManager am = (AudioManager) context.getApplicationContext()
.getSystemService(Context.AUDIO_SERVICE);
// 獲取最大音量
float audMaxVolumn = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
// 獲取目前音量
float audCurrentVolumn = am.getStreamVolume(AudioManager.STREAM_MUSIC);
// 左右聲道值範圍為 0.0 - 1.0
float volRatio = audCurrentVolumn / audMaxVolumn;
// 下面參數分別為播放音頻,左聲道,右聲道,設置優先級,重撥次數,速率(速率最低0.5,最高為2,1代表正常速度)
sp.play(sourceid, volRatio, volRatio, 1, repeatTime, 1);
}
}
播放音效的作法,請參考
先前的文章
3. 在Layout裡加入一個按鈕, 來啟動鬧鐘
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="54dp"
android:text="1分鍾後,鬧鍾啟動" />
</RelativeLayout>
4. 最後在AndroidManifest.xml 的 application 區段寫入要接收廣播的程式:
<receiver android:name="com.example.s.PlayReceiver" >
<intent-filter>
<action android:name="play_voice" />
</intent-filter>
</receiver>
reference
http://oldgrayduck.blogspot.tw/2012/10/androidalarmmanager.html