Android Oで導入されたNotification Channelsを使ってみた

Android Oで色々と機能が追加されたので、色々試してみたいですが、先ずは「Android O Features and APIs」の冒頭で紹介されているNotificationsのNotification Channelsを試してみました。

以前の投稿でAndroid Studio 2.4 Preview3のインストールとPixelエミュレータの起動まではできたので、その環境で実装していきます。まぁ、基本的には公式のサンプル通りですが。

Android Studioのメニューから「File > New > New Project」と選択して適当にプロジェクトを作ります。プロジェクト名は分かりやすく(?)「Oreo」にしました。Activityの種類は「Empty Activity」にしました。

途中、Android Studioのアップデートがあるというポップアップが表示されたので、すかさずアップデート!Preview4になりました… と思ったらいきなりエラーメッセージが!「Could not initialize class com.android.ide.common.util.ReadWriteProcessLock」

公式サイトにも「Known Issues」として取り上げられていました。要は「再起動してね」と。

https://androidstudio.googleblog.com/2017/04/android-studio-24-preview-4-is-now.html

めげずに(?)Android Studioを再起動して開発を続けます。NotificationChannelクラスのリファレンスも見つつ。ページ背景にはひたすら「PREVIEW」の文字が…(2017年4月時点)全体の色も緑でなく黄色になっています。いずれ正式に緑になるのでしょう。

NotificationChannelクラスリファレンス

Notificationに「チャンネル」という、分類のような要素を紐付ける事が可能になったわけですが、チャンネルには更に「グループ」を割り当てる事ができます。今回は、チャンネルとグループ、両方を生成し、Notificationに適用するアプリにしてみます。チャンネルとグループの設定はアプリの画面から入力できるようにして、色々な設定が試せるようにしてみます。

先ずは画面から…と、何とAndroid Studio2.4からでしょうか、ActivityのデフォルトレイアウトがRelativeLayoutでなくConstraintLayoutになっています。うーん、まだ慣れてないのに…なにはともあれチャンネルとグループの情報を入力できる画面を作成してみます。完成した画面はこんな感じで:
NotificationChannelアプリ
画面下部の「Hello World!」は残骸です、気にしないでください…
UI部品が多いので、xmlがちょっと長くなってしまいました。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="jp.co.techfirm.oreo.MainActivity">

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.383"
        app:layout_constraintVertical_bias="0.819" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Channel_Group"
        android:text=""
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="create group"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText1"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Channel_ID"
        android:text=""
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/button1"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="create channel"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/editText2"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <EditText
        android:id="@+id/editText3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="title"
        android:text=""
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/button2"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <EditText
        android:id="@+id/editText4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:ems="10"
        android:hint="content"
        android:text=""
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText3"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <EditText
        android:id="@+id/editText5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Notification_ID"
        android:inputType="numberDecimal"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/editText4"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:text="post"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText5"
        android:layout_marginTop="9dp" />

</android.support.constraint.ConstraintLayout>

画面ができたら、Activityの処理を実装する前にgradleの設定をしておこうと思います。あちこちに「O」の文字が指定されていますね。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 'android-O'
    buildToolsVersion '26.0.0-rc1'
    defaultConfig {
        applicationId "jp.co.techfirm.oreo"
        minSdkVersion 'O'
        targetSdkVersion 'O'
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
}

Notificationに表示するアイコンを作ってみました。
The Gimpで「の」の文字を描いてみました、背景を透過するのがポイントでしょうか。公式ガイドラインに沿ってサイズは48 x 48pxにしました。
icon_no
そして遂にActivityの実装です。グループを作ってからチャンネルを作り、チャンネルができたらNotificationを表示できるようにしました。グループ名の先頭には「雑談:」という文字を付けて、チャンネル名の先頭には「24ちゃんねる:」という文字を付けるようにしました、同じ値を入れた時に区別したかっただけですが。

