通知領域に文字を表示する

今回作成したサンプルプログラムです。
http://dl.dropbox.com/u/8518065/android/notificationSample1/SampleAndroid.apk
画像は、notifyボタンを押した直後の状態

で、下記がソース。

まずは、main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <EditText
        android:id="@+id/title"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="sample_title"
        />
    <EditText
        android:id="@+id/message"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="sample_message"
        />
    <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="notify" 
        />
</LinearLayout>

次に、メインとなるアクティビティクラス。

package hm.orz.chaos114.android.sample;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class SampleAndroidActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        init();
    }

    private void init() {
        // タイトル入力領域を取得
        final EditText titleTextView = (EditText) findViewById(R.id.title);
        // メッセージ入力領域を取得
        final EditText messageTextView = (EditText) findViewById(R.id.message);

        // 通知ボタンを取得
        Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CharSequence title = titleTextView.getText();
                CharSequence message = messageTextView.getText();
                NotificationUtil.notify(SampleAndroidActivity.this, title,
                        message);
            }
        });
    }
}

あと、そこから呼ばれているユーティリティクラス。

package hm.orz.chaos114.android.sample;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

public class NotificationUtil {

    public static void notify(Context context, CharSequence title,
            CharSequence message) {

        // 通知をタップされたときのintentを作成
        Intent newIntent = new Intent(context, SampleAndroidActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                newIntent, 0);
        
        // Notificationオブジェクトの作成
        Notification notification = new Notification(R.drawable.icon, title,
                System.currentTimeMillis());
        notification.setLatestEventInfo(context, title, message, contentIntent);
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        
        // Managerオブジェクトの取得
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        
        // このアプリの通知を一旦削除し、再通知
        notificationManager.cancelAll();
        notificationManager.notify(0, notification);
    }
}


あと、補足事項。

  • NotificationManager#notifyの第一引数が、今回固定値となっています。

アプリケーション内で同一のidが指定された場合、cancelAllをしてやらないと、再通知されませんでした。
複数の通知を表示したいは、表示した最後の番号をSharedPreferencesとかに入れといて、それにインクリメントして表示するとか?
さらに、あとでcancel(通知を削除)したい場合、通知内容とidを保存しないといけないかな?(あまり、そんな場面が思いつきませんが。)

  • 通知をクリックした際のintent

今回、SampleAndroidActivityを起動しています。
この場合、SampleAndroidActivityを起動したまま通知をタップすると、2枚同じアクティビティが起動してしまいます。(=戻るを押下しても、もう1個のSampleAndroidActivityが表示される)
これを解消する場合、newIntentを生成後に下記のように設定。

newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

ただし、複数のアクティビティが定義されていたりした場合、意図しない動きをするかもしれません。

  • PendingIntent

通知がタップされた際に発行するIntentを保持するIntentのようです。
あまりよくわかっていません。