T

Titanium MobileでLocal Notificationを実装する

iOSにはリモートからメッセージなどを通知するPush Notificationとインストール済みアプリから通知するLocal Notificationという二つの機構があります。以前、Push Notificationのサンプルはgistに公開したことがあるので、今回はLocal Notificationについて書いてみます。

Local Notificationが出来るのは

・ポップアップまたはステータスバーへの通知
・通知の際のサウンドの再生
・バッヂの操作(アプリのアイコンの数字のことね)

です。通知が発生した際にステータスバーまたはポップアップのOKをタッチしてアプリケーションを起動することができます。端末がスリープ状態のときはロック解除のところが下のalertActionで指定する文字になります。通知がユーザに無視された、またはユーザがキャンセルボタンをクリックした場合は何も起きません。また設定で通知をオフにした場合は何も表示されません。

*アプリを企画する方はここに注意してください。アプリを通知から必ず起動する方法はありません(やったらリジェクトされます)。

それから、通知を予約したアプリがフォアグランドで実行中には通知は実行されません。ただし、通知が発生していたことはアプリに通知されます。後ほど詳しくみていきます。

サウンドの再生ですが、どうやらシステムに組み込まれたサウンドを鳴らす方法はありません。サウンドデータを自前で用意することになります。対応しているフォーマットはcaf、aiff、mp3まで動作確認できました。wavとかもいけるかもしれませんが試していません。

サウンドの再生は、仕様では30秒までとなっていますが、29秒でないと動作しませんでした。またボリュームはプログラム側から制御することができません。端末でミュートしていたら音は出ません(じゃなきゃ困ります)。

繰り返しは毎日(daily)、毎週(weekly)、毎月(monthly)、毎年(yearly)から選択できます。何も指定しなければ一回だけ実行されます。繰り返しの場合は開始日時に過去の日付を指定すると次回からの実行になりますが、繰り返しがない場合は即時実行になってしまいますのでプログラム作成時に注意しましょう。

以上を踏まえて、作りたいアプリがLocal Notificationを使うのに相応しいかどうかを判断しましょう。

さて、実装です。Local Notificationではアプリいつ、どんなことをするかをiOS側のAPIに予約して、OKボタンの押下などの結果を受け取ります。Resources/app.jsにこんな内容を追記しましょう。

Ti.App.iOS.cancelAllLocalNotifications();
var notifications = [];
notification_params = {
      alertBody: 'こんにちは、こんにちは',
      alertAction: 'OK',
      userInfo: {
        data: {param1:'これはparam1', param2:'これはparam2'}
      },
      sound: 'sound.mp3',
      repeat: 'daily',
      date: new Date((new Date()).getTime() +(1000 * 10))
    };
notifications.push(Ti.App.iOS.scheduleLocalNotification(notification_params));

まずcancelAllLocalNotificationsを実行して過去にこのアプリから登録したLocal Notificationを全てキャンセルにします。必要のないアプリであればここで実行する必要はありませんが、個別に通知を選んでキャンセルすることができないので、こうして一気にやってしまいます。

notificationsという配列を使っていますが、後で利用することはありません。が、アプリの終了後にすぐに消えてしまうと困るのでこうしていちいち宣言しています。

これでdateパラメータで指定された時刻(この場合は10秒後)に通知が実行されます。急いでアプリを閉じて待ちましょう。

実行されましたか?

あ、いまはまだこの記事を読んでいるだけで、実際に手を動かしてはいないんですね。わかりました。でも折角だからやってみましょう。今日は雨だし付き合いますよ。

実行されましたか?

よかったですね。ではもっと細かいところを見てみましょう。Local Notificationの予約はボタンを押せば実行されるようにしますか?でも、ボタンを押した瞬間にアプリを強制的に終了した場合はどうなるんでしょうか。変なタイミングで電話がかかってきてしまったら?Ti.App.iOS.scheduleLocalNotificationはvoid型で戻り値がないので、なんだか落ち着かない感じがしませんか?そうなんです、通常はLocal Notificationの予約はバックグランドで実行するのがベストプラクティスらしいので、ちょっと変更しましょう。値の受け渡しのデモもやります。

app.jsはこんな感じ:

Ti.App.Properties.setString('message', 'こんにちは、こんにちは!');
Ti.App.Properties.setString('when','2012/04/23 00:15:00');
var service = Ti.App.iOS.registerBackgroundService({url:'service.js'});

service.jsをバックグランドで実行するようになっています。Resources以下に設置するservice.jsはこちら:

if(Ti.App.Properties.hasProperty('when')){
	Ti.App.iOS.cancelAllLocalNotifications();
	var notifications = [];
	notification_params = {
	      alertBody: Ti.App.Properties.getString('message'),
	      alertAction: 'OK',
	      userInfo: {
	        alertMessage:'ピンポンパンポン!'
	      },
	      sound: 'sound.mp3',
	      repeat: 'daily',
	      date: new Date(Ti.App.Properties.getString('when'))
	    };
	notifications.push(Ti.App.iOS.scheduleLocalNotification(notification_params));
}
Ti.App.currentService.stop();

アプリがフォアグランドにある場合はLocal Notificationは実行されないといいましたが、実行するはずの時間になるとその旨だけがアプリに通知されます。これはnotificationというイベントとして捕まえることができます。userInfoを使って値の受け渡しまで実行できます。

Ti.App.iOS.addEventListener('notification', function(e) {
  var dialog = Ti.UI.createAlertDialog({
  	title:'お知らせ',
  	message:e.userInfo.alertMessage,
  	buttonNames:['OK', 'お黙り'],
  	cancel:1
  	});
  dialog.show();
});

こんなもんでしょうかね。Local Notificationのパラメータにはいくつか面白いものもあるのでぜひマニュアルをご覧ください。

Posted by on 4月 22, 2012 in Apple, mobile, Titanium

コメントを残す