通知が来ない「通知の自動調整」はOFFに。

「AIが判別」ということにして挙動の基準がユーザーにわからない機能って問題になることが多いです。

👉 LINEやGmailの通知が来ない慢性トラブルの原因がようやく判明?「通知の自動調整」の模様 | スマホダイジェスト 

しかも、機能をOFFにする設定が深く遠い。


設定

 ↓

アプリと通知

 ↓

特別なアプリアクセス

 ↓

通知の自動調整

 ↓

なし

notification-off

おせっかいな機能うざいですね。

Androidの通知機能は、これまでも混乱を招くことが多く、最も分かりづらい機能といってもいいでしょう。

👉 消した通知「通知履歴」をすばやく見る方法【Android11】 
👉 通知が来ない、遅れるときに見直すべき「電池(バッテリー)の最適化」 
👉 【Android Pie】「通知」設定のシンプルな考え方 


消した通知「通知履歴」をすばやく見る方法【Android11】

必要な通知を読む前に消してしまうこと、ありますよね。

通知をすべて消してしまうと、通知バー左下の「履歴」のボタンは表示されません。

なので、えーと、


[設定]

  |

[アプリと通知]

  |

[通知]

  |

[通知履歴]

ですかね、だるいですね!

通知の履歴

 

すばやく見る方法

「通知はありません」をクリックすると、すぐに「通知履歴」が表示されます。

👉 Android で通知を管理する - Android ヘルプ 


Related Categories :  Android


【Android Pie】通知を最小化する / 元に戻す

「通知がステータスバーに表示されない」とか「ステータスバーにアイコンを表示する設定に戻したい」ときの設定の手順です。

まず、表示された通知の横スワイプからの通知設定の変更で、「最小化」します。

きっと、この操作を使ってうるさい通知を非表示にしていることでしょう。

しかし、音楽プレーヤーのバックグラウンド再生などのそれを意味するアイコンを表示しておいてほしい場合があります。

その場合の戻し方です。



そのアプリの「アプリ情報」画面などから「通知」を選択してその設定へ。

各選択肢右にあるチェックボックスしか操作の対象でないと思っていたら、項目名もタップが可能でさらに表示される選択ダイアログにて設定できます。

このダイアログ、英語表示だと以下の文言になるけど、おかしくねえですか???

知らんけど。

👉【Android Pie】「通知」設定のシンプルな考え方
👉 How do I unminimize android notifications on P? : AndroidQuestions
👉【公式 2018-05-07】Android Pie のバージョンシェア がやっと 10%超えている件


FCM を Firebase コンソールから使う

以前まとめておいたつもりが時間が経つとすぐに理解できない。

FCM と Notification の併用をやめてバックグラウンド受信時にうれしがる

もう、面倒くさいので忘れていても直感的すぐに使いたいので

WEBで提供されている Firebaseコンソール(コンポーザー?)から。

 

送信時の「メッセージ」は必須である

APIから送信する場合は、「データ」のみでバックグランドでしれっと端末に渡すことができるが、

WEB画面から送信する場合は「メッセージ」の入力なしでは送信ボタンがが有効化されず送信できない。

 

送信時にアプリがフォアグラウンドの場合

通知バーは表示されない。

「データ」は、端末内で稼働している Service で受け取る。

「データ」がなければ何も起きない。

 

アプリがバックグラウンドの場合

「メッセージ」と「データ」は通知バーに入る。

「データ」のタイトルは通知バーに表示され、キーと値のペアデータは PendingIntent として通知バーに入る。

 

どう使う?

端末内でプロセスが死んでない限りはフォア/バックグラウンド共に同じ挙動としたい。

フォアグラウンド受信時にも同じ挙動をするように、サービスに処理を追加。

QucikStart のサンプル内に未稼働のコードがある。


/**
 * Create and show a simple notification containing the received FCM message.
 *
 * @param messageBody FCM message body received.
 */
private void sendNotification(String messageBody) {
    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = getString(R.string.default_notification_channel_id);
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_stat_ic_notification)
            .setContentTitle("FCM Message")
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_DEFAULT);
        notificationManager.createNotificationChannel(channel);
    }

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}

quickstart-android/MyFirebaseMessagingService.java at master · firebase/quickstart-android

結局は、起動されるActivityでIntentを受けるような処理を記述しなければならない。 これ書くと見通し悪くなる。きもい。


