繁体   English   中英

Android FCM 在应用程序被杀死时部分工作

[英]Android FCM working partly while app is killed

I have 2 kinds of notification builders in my MyFirebaseMessagingService.java, one passes string called 'lecture_date' and opens Lectures_graph.class while the other one passes string called 'web_url' and opens webview_base.class when clicked.

我想要实现的目标:即使应用程序被杀死,FCM 通知也能完全正常工作,一旦点击通知,通知必须打开活动(带有附加功能)。

我有多远:我可以收到打开 Lectures_graph.class 的通知,带有额外的意图,一切都加载并正常工作。 即使我收到 webview_base.class 活动的通知,当我单击通知时也没有任何反应。

可能有一件事指向问题 - Logcat 经常告诉我这个:

E/FirebaseMessaging: Notification pending intent canceled

我使用 PHP 发送通知(该代码 100% 正确且有效),下面显示的代码代表了为 webview_base.class 活动发送 JSON 的想法。 要发送 Lectures_graph.class 活动的通知,我只需将 click_action 从“OPEN_ACTIVITY_WEBVIEW”交换为“OPEN_ACTIVITY_LECTURES”并更改数据有效负载。 PHP for webview_base.class 活动发送了这样的数据:

$msg = array
    (
        'body'  => 'test body',
        'title'     => "test title",
        'click_action' => 'OPEN_ACTIVITY_WEBVIEW',
        'channelId' => "newsfeed",
        'vibrate'   => 1,
        'sound'     => 1
        
    );


//sends notifications via topics
$fields = array
    (
        "data" => [
            'web_url' => $_POST['notification_url']
        ],
        'notification'          => $msg,
        'to'  => '/topics/test'
    );

这是我来自 Android 工作室的整个清单文件:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="secret">
    
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:anyDensity="true" />
    
    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:theme="@style/AppTheme.CustomTheme"
        android:usesCleartextTraffic="true"
        tools:targetApi="m">
        <activity
            android:name=".systems.webview_activity.webview_base"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <category android:name="android.intent.category.BROWSABLE" />
                <action android:name="android.intent.action.VIEW" />
                <data android:scheme="file" />
                <data android:mimeType="\*/\*" />
                <data android:pathPattern=".*\\.kdb" />
                <data android:host="*" />
    

//even if this method worked with Lectures_graph activity
//it doesnt work with this one

                <action android:name="OPEN_ACTIVITY_WEBVIEW" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".systems.lectures.Lectures_graph"
            android:configChanges="keyboardHidden|screenSize"
            android:label="@string/title_lectures_graph"
            >
            <intent-filter>

//this intent filter provides correct response
//to click_action which is provided in my PHP file


                <action android:name="OPEN_ACTIVITY_LECTURES" />
                <action android:name = "android.intent.action.CREATE_SHORTCUT" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SplashScreen"
            android:configChanges="keyboardHidden|orientation|screenSize" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        </activity>
        <activity
            android:name=".NoInternetConnection"
            android:configChanges="keyboardHidden|orientation|screenSize" />
        <activity
            android:name="secret.systems.about.about_app"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:theme="@style/FullscreenTheme" />
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTask"
            android:configChanges="orientation|keyboardHidden|screenSize">
    
        </activity>
    
        <service
            android:name="secret.services.MyFirebaseMessagingService"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
    </application>
    
    </manifest>

MyFirebaseMessagingService.java:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());

            //get key/value from notification
            String lectureDate = remoteMessage.getData().get("lecture_date");
            String web_url = remoteMessage.getData().get("web_url");

            if(lectureDate != null)sendLecturesNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody(), lectureDate);
            else if(web_url != null) sendNotificationWithURL(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody(), web_url);
            else Log.e(TAG, "Message.notification is empty!");
        }
    }

    @Override
    public void onNewToken(@NonNull String token) {
        Log.d(TAG, "Refreshed token: " + token);
    }

    private void sendLecturesNotification(String title,String messageBody, String date) {

        Intent intent;
        intent = new Intent(this, Lectures_graph.class).putExtra("lecture_date", date).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, ((int) System.currentTimeMillis()) /* Request code */, intent,
                0);

        String channelId = getString(R.string.lectures_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.secret)
                        .setContentTitle(title)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

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

        if (notificationManager != null) {
            notificationManager.notify(((int) System.currentTimeMillis()), notificationBuilder.build());
        }

        Log.d(TAG, "Lectures notification built with date:"+date);
    }

    private void sendNotificationWithURL(String title, String messageBody, String web_url) {

        Intent intent;
        intent = new Intent(this, webview_base.class).putExtra("web_url", web_url).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, ((int) System.currentTimeMillis()) /* Request code */, intent,
                0);

        String channelId = getString(R.string.newsfeed_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.secret)
                        .setContentTitle(title)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

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

        if (notificationManager != null) {
            notificationManager.notify(((int) System.currentTimeMillis()), notificationBuilder.build());
        }

        Log.d(TAG, "Webview notification built with URL:"+web_url);
    }
}

不久前,我在 logcat 中收到一个错误,上面写着“未定义默认 FCM 通道”,但我不太确定这就是问题所在。

即使我搜索了整个 web,我也希望在应用程序被终止时看到更好的通知(及其有效负载)处理解决方案/建议。

所以我解决了我的噩梦,方法如下:

既然我不能从通知中打开多个特定活动,为什么我只能打开我的应用程序主 class 并从那里处理额外的变量?

而不是每个想要的活动

   <intent-filter>
        <action android:name="OPEN_ACTIVITY_???????" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>

我做的:

<activity
        android:name=".MainActivity"
        android:launchMode="singleTask"
        android:configChanges="orientation|keyboardHidden|screenSize">
    <intent-filter>
        <action android:name="OPEN_APP" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    </activity>

我在通知负载中添加了额外的变量(例如:'activity' => 'webview')并在我的 PHP 代码中重命名了 click_action。 我在 MainActivity.class 中处理了所有有效负载,并从那里调用了想要的 android 活动。 主要活动代码:

Bundle extras = getIntent().getExtras();
        if(extras == null) {
            Log.e("MainActivity", "No Activities passed in notification extras");
        } else {
            //get opening activity from notification payload
            String activity = extras.getString("activity");
            if( activity != null){
                switch (activity){
                    //webview activity
                    case "webview":
                        //gets url for webview
                        String web_url = extras.getString("web_url");
                        if(web_url != null){
                            finish();
                            startActivity(new Intent(this, webview_base.class).putExtra("web_url", web_url));
                        }
                        break;
                    //lectures activity
                    case "lectures":
                        //gets lecture date
                        String lecture_date = extras.getString("lecture_date");
                        if(lecture_date != null){
                            finish();
                            startActivity(new Intent(this, Lectures_graph.class).putExtra("lecture_date", lecture_date));
                        }
                        break;
                }
            }
        }

希望这对某人有所帮助,有一天..

干杯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM