android - xamarin android通知中心到特定设备

标签 android xamarin mono azure-notificationhub

我正在按照本教程测试 Android 的通知中心,它可以工作 https://learn.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm

但我需要完成用户注册过程并获取用户 ID,以便我可以使用用户 ID 作为标记在 Azure 通知中心进行注册。因此,我没有立即在 MainAcitivty.cs 中进行注册,而是将 token 保存在数据库中。

所以不要这样

public override void OnNewToken(string token)
        {
            Log.Debug(TAG, "FCM token: " + token);
            SendRegistrationToServer(token);
        }

我只是将 token 插入本地数据库

public override void OnNewToken(string token)
        {
            Log.Debug(TAG, "FCM token: " + token);
            LocalDb.InsertDeviceToken(token);
        }

当整个注册过程完成后,我在 RegistrationAcitivty.cs

 var notificationUtil = new NotificationUtil();
 notificationUtil.SendRegistrationToServer(this.ApplicationContext);

以下是NotificationUtil.cs的代码

using System;
using System.Collections.Generic;
using Android.Util;
using PantAppLib.source.dbaccess;
using PantAppLib.source.models;
using WindowsAzure.Messaging;

namespace PantAppAndroid.Utils
{
    public class NotificationUtil
    {
        public void SendRegistrationToServer(Android.Content.Context context)
        {
            try
            {
                // Register with Notification Hubs
                NotificationHub hub = new NotificationHub(Constants.NotificationHubName,
                                            Constants.ListenConnectionString, context);
                var userProfile = LocalDb.GetUserProfile();
                if (userProfile != null)
                {
                    var tags = new List<string>() { userProfile.Id };
                    var token = LocalDb.GetDeviceToken().TokenValue;
                    Registration registration = hub.Register(token, tags.ToArray());
                    var regID = registration.RegistrationId;

                    Log.Debug("MyFirebaseMsgService", $"Successful registration of ID {regID}");

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}

我只能猜测我在这里使用了正确的上下文对象,当我运行代码时,我遇到了以下异常

{Android.OS.NetworkOnMainThreadException: Exception of type 'Android.OS.NetworkOnMainThreadException' was thrown.
  at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <42748fcc36b74733af2d9940a8f3cc8e>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <42748fcc36b74733af2d9940a8f3cc8e>:0 
  at WindowsAzure.Messaging.NotificationHub.Register (System.String pnsHandle, System.String[] tags) [0x00043] in <7ef3a358b177460dacd73e56198bd8f2>:0 
  at PantAppAndroid.Utils.NotificationUtil.SendRegistrationToServer (Android.Content.Context context) [0x00041] in C:\Users\weiha\source\repos\App2\PantAppAndroid\Utils\NotificationUtil.cs:36 
  --- End of managed Android.OS.NetworkOnMainThreadException stack trace ---
android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
    at java.net.InetAddress.getAllByName(InetAddress.java:1154)
    at com.android.okhttp.Dns$1.lookup(Dns.java:39)
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:26)
    at com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:213)
    at com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:170)
    at com.microsoft.windowsazure.messaging.Connection.executeRequest(Connection.java:130)
    at com.microsoft.windowsazure.messaging.NotificationHub.refreshRegistrationInformation(NotificationHub.java:301)
    at com.microsoft.windowsazure.messaging.NotificationHub.registerInternal(NotificationHub.java:399)
    at com.microsoft.windowsazure.messaging.NotificationHub.register(NotificationHub.java:148)
    at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method)
    at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25885)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
}

后续教程 - Send notifications to specific devices不适用于 xamarin android,所以我不确定如何以正确的方式进行操作。

最佳答案

NetworkOnMainThreadException 是关键,查看异常堆栈,NotificationHub.Register 是您的问题,因为由于底层,它无法在 UI 线程上执行发生的网络调用,只需在后台线程上执行即可。

示例:

~~~
Registration registration;
await Task.Run(() => registration = hub.Register(token, tags.ToArray()));
~~~

关于android - xamarin android通知中心到特定设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64126994/

相关文章:

android - avd 管理器不显示 - 我没有使用 eclipse

android - 在 MoPub 中集成第三方广告网络

android - Azure 客户端 IServiceFilter 不起作用

service - Android 广播监听器中的 MvvmCross DataService

c# - ListView 顶部的堆栈布局 SCROLL

c# - 单声道 2.6.7 : Array Initializer Bug?

c# - Mono 开发中的构建错误

Android weightsum 没有按预期工作

.net - 我们可以将 mono 捆绑在我们的安装包中吗?

android - 检测触摸事件是否发生在 shapeDrawable 中