Issue
I am following this tutorial to test out notification hub for android and it works https://docs.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm
but I need to finish the user registration process and get the userid so I can use the userid as tag to register on Azure Notification hub. So instead of doing the registration right away in MainAcitivty.cs
, I just save the token in database.
so instead of having this
public override void OnNewToken(string token)
{
Log.Debug(TAG, "FCM token: " + token);
SendRegistrationToServer(token);
}
i just insert the token to local database
public override void OnNewToken(string token)
{
Log.Debug(TAG, "FCM token: " + token);
LocalDb.InsertDeviceToken(token);
}
when the whole registration process is finished, I have following in an RegistrationAcitivty.cs
var notificationUtil = new NotificationUtil();
notificationUtil.SendRegistrationToServer(this.ApplicationContext);
following is the code for 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());
}
}
}
}
I can only guess that I am using the correct context object here, and when I run the code, i hit on following exception
{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)
}
the follow up tutorial - Send notifications to specific devices is not for xamarin android, so i am not sure how to do it in a correct way.
Solution
The NetworkOnMainThreadException
is the key, looking at the exception stack, the NotificationHub.Register
is your problem as it can not be performed on the UI thread due to the underlaying networks calls that happen, just execute it on a background thread.
Example:
~~~
Registration registration;
await Task.Run(() => registration = hub.Register(token, tags.ToArray()));
~~~
Answered By - SushiHangover
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.