目前分類:Android (2)

瀏覽方式: 標題列表 簡短摘要

1. setSmallIcon() 只可以用白色透明組成的圖片,漸層也不行,不然會變成一塊銀灰色的圖

2. 最好使用 android studio (File -> new -> image asset ) 產生各種 Size 的圖,Icon Type 要選 Notification Icons,超方便低

3. 圖示都白白的不好看,用 setColor() 設定圖示顏色,真心覺得多個顏色真的差很多

   a) Android < N 使用此作為圖標的背景顏色。

   b) Android >= N 使用它來為圖標和應用程序名稱著色。

4. 強烈建議一定要在 app/src/main/AndroidManifest.xml 設定 default 值,才不會遇到自動生成的通知,圖示是一塊銀灰色的,或是沒有顏色,看起來就像是BUG對吧~
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

 

文章標籤

vivian 發表在 痞客邦 留言(0) 人氣()

說到 APP 推播,早期真的比較麻煩,不管是對 APP 端還是後台都是很複雜的工作
由於 APP 端,iOS 和 Android 各走各的路,後台要針對 iOS 和 Android 做設置,還要保存管理載具的 Token
才能做到對所有載具廣播訊息,也可以針對會員載具發送私人訊息

Android 部分早期用 GCM,說實在,改用 FCM (Firebase Cloud Messaging) 真的方便多了
而且 iOS 也可以用 FCM ,麻煩事都交給 Firebase,對後台而言真是個好消息

在 Android 這邊超簡單,以下幾個的步驟就搞定了

1. 下載 google-services.json 檔案移到 Android 應用程式的模組根目錄中(就是 app 資料夾下面)

   a) 建立一個 Firebase 專案,新增 Android 應用程式,註冊完成後,就可以下載  google-services.json

   b) 已有專案和Android 應用程式,就到 [專案設定] 找 Android 應用程式的 [下載最新的設定檔],就可以下載  google-services.json

2. 在模組根目錄中 app/build.gradle 加

apply plugin: 'com.android.application'

android {

  // ...

}

dependencies {

  // ...

  implementation 'com.google.firebase:firebase-messaging:19.0.1'

}

3.  在 app/src/main/AndroidManifest.xml 加

<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<!-- Set custom default icon. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />

<!-- Set color used with incoming notification messages.  -->
<!-- 不同的Android版本以不同的方式使用此設置:Android < N 使用此作為圖標的背景顏色。 Android >= N 使用它來為圖標和應用程序名稱著色。 -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

<!-- Set default channel -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id" />

4. 建立 MyFirebaseMessagingService.java

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        super.onMessageReceived(remoteMessage);

        //收到 FCM 訊息分為 Notification 和 Data 兩種,取得方式如下

        //Data messages
        String title = remoteMessage.getData().get("title");
        String body = remoteMessage.getData().get("body");
        String badge = remoteMessage.getData().get("badge");
        int badgeCount = 0;

        if (badge.length() > 0 && TextUtils.isDigitsOnly(badge)) {
            badgeCount = Integer.parseInt(badge);
        }

        //Notification messages
        //String title = remoteMessage.getNotification().getTitle();
        //String body = remoteMessage.getNotification().getBody();
        
        //根據收到 FCM 訊息生成自己的通知
        sendNotification(title, body, badgeCount);

    }


    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param messageTitle FCM message Title received.
     * @param messageBody FCM message body received.
     * @param badgeCount
     */
    private void sendNotification(String messageTitle, String messageBody, String badgeCount) {

        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(messageTitle)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent)//效果:按下訊息,打開APP
                        .setNumber(badgeCount);


        //設置訊息數量(ShortcutBadger 會在部分廠牌手機的圖示上顯示數字)
        ShortcutBadger.applyCount(context, badgeCount); //for 1.1.4+

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

        //Android 8.0 Oreo 一定要實作 通知頻道(Notification channels)
        //Android 7.1或之前的舊版本Android手機中執行,它會以舊的通知方式展示,也就是沒有通知頻道的效果。
        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());
    }
}


Firebase 官方文件:  https://firebase.google.com/docs/cloud-messaging/android/client?authuser=0


完成以上步驟,基本上已經可以收到推播訊息了

值得注意的是

訊息發送端(後台)使用的推播訊息類型分為 Data messages 和 Notification messages 兩種

1. Data messages : 
    a) 無論 APP 處於 [前台執行] 還是 [背景執行],都會呼叫 onMessageReceived()
    b) 傳統的 GCM 就是用這種 

2. Notification messages : 
    a) 若 APP 處於 [前台執行] 才會呼叫 onMessageReceived()
    b) 若 APP 處於 [背景執行] 會顯示自動生成的通知。按下訊息,就會打開應用程式(真貼心!)

所以訊息發送端(後台)使用 Notification messages 時,APP 是處於 [背景執行] 還是 [前台執行] 狀態,通知是由不同對象處理的
這時記得去 AndroidManifest.xml 設定 FCM 用的 default icon , color , channel id ,就是跟 onMessageReceived() 設置的一樣就可以囉~

但是問題來了,如果在 onMessageReceived() 自訂訊息顯示樣式不只是 icon , color , channel id 和按下訊息就會打開應用程式這些呢!
例如: 按下訊息後,跳去某個指定畫面或是需要設置 Badge Count ...

這時,訊息發送端(後台)需強迫使用 Data messages,也就是不管 APP 是處於什麼狀態,保證呼叫 onMessageReceived() 生成自訂的通知樣式

文章標籤

vivian 發表在 痞客邦 留言(0) 人氣()