Firebaseを実装し、Firebase通知をテストしました。アプリがフォアグラウンドにあるとき、問題はありません。FirebaseMessagingServiceを拡張し、onMessageReceivedでメッセージとデータを処理するサービスを実装しました
アプリがバックグラウンドにあるときに問題が発生しました。アプリを開くだけでなく、特定のアクティビティを開き、予定されていることを行う通知を送信したいと思います。
Firebaseガイドに記載されているとおりに実行しましたが、特定のアクティビティを開始できません。
ここでマニフェスト:
<activity Android:name=".BasicNotificationActivity">
<intent-filter>
<action Android:name="OPEN_ACTIVITY_1" />
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
</activity>
そして、Firebase Console。 「BasicNotificationActivity」を開くには、これらのフィールドに何を書く必要がありますか?
これはこの質問の複製です: Firebase FCM通知click_actionペイロード
しかし、この質問の著者が受け入れた答えは、Firebase Consoleでは不可能であると述べているだけですが、簡単な回避策があります。 diiduによるこの回答 同じ質問に対する私が使用する回避策を説明しています。
UPDATE:
彼の答えを詳しく説明するには:
ヘルパークラスを追加します(またはstartActivity()
メソッドを実装します):
_public class ClickActionHelper {
public static void startActivity(String className, Bundle extras, Context context){
Class cls;
try {
cls = Class.forName(className);
}catch(ClassNotFoundException e){
//means you made a wrong input in firebase console
}
Intent i = new Intent(context, cls);
i.putExtras(extras);
context.startActivity(i);
}
}
_
アプリのランチャーアクティビティで、onCreate()
およびonNewIntent()
(onNewIntent()
がonCreate()
シングルトップフラグでアクティビティが起動された場合):
_@Override
protected void onCreate(Bundle bundle) {
[...]
checkIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
[...]
checkIntent(intent);
}
public void checkIntent(Intent intent) {
if (intent.hasExtra("click_action")) {
ClickActionHelper.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
}
}
_
そしてonMessageReceived()
で:
_ public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
if (data.containsKey("click_action")) {
ClickActionHelper.startActivity(data.get("click_action"), null, this);
}
}
_
Firebaseコンソールで通知を送信するには、次のようにキーと値のペアをカスタムデータとして配置します。
_Key: click_action
Value: <fully qualified classname of your activity>
_
これで、通知を受信してクリックすると、アクティビティが開きます。アプリがフォアグラウンドにある場合、すぐにアクティビティに変更されます-このアクティビティに行きたいかどうかをユーザーに尋ねるとよいでしょう(onMessageReceived()
にダイアログを表示します)。
私はhandleIntent(Intent intent)
メソッドを使用してintent
を処理し、その特定の画面に移動しました。以下は、アプリがバックグラウンドにある場合でも完全に動作している私のコードです:
FCMMessagingService.Java which extends FCMMessagingService
@Override
public void handleIntent(Intent intent) {
super.handleIntent(intent);
Intent i = null;
String value_action = "";
if (intent.getExtras() != null) {
if (key.equals("click_action")) {
value_action = intent.getExtras().getString(key);
}
i = new Intent(FCMMessagingService.this, MainActivity.class);
i.putExtra("notificationFlag", value_action);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, notifCount, i, PendingIntent.FLAG_ONE_SHOT);
final int icon = R.mipmap.logo;
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
Notification notification;
notification = notificationBuilder.setSmallIcon(icon).setTicker(title)
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(body)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon))
.build();
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(body);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
notificationBuilder.setContentIntent(pendingIntent);
notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
notificationBuilder.setSmallIcon(R.mipmap.logo);
} else {
notificationBuilder.setSmallIcon(R.mipmap.logo);
}
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifCount, notification);
}
この質問は2歳です。しかし、まだ関連しています。これは、Firebaseコンソールで( `click_actionなしで)行う方法です。
アプリがバックグラウンドにある場合、onMessageReceived
は呼び出されません。ただし、アプリがバックグラウンドであるときに通知を受け取ると、firebaseコンソールで指定したカスタムデータとともにIntent
を受け取ります。
したがって、ユーザーが通知をタップすると、_the intent
_が実行され、ランチャーアクティビティが開きます。ランチャーアクティビティのgetIntent().hasExtra("key")
でデータを確認できます。 _"key"
_は、コンソールで指定するキーです。
その_"key"
_があるかどうかを確認してから、別のIntent
を作成してstartActivity
を呼び出すことができます
これが私の実装です
SplashActivity
> OnCreate
(この方法は、ランチャーアクティビティとしてスプラッシュスクリーンがある場合に最適です):
_if (getIntent().hasExtra("key")){
Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);
finish();
} else {
startActivity(new Intent(this, MainActivity.class));
finish();
}
_
これにより、TargetActivity
が開始されます。あなたの希望に応じてこれに任意の機能を追加できます:)
私もあなたのようなトラブルを抱えていますが、私が知っている事実である正しい答えは得られません、
- onNewIntent
アプリが動作するデフォルトアクションのバックグラウンドcozである場合、このオーバーライドメソッドは動作しませんAndroid.intent.action.MAIN
- Firebaseコンソール
firebaseコンソールは、click_actionを処理するのに十分なパワーがありません。つまり、アプリがバックグラウンドにある場合、クリックアクションはアプリケーションに到達できません。
- CURL
Curlはアプリのバックグラウンドで動作していますが、フォアグラウンドではない場合があります。
curl --header "Authorization: key=<Colud_Messaging_Server_Key_here>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"dwdfosu6SDs:APA91bFWxZZB2f8AOgP9MG504cy5AhFECHGbYFfIzVixoAfy-ErT0NYQrREg150CbKYBtk3Ywpu7WQuWsQhk-VmoOe-0iDK3ZgaFZNvYxDuixZB8zQp0zydoXhyrMosi5C4eyBb7Ai1z\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"noti\",\"ticket_download\":\"noti\"}}"
ミニフェストを追加
<activity
Android:name=".activity.TicketDownload"
Android:exported="true">
<intent-filter>
<action Android:name="noti" />
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
</activity>
注:cloud_messaging_server_keyは設定> cloudmessagingにあります
何か新しい事実があれば、教えてください。