Android
 Computer >> コンピューター >  >> プログラミング >> Android

BroadcastReceiverを使ってAndroidの通知を表示する方法を解説

この記事では、BroadcastReceiverAlarmManagerを組み合わせて、指定した時間にAndroidの通知を表示する方法を解説します。アプリから一定時間後に通知を発行したい場合に役立つ実装例です。

全体の流れ

このサンプルでは、メニューから「5秒後」「10秒後」「30秒後」を選択すると、AlarmManagerが指定時刻にBroadcastReceiverを起動し、そのonReceive()メソッド内で通知を発行する仕組みを実装します。

ステップ1:新規プロジェクトの作成

Android Studioで新しいプロジェクトを作成します。メニューから「File」⇒「New Project」を選択し、必要な項目を入力してプロジェクトを作成してください。

ステップ2:res/layout/activity_main.xmlの編集

メインレイアウトファイルに以下のコードを追加します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity" />

ステップ3:res/menu/main_menu.xmlの作成

オプションメニュー用のXMLファイルを作成し、通知の遅延時間を選択するための3つのアイテム(5秒・10秒・30秒)を定義します。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_5"
        app:showAsAction="never"
        android:title="5 seconds" />
    <item
        android:id="@+id/action_10"
        app:showAsAction="never"
        android:title="10 seconds" />
    <item
        android:id="@+id/action_30"
        app:showAsAction="never"
        android:title="30 seconds" />
</menu>

ステップ4:src/MainActivity.javaの実装

メインアクティビティでは、メニュー選択時にscheduleNotification()メソッドを呼び出し、AlarmManagerで通知の発行をスケジュールします。getNotification()メソッドでNotificationCompat.Builderを使って通知オブジェクトを生成しています。

package app.tutorialspoint.com.notifyme;
import android.app.AlarmManager;
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.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
    public static final String NOTIFICATION_CHANNEL_ID = "10001";
    private final static String default_notification_channel_id = "default";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // メニューをインフレートし、アクションバーに項目を追加する
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_5:
                scheduleNotification(getNotification("5 second delay"), 5000);
                return true;
            case R.id.action_10:
                scheduleNotification(getNotification("10 second delay"), 10000);
                return true;
            case R.id.action_30:
                scheduleNotification(getNotification("30 second delay"), 30000);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    private void scheduleNotification(Notification notification, int delay) {
        Intent notificationIntent = new Intent(this, MyNotificationPublisher.class);
        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, 1);
        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        long futureInMillis = SystemClock.elapsedRealtime() + delay;
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        assert alarmManager != null;
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
    }
    private Notification getNotification(String content) {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, default_notification_channel_id);
        builder.setContentTitle("Scheduled Notification");
        builder.setContentText(content);
        builder.setSmallIcon(R.drawable.ic_launcher_foreground);
        builder.setAutoCancel(true);
        builder.setChannelId(NOTIFICATION_CHANNEL_ID);
        return builder.build();
    }
}

ステップ5:src/MyNotificationPublisher.javaの作成

BroadcastReceiverを継承したクラスを作成します。onReceive()メソッド内で通知チャンネルの生成(Android 8.0以降が必要)を行い、NotificationManagerを使って実際に通知を発行します。

package app.tutorialspoint.com.notifyme;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import static app.tutorialspoint.com.notifyme.MainActivity.NOTIFICATION_CHANNEL_ID;
public class MyNotificationPublisher extends BroadcastReceiver {
    public static String NOTIFICATION_ID = "notification-id";
    public static String NOTIFICATION = "notification";
    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = intent.getParcelableExtra(NOTIFICATION);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
            assert notificationManager != null;
            notificationManager.createNotificationChannel(notificationChannel);
        }
        int id = intent.getIntExtra(NOTIFICATION_ID, 0);
        assert notificationManager != null;
        notificationManager.notify(id, notification);
    }
}

ステップ6:AndroidManifest.xmlの編集

マニフェストファイルにVIBRATE権限を追加し、MyNotificationPublisherをreceiverとして登録します。これにより、AlarmManagerからのブロードキャストを受け取れるようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.tutorialspoint.com.notifyme">
    <uses-permission android:name="android.permission.VIBRATE" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".MyNotificationPublisher" />
    </application>
</manifest>

アプリの実行と動作確認

それでは、アプリケーションを実行してみましょう。実機のAndroidスマートフォンをパソコンに接続していることを前提とします。Android Studioからプロジェクトのアクティビティファイルを開き、ツールバーの「Run」アイコンをクリックしてください。デバイスを選択してアプリを起動すると、以下のような画面が表示されます。

BroadcastReceiverを使ってAndroidの通知を表示する方法を解説

メニューから遅延時間を選択すると、指定した秒数が経過した後に通知が表示されます。

BroadcastReceiverを使ってAndroidの通知を表示する方法を解説

まとめ

このように、AlarmManagerとPendingIntent、BroadcastReceiverを組み合わせることで、指定したタイミングで通知を発行することができます。リマインダーアプリや定期通知など、時間指定の通知機能を実装したい場合にぜひ参考にしてください。

  1. 【Android開発】角丸のEditTextを作成する方法をステップごとに解説

    はじめにこの記事では、Androidアプリで角が丸い(角丸)EditTextを作成する方法を、具体的なコード例とともに解説します。drawableリソースにカスタムのshapeファイルを定義し、それをEditTextの背景に設定するだけで、簡単におしゃれな角丸デザインを実現できます。手順1:新規プロジェクトを作成するまず、Android Studioで新しいプロジェクトを作成します。メニューから「File → New Project」を選択し、必要な情報を入力してプロジェクトを作成してください。手順2:レイアウトファイル(activity_main.xml)を編集する次に、「res/layou

  2. CSSで通知バッジ付きボタンを作成する方法【コード例付き】

    CSSを使えば、通知件数を示すバッジ(数字)が付いたボタンを簡単に作成できます。ポイントは、親要素に position: relative; を指定し、バッジ側に position: absolute; を指定して右上に配置することです。以下に、実際に動作するサンプルコードを紹介します。 実装例 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <styl