CommonsWareのランチリストの例を使用して、アラームを設定およびリセットしています。
特定の時間にアラームを設定し、それが定期的なアラームの場合は、アラームを新しい日付/時刻にリセットしようとします。
OnAlarmReceiverでは、アプリケーションのコンテキスト(アクティビティ)で最初にアラームを設定するときに、元の3行のコードを使用しようとします。3行は次のとおりです。
ComponentName component=new ComponentName(context, OnBootReceiver.class);
context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
OnBootReceiver.setAlarm(context, itemId, mDateDue);
ただし、これは機能していないようです。私が試したのは、この行を追加することでした。
OnBootReceiver.cancelAlarm(context, itemId);
しかし、それも違いはありませんでした。私はこれがどのように結びついているのかを適切に理解していませんが、次のいずれかを疑っています:
- 私の文脈は間違っています。
- 私も放送をキャンセルするなど、放送で何かをしなければなりません。
- おそらく、変更する必要のあるフラグがありますか?
繰り返し発生するアラームが発生するたびに、コードによってリセットされるという考え方です。繰り返しアラームを使用できることはわかっていますが、アプリケーションのこの段階では、手動でこれを行うことを好みます。
OnAlarmReceiverは次のとおりです。
public class OnAlarmReceiver extends BroadcastReceiver {
private static final int NOTIFY_ME_ID=1337;
private static final String TAG = "OnAlarmReceiver";
private DbAdapter mDbHelper;
private String mDateDue;
private String mFrequency;
@Override
public void onReceive(Context context, Intent intent) {
mDbHelper = new DbAdapter(context);
mDbHelper.open();
AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
Bundle bundle = intent.getExtras();
long itemId = bundle.getLong("itemId");
Cursor c = mDbHelper.getItem(itemId);
String itemTitle = c.getString(c.getColumnIndex(Db.KEY_ITEMS_TITLE));
int priority = c.getInt(c.getColumnIndex(Db.KEY_ITEMS_PRIORITY));
long listId = c.getLong(c.getColumnIndex(Db.KEY_ITEMS_LIST_ID));
String listTitle = mDbHelper.getListTitle(listId);
mDateDue = c.getString(c.getColumnIndex(Db.KEY_ITEMS_DATE_DUE));
mFrequency = c.getString(c.getColumnIndex(Db.KEY_ITEMS_FREQUENCY));
Toast.makeText(context, "Due: " + listTitle + "->" + itemTitle, Toast.LENGTH_LONG).show();
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(context);
boolean useNotification=prefs.getBoolean("use_notification", true);
// Check if the alarm must be reset to a new future date based on frequency
checkResetAlarm(context, itemId);
if (useNotification) {
NotificationManager mgr = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification();
if (priority == 1) { // Display red icon
notification=new Notification(R.drawable.nuvola_apps_kwrite, itemTitle, System.currentTimeMillis());
} else { // Display blue icon
notification=new Notification(R.drawable.nuvola_apps_package_editors, itemTitle, System.currentTimeMillis());
}
Intent itemEditor = new Intent(context, ActivityEditItem.class);
long lAlarmId = (long) (int) itemId;
itemEditor.putExtra(DbAdapter.KEY_ITEMS_ITEM_ID, lAlarmId);
itemEditor.putExtra("listId", listId);
itemEditor.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// For flags, also see http://developer.android.com/guide/topics/ui/actionbar.html#ActionView
PendingIntent i=PendingIntent.getActivity(context, 0, itemEditor, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, listTitle, itemTitle, i);
String notifyPreference = prefs.getString("notification_sound", "DEFAULT_RINGTONE_URI");
notification.sound = Uri.parse(notifyPreference);
int oldVolume = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
if (priority == 1) {
Log.d(TAG, "A high priority item is due");
//notification.defaults |= Notification.DEFAULT_VIBRATE;
Vibrator v;
v=(Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(3000);
int streamVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION);
audioManager.setStreamVolume(AudioManager.STREAM_NOTIFICATION, streamVolume, 0);
}
mgr.notify((int) (long) itemId + NOTIFY_ME_ID, notification);
audioManager.setStreamVolume(AudioManager.STREAM_NOTIFICATION, oldVolume, 0);
}
else {
Intent i=new Intent(context, AlarmActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
private void checkResetAlarm(Context context, long itemId) {
if (!mFrequency.equals("")) {
String newDateDue = Item.addMinutesToDate(mDateDue, mFrequency);
Log.d(TAG, "Due date " + mDateDue + " reset with frequency of " + mFrequency + ", new due date: " + newDateDue);
mDbHelper.updateItemDueDate(itemId, newDateDue);
Toast.makeText(context, "Resetting alarm...", Toast.LENGTH_LONG).show();
ComponentName component=new ComponentName(context, OnBootReceiver.class);
context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
OnBootReceiver.cancelAlarm(context, itemId);
OnBootReceiver.setAlarm(context, itemId, mDateDue);
}
}
}
OnBootReceiverは次のとおりです。
public class OnBootReceiver extends BroadcastReceiver {
public static void setAlarm(Context context, long itemId, String dateDue) {
AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar cal=Calendar.getInstance();
String[] pieces=dateDue.split("/");
String day_of_month = dateDue.substring(8,10);
String hour = dateDue.substring(11,13);
String minute = dateDue.substring(14,16);
String second = dateDue.substring(17,19);
cal.set(Calendar.YEAR, Integer.parseInt(pieces[0]));
cal.set(Calendar.MONTH, Integer.parseInt(pieces[1])-1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day_of_month));
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour));
cal.set(Calendar.MINUTE, Integer.parseInt(minute));
cal.set(Calendar.SECOND, Integer.parseInt(second));
cal.set(Calendar.MILLISECOND, 0);
if (cal.getTimeInMillis()<System.currentTimeMillis()) {
cal.add(Calendar.DAY_OF_YEAR, 1);
}
mgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
getPendingIntent(context, itemId));
}
/**
* Cancel Alarm
*
* @param ctxt
* @param itemId
*/
public static void cancelAlarm(Context ctxt, long itemId) {
AlarmManager mgr=(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
mgr.cancel(getPendingIntent(ctxt, itemId));
}
private static PendingIntent getPendingIntent(Context ctxt, long itemId) {
//Intent i = new Intent(OnAlarmReceiver.ACTION, Uri.parse("timer:"+alarmId));
Intent i=new Intent(ctxt, OnAlarmReceiver.class);
i.putExtra("itemId", itemId);
return(PendingIntent.getBroadcast(ctxt, (int) (long) itemId, i, 0));
}
// When the phone restarts all alarms must be reset by this method
@Override
public void onReceive(Context ctxt, Intent intent) {
// To be added
//setAlarm(ctxt);
}
}