if (getIntent().getExtras() != null) {
    for (String key : getIntent().getExtras().keySet()) {
        Object value = getIntent().getExtras().get(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
    }
}

quickstart-android/MainActivity.java at master · firebase/quickstart-android

直感的にそのまま使うと、単に「アプリ起動を喚起するだけのもの」になってしまいがちだのだが、きもい。


FCM と Notification の併用をやめてバックグラウンド受信時にうれしがる

ややこしすぎな気がします。

この記事のタイトルも書いてて意味不明です。

以下のような、FCMにJSONをPOSTしてアプリで受ける場合の話です。


curl https://fcm.googleapis.com/fcm/send -X POST \
--header "Authorization: key=FirebaseConsoleのプロジェクトの設定、クラウドメッセージングのタブにあるサーバーキー" \
--Header "Content-Type: application/json" \
 -d '
 {
   "to":"/topics/all",
   "data":{
     "title":"New Notification!",
     "body":"Test"
   },
   "priority":"high"
 }'

このPOSTするJSONに含まれるデータ構造によって、アプリ側で受信する場合の処理の流れ変わって見通しが悪くなります。

きれいにまとめられています。

Firebase Notificationでアプリの状態による挙動の違いについて - Qiita

アプリがフォアグラウンドにある場合、このServiceのonMessageReceived()が呼び出されることになります。

アプリがバックグラウンドにある場合はこのonMessageReceived()は呼ばれることはなく、システム側で自動的にシステムトレイに通知を表示します。

"data"ブロックはConsoleからも含めることはできます(詳細オプションのカスタムデータで指定できる)。しかし、Consoleでは"notification"ブロックを省略することができません(メッセージ文を入力しないと送信できない)。

送信したメッセージに"data"ブロックがあっても、"notification"ブロックが存在する限り、アプリがバックグラウンドにある状態ではFirebaseMessagingServiceのonMessageReceived()は呼ばれません。

"data"ブロックの内容を受け取れないわけではありません。通知をクリックして起動したActivityのintentに含まれることになります。

"data"ブロックの内容の処理が、フォアグラウンド時に受け取ったときはFirebaseMessagingServiceで、バックグラウンドのときにはActivityでとなってしまって煩雑です。

実際に試してみると、これら書かれてることすごく良く分かります。

結局、この"notification"ブロックの特典としては、

アプリがバックグラウンド状態で受信した場合にのみ、アプリ側の実装なしで通知トレイに入る。

ということだけでしょうか、おおまかですが。

すべてのメッセージ受信時にonMessageReceived()が呼び出されれば、アプリがフォアグラウンドにあるかバックグラウンドにあるかを気にする必要がなくなります。

なるほど。

では、入れ子にしたらいいんじゃないかと。

例えば、


{
  // ...

  "notification": {
    "title" : "News!!",
    "body" : "New Product Release!!"
  },

  "data": {
    "user": "Yamada Taro",
    "age": 20
  },

  // ...
}

を以下のように入れ子にする。


{
  // ...

  "data": {
    "user": "Yamada Taro",
    "age": 20,

    "notification": {
      "title" : "News!!",
      "body" : "New Product Release!!"
    }

  },

  // ...
}

すべてサービスで受けることができます。


class  MyFirebaseMessagingService : FirebaseMessagingService() {

  override fun onMessageReceived(message: RemoteMessage) {

    // ...

    // 2層目以下はStringで送られてくるのでMap化
    message.data["notification"]?.let {
      val notification : Map<String, String> =
        Gson().fromJson(it, object : TypeToken<HashMap<String, String>>() {}.type)
      sendNotification(notification)
    }

  }

  // サンプルを参考に
  private fun sendNotification(notification: Map<String, String>) {
    val intent = Intent(this, MainActivity::class.java)
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

    val pendingIntent = PendingIntent.getActivity(this, 0, intent,
        PendingIntent.FLAG_ONE_SHOT)

    val channelId = getString(R.string.default_notification_channel_id)
    val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
    val notificationBuilder = NotificationCompat.Builder(this, channelId)
        .setSmallIcon(android.R.drawable.ic_notification_overlay)
        .setContentTitle(notification["title"])
        .setContentText(notification["body"])
        .setAutoCancel(true)
        .setSound(defaultSoundUri)
        .setContentIntent(pendingIntent)

    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    notificationManager.notify(0, notificationBuilder.build())
  }

quickstart-android/MyFirebaseMessagingService.java at master · firebase/quickstart-android

元々、Firebase てのは、敷居を下げてマーケティングなどに利用を広めようとしてるのかな。