gpt4 book ai didi

java - 适用于 Android 的 Azure 通知中心 : How do I handle Data-Messages with a Background-Service?

转载 作者:行者123 更新时间:2023-12-04 23:59:03 28 4
gpt4 key购买 nike

我正在尝试制作一个能够处理 Azure 通知中心发送的(数据)消息的应用程序。在当前状态下,它会在 Azure 接收有效负载时发送通知。当应用程序在前台运行(或仍然在快速面板中打开)时,它完全没有问题,并且 onPushNotificationReceived() 可以很好地处理传入消息,但是当从快速面板中删除应用程序时我在尝试调用空对象引用时收到错误:

<小时/>
Logcat
2021-07-22 15:27:33.675 23017-23053/com.example.fcmtutorial1app E/AndroidRuntime: FATAL EXCEPTION: Firebase-Messaging-Intent-Handle
Process: com.example.fcmtutorial1app, PID: 23017
java.lang.NullPointerException: Attempt to invoke interface method 'void com.microsoft.windowsazure.messaging.notificationhubs.NotificationListener.onPushNotificationReceived(android.content.Context, com.google.firebase.messaging.RemoteMessage)' on a null object reference
at com.microsoft.windowsazure.messaging.notificationhubs.FirebaseReceiver.onMessageReceived(FirebaseReceiver.java:52)
at com.google.firebase.messaging.FirebaseMessagingService.dispatchMessage(com.google.firebase:firebase-messaging@@22.0.0:13)
at com.google.firebase.messaging.FirebaseMessagingService.passMessageIntentToSdk(com.google.firebase:firebase-messaging@@22.0.0:8)
at com.google.firebase.messaging.FirebaseMessagingService.handleMessageIntent(com.google.firebase:firebase-messaging@@22.0.0:3)
at com.google.firebase.messaging.FirebaseMessagingService.handleIntent(com.google.firebase:firebase-messaging@@22.0.0:3)
at com.google.firebase.messaging.EnhancedIntentService.lambda$processIntent$0$EnhancedIntentService(com.google.firebase:firebase-messaging@@22.0.0:1)
at com.google.firebase.messaging.EnhancedIntentService$$Lambda$0.run(Unknown Source:6)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:6)
at java.lang.Thread.run(Thread.java:923)

这只在发送数据消息时发生,因为 Firebase 服务处理带有通知负载的消息,而不调用 onPushNotificationReceived()

<小时/>

我已尝试以下方法来解决此问题:

  • 使用 android.app.Service 扩展 CustomNotificationListener.class
  • 用 Thunderbirds onMessageReceived() 替换 onPushNotificationReceived()

第一个解决方案导致相同的错误,第二个解决方案根本没有任何消息。

如果有人有办法解决这个问题或者知道可能出了什么问题,如果你能写下答案,我会很高兴:)

这是两个类的代码(仍然包含 android.app.Service,尽管它对我不起作用)。提前致谢!

<小时/>
MainActivity.class
package com.example.fcmtutorial1app;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import com.microsoft.windowsazure.messaging.notificationhubs.NotificationHub;

public class MainActivity extends AppCompatActivity
{
public static final String CHANNEL_1_ID = "Channel1";
public static final String CHANNEL_2_ID = "Channel2";

public static String editTextTitle;
public static String editTextMessage;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

createNotificationsChannels();

NotificationHub.setListener(new CustomNotificationListener());
NotificationHub.start(this.getApplication(), "spfcmtutorial1nhub", "Endpoint=sb://azurecloudmessaging.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=abc[...]xyz");
}

public static void sendCloudMessage(Context context)
{
editTextTitle = CustomNotificationListener.title;
editTextMessage = CustomNotificationListener.body;

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(editTextTitle)
.setContentText(editTextMessage)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE);

NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());

Log.v("MSG", "SENDCLOUDMESSAGE WAS ACTIVATED");
}

public void createNotificationsChannels() //Channel 2 is for tests only
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel1 = new NotificationChannel(
CHANNEL_1_ID,
"Channel 1",
NotificationManager.IMPORTANCE_HIGH
);
channel1.setDescription("This is Channel 1");

NotificationChannel channel2 = new NotificationChannel(
CHANNEL_2_ID,
"Channel 2",
NotificationManager.IMPORTANCE_LOW
);
channel2.setDescription("This is Channel 2");

NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel1);
manager.createNotificationChannel(channel2);
}
}
}
<小时/>
CustomNotificationListener.class
package com.example.fcmtutorial1app;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import com.google.firebase.messaging.RemoteMessage;
import com.microsoft.windowsazure.messaging.notificationhubs.NotificationListener;
import java.util.Map;

public class CustomNotificationListener extends Service implements NotificationListener
{
private static final String TAG = "Message";

public static String title;
public static String body;
public static String dataTitle;
public static String dataBody;

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "Service started");
return Service.START_NOT_STICKY;
}

@Override
public void onPushNotificationReceived(Context context, RemoteMessage message) //FATAL EXEPTION: Firebase-Messaging-Intent-Handle HERE
{
RemoteMessage.Notification notification = message.getNotification();

try { title = notification.getTitle(); } catch(Exception e) {}
try { body = notification.getBody(); } catch (Exception e) {}

Map<String, String> data = message.getData();

//region LOGGING
if (message != null)
{
Log.d(TAG, "Message Notification Title: " + title);
Log.d(TAG, "Message Notification Body: " + body);
}
else { Log.e(TAG, "ERROR, no message found"); }

if (data != null)
{
for (Map.Entry<String, String> entry : data.entrySet())
{
Log.d(TAG, "key, " + entry.getKey() + "value " + entry.getValue());
}
}
else { Log.e(TAG, "ERROR, no data found"); }
//endregion

Log.v("VERBOSE", data.get("property1"));

MainActivity.sendCloudMessage(context);
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<小时/>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fcmtutorial1app">

<application
android:allowBackup="true"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FCMTutorial1App">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".CustomNotificationListener"></service>
</application>

</manifest>
<小时/>

最佳答案

为了回答这个问题,我们需要讨论一些 Android 生命周期概念,如 https://developer.android.com 中所述。 :

在上面提供的代码中,您在应用程序的主入口点 MainActivity 中调用 NotificationHub.setListener。如您所见,当您的最终用户手动启动应用程序时,这会起作用,因为 MainActivity.onCreate 被调用。

但是,您的场景中还有第二个入口点:FirebaseMessagingService 在后台收到纯数据通知时启动应用程序。这是微妙且容易被忽略的 - 因为如果有效负载包含 notification 组件,当在系统托盘中单击通知时,Android 仍会路由到 MainActivity

在这种情况下,不涉及 MainActivity,因此在应用程序初始化时不会调用 MainActivity.onCreateNotificationHub.setListener,并且following line from the stack trace遇到空引用:

mHub.getInstanceListener().onPushNotificationReceived(this.getApplicationContext(), remoteMessage);

要解决此问题,您需要在某个地方调用 NotificationHub.setListener,无论入口点如何,该函数都会在应用程序初始化时调用。

最自然的选择是通过扩展 android.app.Application 在应用程序级别设置NotificationHub,覆盖 onCreate() method ,和updating your manifest .

关于java - 适用于 Android 的 Azure 通知中心 : How do I handle Data-Messages with a Background-Service?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68486780/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com