はじめに
Codelabs タスク1:基本的な通知を作成するを参考に通知機能を実装してみた。
通知機能の実装ポイント
①通知チャネルを作成する
- チャネルIDを用意
- 通知チャネルのカスタマイズ初期設定(APIレベル26以上に対して)
- チャネルの設定名称
- 通知の優先度(他にも通知が複数あったときの表示位置の優先度)
- バイブ、LEDの色設定
- チャネルの説明文
- 注意事項
- Android8.0(APIレベル26)より古いデバイスはカスタマイズできない。
- Android8.0(APIレベル26)以上は通知チャネルを作成しないとクラッシュする。
通知チャネル画面を比較する
Android7.0(APIレベル24) | Android10.0(APIレベル29) |
---|---|
![]() |
![]() |
通知チャネルのカスタマイズ画面(APIレベル26以上)

②通知を作成する
- 通知IDを用意
- 通知する内容を設定
- タイトル
- 本文
- アイコン
- タップしたときの処理
- 通知の優先度(API25以下に対して)
- バイブ、LEDの色設定(API25以下に対して)
③通知を送信する
ボタンがクリックされた時に②で設定した通知を送信させる
実装
layout
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<data>
<variable
name="viewModel"
type="com.example.samplenotification.NotificationViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/notify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Notify Me!"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:onClick="@{(v) -> viewModel.sendNotification()}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Interface
NotificationView
public interface NotificationView {
PendingIntent getNotificationContentIntent(int notificationId);
Context getContext();
}
Activity
MainActivity.java
public class MainActivity extends AppCompatActivity implements NotificationView{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
NotificationViewModel notificationViewModel = new NotificationViewModel();
// ViewModelにActivityのViewを紐付ける
notificationViewModel.setView(this);
// xmlのviewModelにNotificationViewModelを紐付ける
binding.setViewModel(notificationViewModel);
// 通知チャネル作成
notificationViewModel.createNotificationChannel();
}
// PendingIntentを使用すると、Android通知システムがコードに代わって割り当てられたアクションを実行してくれる。
@Override
public PendingIntent getNotificationContentIntent(int notificationId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
// PendingIntentの作成にはコンテンツインテント(アクティビティを起動するインテント)と通知idが必要
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
notificationId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return notificationPendingIntent;
}
@Override
public Context getContext() {
return this;
}
}
ViewModel
NotificationViewModel.java
public class NotificationViewModel {
// チャネル ID 全てのチャネルはパッケージ内で一意のIDに関連付ける
private static final String PRIMARY_CHANNEL_ID = "primary_notification_channel";
// PendingIntentに渡す通知id(requestCode)。 通知作成,更新または削除する場合に必要になるため、通知IDは必ず保存する。
private static final int NOTIFICATION_ID = 0;
// 通知処理を管理してくれるオブジェクト
private NotificationManager mNotifyManager;
private NotificationView view;
public void setView(NotificationView view) {
this.view = view;
}
// 通知チャネル作成(ユーザーが通知設定をカスタマイズできるようにする)
public void createNotificationChannel() {
mNotifyManager = (NotificationManager) view.getContext().getSystemService(NOTIFICATION_SERVICE);
// Android 8.0(APIレベル26)より古いデバイスはカスタマイズできない。逆にAndroid8.0(APIレベル26)以上は作成しないとクラッシュする。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(PRIMARY_CHANNEL_ID, "お知らせ", NotificationManager.IMPORTANCE_HIGH);
// 通知機能の初期設定
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription("お知らせの説明");
mNotifyManager.createNotificationChannel(notificationChannel);
}
}
// 送信する通知内容を定義
private NotificationCompat.Builder getNotificationBuilder() {
// MainActivityを起動してくれる通知のコンテンツインテントを取得
PendingIntent notificationPendingIntent = view.getNotificationContentIntent(NOTIFICATION_ID);
// 通知ビルダー(チャネル ID の指定を必要とするコンストラクタ)の初期設定をする
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(view.getContext(), PRIMARY_CHANNEL_ID)
.setContentTitle("通知されました")
.setContentText("ここは本文です")
.setSmallIcon(R.drawable.ic_android) // 通知アイコンの設定
.setContentIntent(notificationPendingIntent) // ユーザーが通知をタップしたときに起動するインテント
.setAutoCancel(true) // ユーザーが通知をタップしたときに通知を閉じる
// 以下、Android 8.0(APIレベル26)より古いデバイスに対しての設定
.setPriority(NotificationCompat.PRIORITY_HIGH) // 通知の優先度を設定。通知が複数あったとき優先度の高い通知から上に並べられる
.setDefaults(NotificationCompat.DEFAULT_ALL); // 通知の音、バイブレーション、LEDの色パターンをデフォルト値に設定
return notifyBuilder;
}
// 通知ビルダーの結果を送信する(通知発信)
public void sendNotification() {
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
}
}
おわりに
次回は通知の更新、キャンセルを紹介
参考サイト