-
Notifications
You must be signed in to change notification settings - Fork 355
2.04. メッセージングと通知
GitHub Pagesへ移行しましたmixi-inc.github.ioへお願いします。
wikiの方はしばらくしたら消していきます
この章では、アプリ内や、アプリ外との遣り取りをする仕組みであるメッセージングについて解説します。
参考:Context | Android Developers
参考:Intent | Android Developers
参考:Intents and Intent Filters | Android Developers
参考:BroadcastReceiver | Android Developers
参考:LocalBroadcastManager | Android Developers
参考:Notifications | Android Developers
-
Intent
- [Intent オブジェクト](#Intent オブジェクト)
- [Intent Filter](#Intent Filter)
- [Intent を用いた、1 対 1 のメッセージング](#Intent を用いた、1 対 1 のメッセージング)
- [Activity を起動する Intent](#Activity を起動する Intent)
- [Activity を起動し、処理結果を期待するメッセージング](#Activity を起動し、処理結果を期待するメッセージング)
- [Service を起動する Intent](#Service を起動する Intent)
- [Intent を用いた、1 対 多 のメッセージング](#Intent を用いた、1 対 多 のメッセージング)
- BroadcastReceiver
- [BroadcastReceiver のライフサイクル](#BroadcastReceiver のライフサイクル)
- [Static BroadcastReceiver](#Static BroadcastReceiver)
- [Dynamic BroadcastReceiver](#Dynamic BroadcastReceiver)
- [Intent を Broadcast する](#Intent を Broadcast する)
- LocalBroadcastManager
- [Intent に付加情報を追加する](#Intent に付加情報を追加する)
- [Intent Extras](#Intent Extras)
-
Notification
- [Notification の役割](#Notification の役割)
- [Notification の仕組み](#Notification の仕組み)
- PendingIntent
- NotificationCompat.Builder
Android のメッセージングで、最も頻繁に使われるオブジェクトに Intent があります。
Intent は、メッセージングでやり取りするメッセージそのものを取り扱う Entity の役割を持っています。
実際に Intent をメッセージとして送る仕組みは、Context が持っており、
Intent を受け取ることが出来るのは、Activity、Service、BroadcastReceiver の 3 つのコンポーネントです。
Intent オブジェクトは、メッセージを送信する相手に実行してもらいたい処理を記述したデータです。
Intent オブジェクトには、以下に挙げる情報が含まれています。
- Action
-
どのようなアクション(処理)を実行してほしいか、を示します。
Activity に向けた Action と、Broadcast 用の Action の 2 種類があります。Activity に向けた Action の代表的なものを以下に示します。
- ACTION_VIEW
- ACTION_MAIN
- ACTION_SEND
- ACITON_SENDTO
- ACTION_EDIT
- ACTION_PICK
- ACTION_DELETE
- ACTION_INSERT
- ACTION_SEARCH
- ACTION_CALL
Broadcast 用の Action の代表的なものを以下に示します。
- ACTION_BOOT_COMPLETED
- ACTION_SHUTDOWN
- ACTION_PACKAGE_ADDED
- ACTION_PACKAGE_REPLACE
- ACTION_PACKAGE_REMOVED
- Category
-
Intent を処理するべき対象が、どのような属性を持っていることを期待しているかを示すものです。
- CATEGORY_DEFAULT
- CATEGORY_LAUNCHER
- CATEGORY_HOME
- CATEGORY_PREFERENCE
- CATEGORY_BROWSABLE
- Data
-
Action の対象となるデータを指し示す URI です。
例えば、ACTION_VIEW と対にして Data を渡すということは、対象のデータを表示するよう指示することを意味します。 - Type
- Data の種類を表す MIME タイプです。
- Component
-
Action を実行することを期待するコンポーネントです。
Intent を送りつける対象のコンポーネントとも読み替えることができます。この、Component を明示している(Intent を送る対象が明らかな)Intent のことを、明示的 Intent と呼んでいます。
一方、Component を明示していない(Action をハンドリング出来るもの全てを対象とする)Intent のことを、 暗黙的 Intent と呼びます。 - Extras
-
Intent を送りつける対象に渡す追加情報です。
Key と Value のペアを Bundle オブジェクトに詰めて渡します。 - Flag
- Activity の起動方法をシステムに通知するための情報です。
暗黙的 Intent を受け取るコンポーネントが、その Intent をハンドリング可能かどうかを宣言するための仕組みです。
Android フレームワークは、この Intent Filter の宣言を元にして、暗黙的 Intent の対象となるコンポーネントをリストアップします。
Action、 Data、 Categoryの 3 つの情報を基準に暗黙的 Intent がハンドリング可能なものを選択するように設計されているので、Intent Filter にもこの 3 つの情報について宣言をしておきます。
暗黙的 Intent がハンドリング可能かどうかの判定に、Flag や Extras は使われません。
AndroidManifest での IntentFilter の宣言の例を以下に示します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.mixi.sample"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="jp.mixi.sample.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<!-- アプリのメイン(入り口)となる Activity を起動するときの Action を受け取る -->
<!-- Intent クラスに定義されている ACTION_MAIN 定数の実態は "android.intent.action.MAIN" という文字列 -->
<action android:name="android.intent.action.MAIN" />
<!-- ランチャーからの起動のものを受け取る -->
<!-- Intent クラスに定義されている CATEGORY_LAUNCHER 定数の実態は "android.intent.category.LAUNCHER" という文字列 -->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="jp.mixi.sample.AnotherActivity"
android:label="@string/app_name" >
<!-- 画像を共有する Action のための Intent Filter 宣言 -->
<intent-filter>
<!-- ACTION_SEND または ACTION_SEND_MULTIPLE のいずれかを受け取る -->
<!-- Intent に設定可能な Action は 1 つだけなので、<intent-filter> に Action を複数宣言すると -->
<!-- その中からいずれかに該当するものを受け取る、という意味になる -->
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<!-- 暗黙的 Intent を扱う際に必須のカテゴリ -->
<!-- システムは、Activity の起動に暗黙的 Intent を発行すると、 -->
<!-- このカテゴリが付与されているものとして扱うため、Activity で暗黙的 Intent を受け取りたい場合は -->
<!-- 必ずこのカテゴリを <intent-filter> に宣言しておく -->
<!-- 複数のカテゴリを <intent-filter> に宣言した場合は、 -->
<!-- 全てのカテゴリにマッチするもののみを受け取る、という意味になる -->
<category android:name="android.intent.category.DEFAULT" />
<!-- Data の種類の制限 -->
<!-- MIME タイプのほか、URI のスキームを制限することもできる -->
<data android:mimeType="image/jpeg" />
</intent-filter>
</activity>
</application>
</manifest>
新しい Activity を呼び出すときに使用します。
public class MyActivity extends Activity {
@Overrride
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// メッセージのオブジェクトとして Intent を作る
// どの Context から、どのクラスに対してメッセージを送るかを指定する
Intent intent = new Intent(this, NextActivity.class);
// Intent を Context に渡して、メッセージを送る
// この場合、NextActivity クラスにメッセージが送られ、NextActivity が立ち上がる
startActivity(intent);
}
}
新しい Activity を呼び出し、その Activity から元の Activity へと Intent を戻すことで、何らかの処理の結果を呼び出し元に通知することができるものです。
// 呼び出し元の Activity
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 新しい Activit を呼び出す
// 戻りの Intent を期待する場合は、Activity#startActivityForResult(Intent, int) を使用する
startActivityForResult(new Intent(this, SubActivity.class), SubActivity.REQUEST_CODE_HOGE);
}
// 新しい Activity から戻ってくる Intent を受け取るコールバック
// 新しい Activity が全面に出る場合は、onRestart()の前、ダイアログのように一部を覆って表示される場合は、onResume()の前で呼ばれる
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(int, int, Intent) の呼び出しは、条件に関係なくすること
// Fragment から startActivityForResult(Intent, int) した場合の戻りの判定ができなくなってしまう
super.onActivityResult(requestCode, resultCode, data);
// requestCode には、startActivityForResult(Intent, int) の第 2 引数で指定したものが来る
// resultCode には、呼び出し先で setResult(int, Intent) をコールした時の第 1 引数が来る
// data には、呼び出し先で setResult(int, Intent) をコールした時の第 2 引数が来る
switch (requestCode) {
case SubActivity.REQEUST_CODE_HOGE:
// REQUEST_CODE_HOGE の戻りが来た時の処理
return;
default:
// 知らない requestCode の戻りが来た時の処理
return;
}
}
}
// 呼び出し先の Activity
public class SubActivity extends Activity {
public static final int REQUEST_CODE_HOGE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 何かする
// 呼び出し元に返す Intent オブジェクトをセットする
// 第 1 引数には、RESULT_OK または RESULT_CANCELLED、あるいは、RESULT_FIRST_USER を起点にした独自の int 型定数を使う
setResult(RESULT_OK, new Intent());
finish();
}
}
Service を呼び出します。Service そのものについては、別の章で解説します。
public class MyActivity extends Activity {
private ServiceConnection mServiceConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// サービスのバインド要求
bindService(new Intent(this, MyService.class), mServiceConnection, Context.BIND_AUTO_CREATE);
// サービスの開始要求
startService(new Intent(this, MyIntentService.class));
}
}
アプリ内、アプリ外問わず、Intent を全体へ投げかける仕組みのことを、ブロードキャストと言います。
Android のシステムでは、端末の状態を全アプリに通知するための仕組みとして利用しています。
ブロードキャストされる Intent を受信するためのコンポーネントです。
その宣言の仕方に依って、使われ方が異なることに注意します。
BroadcastReceiver には、ブロードキャストされた Intent を受け取るためのコールバックメソッドが用意されています。
public class MyBroadcastReceiver extends BroadcastReceiver {
// Broadcast された Intent を受け取るコールバック
@Override
public void onReceive(Context context, Intent intent) {
}
}
BroadcastReceiver のライフサイクルは、このonReceive(Context, Intent)
メソッドが実行されている間となります。
つまり、onReceive(Context, Intent)
メソッドの処理が終わると、BroadcastReceiver のライフサイクルが終わることになります。
また、BroadcastReceiver が動作しているプロセスは、最も優先順位の高いフォアグラウンドプロセスとして扱われます。
つまり、BroadcastReceiver のライフサイクルが終了したプロセスは、そのプロセスで動作している他のコンポーネントが持つ優先順位になります。
もし、BroadcastReceiver のみがプロセス上で動作していた場合、BroadcastReceiver のライフサイクルが終了すると、そのプロセスは空プロセスとして扱われ、システムが優先してプロセスを kill するようになります。
よって、この 2 つの特徴から、BroadcastReceiver の中で非同期処理(Service を除く)を実行することは良くない実装となります。
なぜなら、非同期処理が終了する以前に、プロセスが終了してしまう可能性があるからです。
代わりに、別の章で解説するService
の仕組みを利用します。
また、BroadcastReceiver の中で、ダイアログを表示することも推奨されません。
なぜなら、ダイアログのイベント処理を実行する前に、BroadcastReceiver のライフサイクルが終了してしまうからです。
代わりに、後述するNotification
の仕組みを利用します。
AndroidManifest に宣言される BroadcastReceiver です。
アプリがインストールされている間はずっと、BroadcastReceiver が動作し、ブロードキャストされる Intent の監視を続けます。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.mixi.sample;"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- ... -->
<receiver
android:name="jp.mixi.sample.MyBroadcastReceiver">
<intent-filter>
</intent-filter>
</receiver>
</application>
</manifest>
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
ただし、Honeycomb 以後の Android では、アプリのインストール直後は、アプリの状態が待機状態として扱われるようになったため、アプリを一度でも起動しないと、ブロードキャストされる Intent が受信できなくなります。
Activity などの Context で動的に登録/解除が行われる BroadcastReceiver です。
Context のライフサイクルの中で動的に登録をするので、解除もライフサイクルの中で実施する必要があります。
また、どのライフサイクルの Context で登録を行うかも重要です。
Activity の Context で動的に登録した場合、解除も Activity の Context の中で行うようにします(下記のサンプルコード参照)。
もし解除を行わなかった場合、システムが自動で登録を解除し、適切に解除を行う指示をエラーログに吐き出します。
Application の Context で動的に登録した場合、アプリケーションの中でグローバルなスコープで BroadcastReceiver が動作します。
つまり、解除を忘れても、システムは自動で登録を解除しません。ですので、解除を適切に行わないと、深刻なリークの原因となります。
public class MyActivity extends Activity {
private BroadcastReceiver mMyReceiver = new MyBroadcastReceiver();
@Override
protected void onStart() {
super.onStart();
// ACTION_PACKAGE_ADDED の Action を通す IntentFilter オブジェクトを作成
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
// MyBroadcastReceiver オブジェクトを、指定した IntentFilter オブジェクトで、Activity の Context に登録
registerReceiver(mMyReceiver, filter);
}
@Override
protected void onStop() {
// MyBroadcastReceiver オブジェクトの登録を、Activity の Context 上から解除する
// Activity のライフサイクルが終わりに向かうコールバックの中で実装する
unregisterReceiver(mMyReceiver);
super.onStop();
}
}
Context#sendBroadcast(Intent)
を利用して、ブロードキャストを送信します。
これによって、端末内で Intent に設定した Action が実行可能で、Category や Data を受け付けてくれる BroadcastReceiver すべてがこの Intent を受信するようになります。
public class MyActivity extends Activity {
// 自分で独自の Action を定義することも可能
public static final String ACTION_HOGEHOGE = "jp.mixi.sample.android.intent.action.HOGEHOGE";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// do something...
// Intent のブロードキャスト
Intent intent = new Intent();
intent.setAction(ACTION_HOGEHOGE);
sendBroadcast(intent);
}
}
特に、アプリ内全体へのブロードキャストを行う仕組みとして、LocalBroadcastManagerがあります。
これによって、他のアプリには知られたくない Broadcast が実現出来ます。
これとは別に、ブロードキャスト時にパーミッションを設定し、そのパーミッションを得ているアプリのみがブロードキャストを受信できるようにする方法もあります。この場合、パーミッションを持っていれば、他のアプリでもブロードキャストの受信が可能となります。
今回は、より軽量に利用可能な LocalBroadcastManager を使って解説します。
注:LocalBroadcastManager では、マルチプロセスをサポートしていないため、プロセスの異なるコンポーネントへのブロードキャストは上手く動作しない。
// LocalBroadcastManager は Support Package に含まれている
import android.support.v4.content.LocalBroadcastManager;
public class MainActivity extends Activity {
public static final String TAG = MainActivity.class.getSimpleName();
public static final String ACTION_HOGEHOGE = "jp.mixi.sample.android.intent.action.HOGEHOGE";
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "local broadcast received.");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
// この Activity の Context の中での、Local な Broadcast を管理する為の LocalBroadcastManager オブジェクト
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.registerReceiver(mReceiver, new IntentFilter(ACTION_HOGEHOGE));
}
@Override
protected void onStop() {
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.unregisterReceiver(mReceiver);
super.onStop();
}
// ボタンなどのクリックハンドラ
public void onHogeClick(View v) {
// Local な Broadcast として Intent を投げる
// 通常の sendBroadcast(Intent) メソッドと違い、この仕組で投げた Intent は他のアプリ(プロセス)では拾うことが出来ない
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.sendBroadcast(new Intent(ACTION_HOGEHOGE));
}
}
Intent
オブジェクトには、受け取り側への付加情報を付与するための仕組みも持っています。
いくつかのプリミティブ型と、文字列、コレクション、Parcelable オブジェクトを付加情報として付与することができます。
Parcelable オブジェクトについての詳細は別の章で解説しますが、オブジェクトの簡易的なシリアライズの仕組みとして利用します。
// Intent を送信する側の Activity
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// do something...
List<String> list = new ArrayList<String>();
list.add("fuga");
list.add("piyo");
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("StringExtraKey", "hogehoge"); // 文字列の場合
intent.putExtra("BooleanExtraKey", true); // boolean の場合
intent.putExtra("IntegerExtraKey", 10); // int の場合
intent.putStringArrayListExtra("StringArrayListExtraKey", list); // ArrayList<String> の場合
startActivity(intent);
}
}
// Intent を受け取る側の Activity
public class NewActivity extends Activity {
@Override
protected void onCreate(savedInstanceState) {
super.onCreate(savedInstanceState);
// do something...
// この Activity への Intent オブジェクトを取得する
Intent received = getIntent();
String stringExtra = received.getStringExtra("StringExtraKey"); // 文字列の Extra を取り出す
boolean booleanExtra = received.getBooleanExtra("BooleanExtraKey"); // boolean の Extra を取り出す
int integerExtra = received.getIntExtra("IntegerExtraKey"); // int の Extra を取り出す
List<String> listExtra = received.getStringArrayListExtra("StringArrayListExtraKey"); // ArrayList<String> の Extra を取り出す
}
}
Android のステータスバー(画面上部の、時間や電波状況を表示している領域)に、アプリからのお知らせを表示する仕組みを Notification と言います。
Notification の表示には、以下に挙げる 2 種類のものがあります。
- Normal View
-
Android で最も一般的な Notification の表示です。
左端から順に、6 つの要素から構成されています。- 通知のタイトル
- アプリのアイコン
- 通知の詳細メッセージ
- 通知の情報量
- 通知の小さいアイコン
- 通知を表示した時間
- Big View
-
JellyBean 以降の Android で登場した、新しいスタイルの Notification です。
通知ドロワーの 1 番上にくる Notification のための表示スタイルです。以下に挙げる 7 つの要素から構成されています。
- 通知のタイトル
- アプリのアイコン
- 通知の詳細メッセージ
- 通知の情報量
- 通知の小さいアイコン
- 通知を表示した時間
- 詳細表示 View
詳細表示 View には、標準で幾つかのスタイルが決められています。
- Big Picture Style
- Big Text Style
- Inbox Style
通知を表示するための窓口は、NotificationManager
が持っています。
このNotificationManager
に対して、通知そのもののデータを受け持つNotification
オブジェクトを渡すことによって、通知を表示しています。
Notificaton
オブジェクトそのものについては、NotificationCompat.Builder
クラスがその生成の役割を持っています。
Notification
クラスそのものを用いてNotification
オブジェクトを生成することも可能ですが、一部端末で不具合があることから、非推奨となっています。
通知を表すNotification
オブジェクトは、少なくとも、アプリのアイコン、通知のタイトル、通知の詳細メッセージの 3 つの情報を持っていなくてはなりません。
通知をタップすると、通知を発信したアプリが起動します。
このため、通知でもIntent
の仕組みを利用しています。
通知でのIntent
の利用方法は、通常の Activity の起動方法とは異なり、すこし特殊な側面を持っています。
通常、Intent
オブジェクトは、Activity の呼び出しや、Service の呼び出し、Broadcast の為に利用されます。
先の項で挙げた方法では、それぞれの呼び出しのタイミングで即座に各コンポーネントが呼び出されます。
一方、通知では、自分たちのアプリケーションではなく、他のアプリケーション(通知の場合は Android のシステム)にIntent
の送信を 行わせる ことになります。
このような要求を満たすための仕組みとして、PendingIntent
があります。
この仕組を用いることで、Intent
の送信のタイミングを遅延させたり、他のアプリに自分の作ったIntent
オブジェクトのハンドリングを任せたりすることができます。
この仕組は、AppWidget でも利用されています。
参考:PendingIntent | Android Developers
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// do something...
// Intent の準備。明示的 Intent でも、暗黙的 Intent でもどちらでも構わない
Intent intent = new Intent(this, SubActivity.class);
// PendingIntent オブジェクトの生成。このオブジェクトを他のアプリに渡すことで、引数に渡した Intent の送信を委ねることができる
// PendingIntent は、Intent の送信先のコンポーネントの種類によって使い分けること
PendingIntent activityIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
PendingIntent
オブジェクトの作成は、遅延させるIntent
オブジェクトのターゲットとしているコンポーネントによって、利用するメソッドが変わります。
PendingIntent#getActivity(Context, int, Intent, int)
- Activity がターゲットの`PendingIntent`オブジェクトを作成します。
PendingIntent#getActivities(Context, int, Intent[], int)
-
Activity がターゲットの`PendingIntent`オブジェクトを作成します。
こちらは、複数の Activity を扱うことが出来るよう、`Intent`オブジェクトを配列で渡すようになっています。
Honeycomb 以降で利用可能です。 PendingIntent#getBroadcast(Context, int, Intent, int)
- Broadcast 用の`Intent`を持つ`PendingIntent`オブジェクトを作成します。
PendingIntent#getService(Context, int, Intent, int)
- Service がターゲットの`PendingIntent`オブジェクトを作成します。
それぞれどのメソッドも、第 2 引数に、int 型整数を要求しています。
この整数は、PendingIntent
を一意に認識するためのものです。どの Context から発せられたPendingIntent
か、だけでなく、その中でもどのような種類のPendingIntent
か、を示すことができます。
公式の API リファレンスには、Currently not used
と記載されていますが、実際には利用されている点に注意してください。
第 4 引数の int 型整数は、PendingIntent
オブジェクトを受け取る側が、それをどのように扱うかを指示するためのものです。
以下の 4 つの定数が定義されており、ビット演算(OR)で複数指定することが可能です。
PendingIntent.FLAG_CANCEL_CURRENT
- 既に
PendingIntent
オブジェクトを作成している場合、新しいPendingIntent
オブジェクトを生成する前に、古い方をキャンセルします。 PendingIntent.FLAG_NO_CREATE
- 未だ
PendingIntent
オブジェクトが作成されていない場合、null を返します。つまり、既にPendingIntent
オブジェクトが作成されている場合には、そのオブジェクトが返されます。 PendingIntent.FLAG_ONE_SHOT
-
PendingIntent
オブジェクトを利用できるのは、ただ一度だけに制限するものです。 PendingIntent.FLAG_UPDATE_CURRENT
- 既に
PendingIntent
オブジェクトを作成している場合、そのオブジェクトが持つ`Intent`オブジェクト自体は置き換えず、`Intent`オブジェクトが持つ`Extras`のみを置き換えます。
通知そのものを表すNotification
オブジェクトを作成するものです。
名前が示す通り、Builder パターンにしたがってNotification
オブジェクトを作成していきます。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, SubActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Notification notification = builder
// 通知の日時
.setWhen(System.currentTimeMillis())
// 通知のタイトル
.setContentTitle("通知だヨ!")
// 通知の詳細メッセージ
.setContentText("通知の詳しい内容をここに書きます。")
// 通知のアイコン
.setSmallIcon(R.drawable.ic_launcher)
// 通知を表示した瞬間、通知バーに表示するショートメッセージ
.setTicker("通知だヨ!")
// 通知をタップした時に使う PendingIntent
.setContentIntent(pendingIntent)
// この通知が未だ表示されていない時だけ、音やバイブレーション、ショートメッセージの表示を行う
.setOnlyAlertOnce(true)
// タップしたら消えるようにする
.setAutoCancel(true)
.build();
}
}
Notification
オブジェクトの作成ができたら、NotificationManager
を利用して、通知を表示します。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Notification notification = /* 通知オブジェクトの作成(省略) */
// 直接インスタンス化せず、Context を経由してインスタンスを取得する
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 通知の種類に応じて id を割当てることが出来る。
// id の異なる通知は違うものとして扱われる。
manager.notify(0, notification);
}
}
- (実習) 画面に複数のボタンが配置されています。各ボタンのクリックイベントを拾う処理の中で、コメントに記述された Activity を呼び出すコードを書いてください。
- (実習) 画面に複数のボタンが配置されています。各ボタンのクリックイベントを拾う処理の中で、コメントに記述された Action を実行させるコードを書き、その
Intent
オブジェクトを受け取るためのBroadcastReceiver
を作成し、AndroidManifest に記述してください。 - (課題) 画面にボタンが 1 つ配置されています。このボタンのクリックイベントを拾う処理の中で、ブラウザを立ち上げ、指定した URL を読み込むための
Intent
オブジェクトを作成し、ブラウザを立ち上げるところまでを実装してください。 - (課題) 画面にボタンが 1 つ配置されています。このボタンのクリックイベントを拾う処理の中で、EditText を 1 つと、ボタンを 1 つ配置した新しい Activity を立ち上げ、EditText の入力内容を結果として返し、返された結果を Toast で表示するようにしてください。
- (実習) アイコン、タイトル、詳細メッセージを含む通知を表示してください。
- (実習) アイコン、タイトル、詳細メッセージを含む通知を表示し、通知をタップしたら MainActivity ではない新しい Activity を立ち上げるようにしてください(プロジェクトは実習 1 と同じもので良い)。
- (課題) アイコン、タイトル、詳細メッセージを含む通知を表示してください。通知を表示するときに、バイブレーションを作動させるようにしてください。
- (課題) アイコン、タイトル、詳細メッセージと、通知を表示した時に展開するティッカーテキストを含む通知を表示してください(プロジェクトは課題 3 と同じもので良い)。
- (課題) アイコン、タイトル、詳細メッセージを含む通知を表示してください。通知をタップしたら、指定した ACTION を受け取ることが出来る Activity を実行するようにしてください。
- 通知をタップすると、このような画面が表示されます。
- この画面では、どちらがどの画面に対応しているのかが分からないので、AndroidManifest を編集して分かりやすい表示にしてください
Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.