notification の利用

目標は,notification を利用して,ステータスバーにアプリを「実行中(OnGoing)」として表示させること。

ステータスバーを伸ばして(拡張して)当該アプリをタップすると,新たなタスクが起動される。この現象はアクティビティのライフサイクルから説明できる。
アクティビティを起動すると,その状態が onCreate → onStart → onResume と進む。この時点でアクティビティはユーザからの入力を待っている。ここでステータスバーの通知をタップすると,onPause → onCreate → onStart → onResume → onStop と状態が遷移し,新たなタスクが生成される。。

一方,Manifest ファイルの activity に android:launchMode="singleTask" を付与すると,ステータスバーの通知をタップした際に onPause → onResume と状態が遷移する。即ち,onCreate へ遷移しない。

<activity android:name=".AndroidNotificationActivity"
                  android:label="@string/app_name"
                  android:launchMode="singleTask">

Manifest ファイル

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jp.android"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroidNotificationActivity"
                  android:label="@string/app_name"
                  android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

ソースファイル

package jp.android;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class AndroidNotificationActivity extends Activity {
  private NotificationManager mManager;
  private static final int NOTIFICATION_ID = 1234;
	
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        
    //Notification service を・・・・
    mManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

    setContentView(R.layout.main);
        
    //開始ボタン
    Button bStart = (Button)findViewById(R.id.startButton);
    bStart.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        //ノーティフィケーションの設定
        //ノーティフィケーションを使用するにはNotificationManagerクラスのnotifyメソッドに
        //Notificationクラスのインスタンスを渡して呼び出す。
        //その引数には,ノーティフィケーションを識別するidとノーティフィケーションのインスタンスを渡す。
        mManager.notify(AndroidNotificationActivity.NOTIFICATION_ID,	//ノーティフィケーションを区別する ID
        generateNotification());	//ノーティフィケーションのインスタンス
      }
    });

    //終了ボタン
    Button bFinish = (Button)findViewById(R.id.finishButton);
    bFinish.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        //ノーティフィケーションの削除
        mManager.cancel(AndroidNotificationActivity.NOTIFICATION_ID);
        finish();
      }
    });

    Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show();
  }
    
  //ノーティフィケーションの生成
  private Notification generateNotification(){
    Notification notification = new Notification();
    notification.icon = R.drawable.icon; //アイコン
    notification.tickerText = "AndroidNotification"; // ステータスバーに表示されるティッカー文字列
    notification.when = System.currentTimeMillis();
    notification.number = 0;
    	
    //「通知」ではなく,「実行中 (OnGoing)」として通知する。
    //これによって「通知を消去」ボタンから notification を消去できなくなる。。
    notification.flags = Notification.FLAG_ONGOING_EVENT;

    //インテントの設定
    Intent i = new Intent(
                getApplicationContext(),
                AndroidNotificationActivity.class);
    PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, i, 0);
    	
    //notification において通知する内容をセットする。
    //notification が表示された状態でNotificationをクリックすると,
    //そのプログラムの指定したIntent (pendingIntent)へ遷移する。 
    notification.setLatestEventInfo(
                         getApplicationContext(),
                         "AndroidNotification", //notification のタイトル
                         "測定中です",
                         pi);
    	
    return notification;
  }

  @Override
  public void onStart(){
    super.onStart();
    Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onResume(){
    super.onResume();
    Toast.makeText(this, "onResume", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onPause(){
    super.onPause();
    Toast.makeText(this, "onPause", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onRestart(){
    super.onRestart();
    Toast.makeText(this, "onRestart", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onStop(){
    super.onStop();
    Toast.makeText(this, "onStop", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onDestroy(){
    super.onDestroy();
    Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
  }
}