今さらだけど！　AndroidのNotificationをJavaで実装してみる(初級編)

# はじめに

Androidの通知(Notification)に関する基本的な使い方を記します。
内容は初心者向けの簡単なものになっています。サンプルアプリをベースに説明したいと思います。

サンプルアプリの環境は以下のとおりです。
- Android Studio 4.0.1
- MacOS 10.15.6
- Android Virtual Device  -  android10.0 / 1080 x 2160

# Notificationとは
[公式ページ](https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=ja)によると以下のような記述があります

> 通知は、アプリの UI 以外で Android が表示するメッセージであり、リマインダー、他の人からのメッセージ、アプリからのタイムリーな情報などをユーザーに提供します。ユーザーは通知をタップしてアプリを開いたり、通知から直接操作したりできます。

うーん、難しいですね・・・
要するにスマホのステータスバーに表示されるアレですね。


# 今回のサンプルアプリ

今回は「ボタンを押下し通知を表示する」アプリを作りたいと思います。
今回はここまでのアプリです。その先のコンテンツをタップすると「アプリを開く」などは今回は実装しません。 
現在はAndroidではKotlinが主流ですが、今回もJavaで実装したいと思います。

今回のサンプルアプリは以下のような動きになります。
* 画面の「BUTTON」を押下
* ステータスバーにアイコンが表示される
* ステータスバーを降ろすと通知のコンテンツが表示される


![sampleApp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701083/b891163b-29b7-cc24-14f1-11877e3eb202.png)



# 実装

では、早速実装しましょう。
ボタンが画面中央にあるだけの画面です。`MainActivity.java`と`activity_main.xml`は以下のとおりです。

### activtiy_main.xml

```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```


### MainActivity.java

```java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {        // ・・・(1)
            int importance = NotificationManager.IMPORTANCE_DEFAULT;

            NotificationChannel channel                              // ・・・(2)
                = new NotificationChannel("CHANNEL_ID", "サンプルアプリ", importance);

            channel.setDescription("説明・説明 ここに通知の説明を書くことができます");     
                  
            NotificationManager notificationManager = getSystemService(NotificationManager.class); 
            notificationManager.createNotificationChannel(channel);      
        }
        
        Button button = findViewById(R.id.button);
        button.setOnClickListener(v -> notifyTest());                // ・・・(3) 
    }

    public void notifyTest() {                     
        NotificationCompat.Builder builder 
            = new NotificationCompat.Builder(this, "CHANNEL_ID")     // ・・・(4)
                .setSmallIcon(android.R.drawable.ic_menu_info_details)   
                .setContentTitle("タイトル")                               
                .setContentText("メッセージ・メッセージ")                      
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);      

        NotificationManagerCompat notificationManager 
                = NotificationManagerCompat.from(this);

        notificationManager.notify(R.string.app_name, builder.build());  
                                                                     // ・・・(5)
    }
}
```

（１） Android 8.0 以上で通知を配信するには、アプリの通知チャネルをシステムに登録する必要があります。アプリが起動したらすぐにこのコードを実行します。

> 既存の通知チャネルを作成してもオペレーションは実行されないので、これを繰り返し呼び出しても問題ありません。

ということですので、`onCreate`で呼び出しておけば問題ないでしょう。

（２）通知チャネルの実装です。通知チャネルは以下のようなイメージです。
スマホの設定 -> アプリ・通知 から見れる画面です。

![スクリーンショット 2020-09-05 23.30.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701083/54709944-b531-1bd0-4cff-fbb9dcc2dd15.png)

（３）ボタンを押したときの処理を実装します。

（４）通知を作成します。
アイコン、タイトル、メッセージなどが設定できます。

* setSmallIcon() で小さなアイコンを設定します。
* setContentTitle() でタイトルを設定します。
* setContentText() で本文テキストを設定します。
* setPriority() で通知の優先度を設定します。

![スクリーンショット 2020-09-05 23.36.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701083/6bccdb5b-9f82-192e-0262-1aef682a6bb2.png)

（５）通知を表示させます。
`notificationManager.notify`で通知を表示します。　引数には一意のIDと、`NotificationCompat.Builder.build()`の結果を渡します。

### 動作確認

アプリを起動し表示されたボタンを押すと・・・通知が表示されるはずです。
上のサンプルアプリの説明の図と同じ動きになれば成功です！


# まとめ

無事にサンプルは動作しましたか？たぶん、コピペで動くと思います。
Android8.0以上で通知を配信するときは追加の実装が必要なくらいで、あとは比較的簡単だと思います。

通知はまだまだたくさんの機能があります。進捗バーを追加したり、通知をタップしたときの実装も追加できます。このあたりの実装は今後記事にしたいと思います。

では、また！