public class MainActivity extends AppCompatActivity {
    private EditText inputChId;
    private EditText inputChGrp;
    private EditText inputTitle;
    private EditText inputContent;
    private EditText inputNotifId;
    private Button btnCreCh;
    private Button btnCreGrp;
    private Button btnPost;
    private String channelId = null;
    private String grpId = null;
    private NotificationManager notificationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // コンポーネント取得。
        inputChGrp = (EditText)findViewById(R.id.editText1);
        inputChId = (EditText)findViewById(R.id.editText2);
        inputTitle = (EditText)findViewById(R.id.editText3);
        inputContent = (EditText)findViewById(R.id.editText4);
        inputNotifId = (EditText)findViewById(R.id.editText5);
        btnCreGrp = (Button)findViewById(R.id.button1);
        btnCreCh = (Button)findViewById(R.id.button2);
        btnPost = (Button)findViewById(R.id.button3);
        notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

        // ボタン押下でChannel生成。
        btnCreCh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                channelId = inputChId.getText().toString();
                // 設定画面などでユーザーに見せるチャンネル名。識別できるようID値を付加してみました。
                CharSequence channelName = "24ちゃんねる:" + inputChId.getText();
                /*
                指定できる値は以下7種類。
                NotificationManager.IMPORTANCE_UNSPECIFIED (-1000);
                NotificationManager.IMPORTANCE_NONE (0);
                NotificationManager.IMPORTANCE_MIN (1);
                NotificationManager.IMPORTANCE_LOW (2);
                NotificationManager.IMPORTANCE_DEFAULT (3);
                NotificationManager.IMPORTANCE_HIGH (4);
                NotificationManager.IMPORTANCE_MAX (5);
                 */
                int importance = NotificationManager.IMPORTANCE_DEFAULT;
                NotificationChannel mChannel = new NotificationChannel(channelId, channelName, importance);
                mChannel.enableLights(true);
                mChannel.setLightColor(Color.RED);
                mChannel.enableVibration(true);
                mChannel.setGroup(grpId);
                mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
                notificationManager.createNotificationChannel(mChannel);
                btnPost.setEnabled(true);  // notificationをpostしてok。
            }
        });
        btnCreCh.setEnabled(false);     // グループを作成するまでは無効に。
        // ボタン押下でChannel Group生成。
        btnCreGrp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                grpId = inputChGrp.getText().toString();
                // 設定画面などでユーザーに見せるグループ名。識別できるようにID値を付加してみました。
                CharSequence grpName = "雑談:" + inputChGrp.getText();
                notificationManager.createNotificationChannelGroup(new NotificationChannelGroup(grpId, grpName));
                btnCreCh.setEnabled(true);  // チャンネルを作ってok。
            }
        });
        btnPost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int notificationId = 1;
                notificationId = Integer.parseInt(inputNotifId.getText().toString());
                // アイコンサイズはとりあえず48x48にしてみた:https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar.html
                Notification notification = new Notification.Builder(MainActivity.this)
                        .setContentTitle(inputTitle.getText())
                        .setContentText(inputContent.getText())
                        .setSmallIcon(R.drawable.icon_no)
                        .setChannel(channelId)
                        .setGroup(grpId)
                        .build();
                notificationManager.notify(notificationId, notification);
            }
        });
        btnPost.setEnabled(false);     // チャンネルを作成するまでは無効に。
    }
}

アプリを起動して、各種値を入力して「POST」ボタンを押せば…
Notification用設定を入力
↓画面の左上にNotificationの「の」アイコンが表示されました!

スワイプして詳細を表示…

Notification部分をロングタップすると設定が表示されます。

これでNotificationのグループやチャンネルを色々な設定で試せます。
グループは主にマルチユーザに対して有効な設定なようなので、マルチユーザを意識したアプリを作るまでは出番が少ないかもしれませんが…

 

カテゴリー: Android タグ: , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です