こんな感じ。
private int localNotificationTag = 0;
private int cancelledLocalNotificationTag = 0;
private final String LOCAL_NOTIFICATION_TAG_PREFERENCE_KEY = "local_notification_tag";
private final String CANCELLED_LOCAL_NOTIFICATION_TAG_PREFERENCE_KEY = "cancelled_local_notification_tag";
// ローカル通知レシーブ用のクラス
// マニフェストにも記述のこと。また、必ずstaticをつけて宣言すること
public static class LocalNotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getIntExtra("notification_id", 0);
String message = intent.getStringExtra("message");
Intent intent2 = new Intent(context, Cocos2dxActivity.class);
intent2.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent2,
PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle(context.getString(R.string.app_name));
builder.setContentText(message);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setLargeIcon(largeIcon);
builder.setTicker(message);
builder.setAutoCancel(true);
builder.setDefaults(Notification.DEFAULT_ALL);
builder.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notificationId, builder.build());
}
}
// 指定秒後の時刻をミリ秒で返す
private long getTimeInMillisSinceNow(int secSinceNow) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, secSinceNow);
return calendar.getTimeInMillis();
}
// ローカル通知用のPendingIntentを作成する
private PendingIntent makeLocalNotificationPendingIntent(String message, int tag) {
Intent intent = new Intent(getApplicationContext(), LocalNotificationReceiver.class);
intent.putExtra("notification_id", tag);
intent.putExtra("message", message);
PendingIntent sender = PendingIntent.getBroadcast(this, tag, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return sender;
}
// ローカル通知用のPendingIntentを返す(データは入れない)
private PendingIntent getLocalNotificationPendingIntent(int tag) {
Intent intent = new Intent(getApplicationContext(), LocalNotificationReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, tag, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return sender;
}
private static void InitLocalNotification() {
instance.localNotificationTag = LoadInt(instance.LOCAL_NOTIFICATION_TAG_PREFERENCE_KEY, 0);
instance.cancelledLocalNotificationTag = LoadInt(instance.CANCELLED_LOCAL_NOTIFICATION_TAG_PREFERENCE_KEY, 0);
}
// 指定秒後に指定の文字列でローカル通知を行う
public static void Native_scheduleLocalNotification(int secSinceNow, String text) {
PendingIntent sender = instance.makeLocalNotificationPendingIntent(text, ++instance.localNotificationTag);
long time = instance.getTimeInMillisSinceNow(secSinceNow);
AlarmManager am = (AlarmManager) instance.getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, time, sender);
SaveInt(instance.LOCAL_NOTIFICATION_TAG_PREFERENCE_KEY, instance.localNotificationTag);
}
// 登録されているローカル通知をすべて削除する
public static void Native_unscheduleAllLocalNotifications() {
AlarmManager am = (AlarmManager) instance.getSystemService(ALARM_SERVICE);
for (int tag = instance.cancelledLocalNotificationTag + 1; tag <= instance.localNotificationTag; ++tag) {
PendingIntent sender = instance.getLocalNotificationPendingIntent(tag);
am.cancel(sender);
}
instance.cancelledLocalNotificationTag = instance.localNotificationTag;
SaveInt(instance.CANCELLED_LOCAL_NOTIFICATION_TAG_PREFERENCE_KEY, instance.cancelledLocalNotificationTag);
}
AndroidManifest.xmlには
<receiver
android:name="***.***.MainActivity$LocalNotificationReceiver"
android:process=":remote" />
と記述のこと。
◯内部クラスを使う場合の注意
・内部クラスはstaticをつけて定義する
Javaでは、内部クラスは基本的にstaticをつけて宣言することが推奨。
staticにしていないと、「no empty constructor」という実行時エラーになる。
なぜなら、staticでない内部クラスは、それを包含するクラスからしかインスタンス化できないからだ。
ちなみに、staticでない内部クラスは、自身を包含するクラスへの参照を暗黙的に持つ。アクセスできて便利だが、当然gcを阻害することになる
・AndroidManifest.xmlでは、内部クラスは $ で繋ぐ。
これもJava的な決まり事。
PR