Android : การใช้ AlarmManager เตือนการทานยา
|สวัสดีผู้อ่านนะครับ บทความนี้ผมมาอธิบายการทำแอพพลิเคชั่นเตือนการทานยาแบบง่ายๆ เขียนแบบค่อนข้างรีบซะด้วย ตัวอย่างในวันนี้ผมมีโค้ดให้ดาวน์โหลดนะครับ และ อธิบายเพิ่มเติมในส่วนที่สำคัญเช่น TimePickerDialog , AlarmManage , BroadcastReceiver รวมถึง PowerManager และ KeyguardManager เอาหละไปดูโครงสร้างคร่าวๆกันก่อน
โครงสร้างตัวอย่าง
โครงสร้างหลักของตัวอย่างนี้มี 3 ไฟล์คือ
– MainActivity ทำหน้าที่ตั้งเวลาทานยาโดย TimePickerDialog (ใช้เลือกเวลา) , บอกให้นาฬิกาเตือนเวลาเท่าไหร่ และ แสดงเวลาเตือนใน listview (สามารถเพิ่มเวลาเตือนได้หลายอัน)
– AlarmReceiver ทำหน้าที่รับการเตือนข้อนาฬิกา และเรียก Showevent ให้แสดง
– ShowEvent ทำหน้าที่ในการแสดงไดอะล๊อกเตือนพร้อมเสียง
รูปที่ 1 ภาพขั้นตอนการทำงานข้อแอพพลิเคชั่น
โค้ดตัวอย่าง
สามารถ ดาวน์โหลดโปรเจ็คตัวอย่างได้ที่ -> AlarmTest
** โดยตัวอย่างนี้ผมได้นำโค้ดของ android4health มาแก้ไขและอธิบายเพิ่มเติมครับโดยผู้เขียนคือคุณ tehnn
อธิบายโค้ดตัวอย่าง
MainActivity.java
ส่วนประกอบที่สำคัญคือส่วนแรกคือ TimePickerDialog คือไดอะล็อกที่สามารถเลือกเวลาได้ ในตัวอย่างนี้ให้เลือกเป็นชั่วโมงและนาที โดยคลาสนี้ (class TimePicker Fragment เป็นคลาสข้างในของ MainActivity อีกทีครับ) มี 2 ฟังก์ชั่นหลักดังนี้
– onCreateDialog ทำการสร้าง TimePickerDialog โดยตั้งค่าชั่วโมงและนาทีเป็นเวลาปัจจุบัน
– onTimeSet ทำเมื่อเราทำการตั่งค่าเวลาเรียบร้อย คือ กดปุ่ม ok
class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {
int callCount = 0;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
return new TimePickerDialog(getActivity(), this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
if(callCount==0){
// Do something with the time chosen by the user
}
callCount++;
}
}
อีกส่วนหนึ่งที่เป็นส่วนสำคัญคือการตั้งค่าเวลาที่จะทำการแจ้งเตือนในฟังก์ชั่น setAlarm โดยวิธีการในขั้นตอนนี้คือเราจะตั้งเวลาให้กับ AlarmManage และ AlarmManage จะเรียกใช้ pendingIntent (ในบรรทัดที่ 6) เพื่อบอกให้แอพพลิแคชั่นของเราให้รู้ว่าถึงเวลารัน AlarmReceiver แล้วนะ
1: private void setAlarm(Calendar targetCal){
2: final int _id = (int) System.currentTimeMillis();
3: Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
4: PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), _id, intent, 0);
5: AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
6: alarmManager.set(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(), pendingIntent);
7: }
AlarmReceiver.java
คลาสนี้มีหน้าที่ในการรอรับ Broadcast (ในที่นี้คือการเตือนของนาฬิกาครับ) เมื่อคลาสนี้ทำงานจะไปทำงานในฟังก์ชั่น onReceive โดยจะไปทำการเรียกใช้คลาส ShowEvent เพื่อเรียกไดอะล๊อกนั้นเอง
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent arg1) {
Intent i = new Intent(context, ShowEvent.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
ShowEvent.java
คลาส ShowEvent จะถูกเปิดแสดงขึ้นมาในเวลาที่กำหนดโดย AlarmReceiver ส่วนสำคัญส่วนแรกคือ การตั้งค่าให้คลาสนี้สามารถแสดงขึ้นมาได้ขณะที่อุปกรณ์อยู่ในขณะพักจอ และ ทำให้แอพพลิเคชั่นแสดงผลขึ้นมาโดยไม่ต้องใส่คีย์ที่ล๊อกเครื่องครับ สามารถดูรายละเอียดของคลาสที่นำมาใช้เพิ่มเติมได้ที่ PowerManager , KeyGuardManager และ KeyguardLock
PowerManager pm;
WakeLock wl;
KeyguardManager km;
KeyguardLock kl;
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
km=(KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
kl=km.newKeyguardLock("ShowEvent");
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.ON_AFTER_RELEASE, "ShowEvent");
wl.acquire(); //wake up the screen
kl.disableKeyguard();
ส่วนสำคัญที่สองคือฟังก์ชั่น onResume จะทำการเรียกเสียงเตือนโดยจะทำการตั้งค่าจากเสียงริงโทนของเราก่อน หากไม่มีรินโทนก็จะใช้เสียงนาฬิกาปลุก และ นอทิฟิเคชั่น ในลำดับถัดไป (เปลี่ยนได้ตามใจนะครับ)
Uri notif = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
if(notif==null){
notif = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if(notif==null){
notif = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
}
r = RingtoneManager.getRingtone(getApplicationContext(), notif);
r.play();
ลายละเอียดอีกนิดหน่อยของคลาส Showevent คือเราจะทำการตั้งค่าใน AndroidManifest.xml ให้คลาสนี้ซึ้งเป็น Activity แสดงเป็นรูปแบบไดอะล๊อก โดยเพิ่มโค้ดข้างล่างนี้เข้าไปใน AndroidManifest.xml ตรงส่วนของ acitivty Showevent
android:theme="@android:style/Theme.Dialog"
การขอ permission ที่จำเป็น
ในไฟล์ AndroidManifest.xml เราจะต้องทำการขอ permission ไว้ 2 อย่างคือ WAKE_LOCK และ DISABLE_KEYGUARD โดยการขอใช้ให้นำโค้ดข้างล่างไปเพิ่มใน AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
รายละเอียดของ permission เพิ่มเติมนะครับ
WAKE_LOCK คือ ขอใช้สิทธิในการใช้ WakeLock ในตัวอย่างนี้เราจะทำให้อุปกรณ์ของเราเปิด (ปลุกให้มันตื่นจาก sleep นั้นเอง)
DISABLE_KEYGUARD คือ ขอให้เมื่อรันแอพพลิเคชั่นนี้ขึ้นมาไม่ต้องป้อนรหัสปลดล๊อค
เอาหละครับอธิบายมายาวพอสมควรซึ้งผมก็คิดว่าครอบคลุมส่วนที่สำคัญทั้งหมดแล้วครับ ไว้พบกันในบทความต่อไป (บทความ Login Facebook)
ผลลัพธ์ตัวอย่าง