Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当我的Xamarin Android应用程序停止时,我如何接收推送通知?_C#_Android_Firebase_Xamarin.forms_Firebase Cloud Messaging - Fatal编程技术网

C# 当我的Xamarin Android应用程序停止时,我如何接收推送通知?

C# 当我的Xamarin Android应用程序停止时,我如何接收推送通知?,c#,android,firebase,xamarin.forms,firebase-cloud-messaging,C#,Android,Firebase,Xamarin.forms,Firebase Cloud Messaging,我见过许多不同类型的解决方案,这些解决方案在过去可能有效,但没有一种对我有效。这是一个雷区,人们说什么有效,什么不起作用,什么已经改变,等等。但我试图找到一个解决方案,但希望能理解-因为现在我非常困惑 我现在可以做什么-我的Xamarin Forms应用程序(Android)可以接收推送通知,如果应用程序位于前台/后台,我还可以在用户点击这些通知时拦截这些通知,以便告诉我的应用程序该做什么 我想做的事基本上是上述内容,但处于应用程序完全停止的状态 我有连接到Azure通知中心的Firebas

我见过许多不同类型的解决方案,这些解决方案在过去可能有效,但没有一种对我有效。这是一个雷区,人们说什么有效,什么不起作用,什么已经改变,等等。但我试图找到一个解决方案,但希望能理解-因为现在我非常困惑


我现在可以做什么-我的Xamarin Forms应用程序(Android)可以接收推送通知,如果应用程序位于前台/后台,我还可以在用户点击这些通知时拦截这些通知,以便告诉我的应用程序该做什么

我想做的事基本上是上述内容,但处于应用程序完全停止的状态


我有连接到Azure通知中心的Firebase消息设置-不幸的是,我不会离开Azure(以防万一有人建议放弃它)。我目前掌握的大部分信息都是从各种Microsoft文档(我不使用AppCenter-只是用它来交叉引用任何有用的代码、、和)、其他StackOverflow问题(如、和-太多了,无法链接)和Xamarin论坛中拼凑而成的,所以,如果有任何过时的代码被使用(请让我知道-我已经尽力使用最新的方法,等等),我深表歉意

我发送的推送通知类型为数据消息,我在通知中使用自定义数据,因此我认为这是我要发送的正确推送类型,如下所示

{
    "data": {
        "title": "Title Test",
        "body": "Push notification body test",
        "area": "SelectedPage"
    }
}
下面是目前为止我在项目中设置的处理推送通知的代码

清单 使用
OnNewIntent
在用户与推送通知交互时拦截推送通知

MyFirebaseMessaging.cs
使用系统;
使用System.Threading.Tasks;
使用Android.App;
使用Android.Content;
使用Android.Support.V4.App;
使用Android.Util;
使用Firebase.Messaging;
使用PushTesting.Models;
使用WindowsAzure.Messaging;
命名空间PushTesting.Droid.Services{
[服务]
[IntentFilter(新[]{“com.google.firebase.MESSAGING_EVENT”}]
公共类OcsFirebaseMessaging:FirebaseMessagingService{
private const String NotificationChannelId=“1152”;
private const String NotificationChannelName=“推送通知”;
private const String NotificationChannelDescription=“接收通知”;
私人通知经理通知经理;
公共覆盖void OnNewToken(字符串令牌)=>SendTokenToAzure(令牌);
/// 
///将令牌发送到Azure,以便针对设备进行注册
/// 
私有void SendTokenToAzure(字符串令牌){
试一试{
NotificationHub hub=新建NotificationHub(Constants.AzureConstants.NotificationHub,Constants.AzureConstants.ListenConnectionString,Android.App.Application.Context);
Run(()=>hub.Register(令牌,新字符串[]{}));
}捕获(例外情况除外){
Log.Error(“Error”,$“错误注册设备:{ex.Message}”);
}
}
/// 
///当应用程序收到通知时,调用此方法
/// 
公共覆盖无效OnMessageReceived(RemoteMessage RemoteMessage){
Boolean Hasttle=remoteMessage.Data.TryGetValue(“标题”,输出字符串标题);
布尔hasBody=remoteMessage.Data.TryGetValue(“body”,输出字符串body);
Boolean hasArea=remoteMessage.Data.TryGetValue(“区域”,输出字符串区域);
布尔hasExtraInfo=remoteMessage.Data.TryGetValue(“extraInfo”,输出字符串extraInfo);
PushNotificationModel push=新的PushNotificationModel{
Title=Hasttle?Title:String.Empty,
Body=hasBody?Body:String.Empty,
Area=hasArea?Area:String.Empty,
ExtraInfo=hasExtraInfo?ExtraInfo:String.Empty
};
发送通知(推送);
}
/// 
///处理通知以确保更新通知管理器以提醒用户
/// 
私有void SendNotification(PushNotificationModel push){
//创建相关的不可重复Id,以允许在通知管理器中显示多个通知
Int32 notificationId=Int32.Parse(DateTime.Now.ToString(“mmddhhmmss”);
意向意向=新意向(此,类型为(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
意向性额外(“区域”,推送区域);
intent.PutExtra(“ExtraInfo”,push.ExtraInfo);
PendingEvent PendingEvent=PendingEvent.GetActivity(this,notificationId,intent,PendingEventFlags.UpdateCurrent);
notificationManager=(notificationManager)GetSystemService(Context.NotificationService);
//为运行Oreo(8.0.0)或更高版本的Android设备创建通知通道
if(Android.OS.Build.VERSION.SdkInt>=Android.OS.BuildVersionCodes.O){
NotificationChannel NotificationChannel=新建NotificationChannel(NotificationChannelId、NotificationChannelName、NotificationImportance.High){
Description=通知ChannelDescription
};
notificationManager.CreateNotificationChannel(notificationChannel);
}
//为通知管理器生成通知
Notification Notification=新建NotificationCompat.Builder(此为NotificationChannelId)
.SetSmallIcon(Resource.Drawable.ic_启动器)
.SetContentTitle(push.Title)
.SetContentText(push.Body)
.SetContentIntent(挂起内容)
.SetAutoCancel(真)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.pushtesting" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
    <application android:label="Push Testing">

        <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
        <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="${applicationId}" />
            </intent-filter>
        </receiver>

    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
protected override void OnNewIntent(Intent intent) {
    base.OnNewIntent(intent);

    String area = String.Empty;
    String extraInfo = String.Empty;

    if (intent.Extras != null) {
        foreach (String key in intent.Extras.KeySet()) {
            String value = intent.Extras.GetString(key);
            if (key == "Area" && !String.IsNullOrEmpty(value)) {
                area = value;
            } else if (key == "ExtraInfo" && !String.IsNullOrEmpty(value)) {
                extraInfo = value;
            }
        }
    }
    NavigationExtension.HandlePushNotificationNavigation(area, extraInfo);
}
using System;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.Support.V4.App;
using Android.Util;
using Firebase.Messaging;
using PushTesting.Models;
using WindowsAzure.Messaging;

namespace PushTesting.Droid.Services {

    [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class OcsFirebaseMessaging : FirebaseMessagingService {

        private const String NotificationChannelId = "1152";
        private const String NotificationChannelName = "Push Notifications";
        private const String NotificationChannelDescription = "Receive notifications";
        private NotificationManager notificationManager;

        public override void OnNewToken(String token) => SendTokenToAzure(token);

        /// <summary>
        /// Sends the token to Azure for registration against the device
        /// </summary>
        private void SendTokenToAzure(String token) {
            try {
                NotificationHub hub = new NotificationHub(Constants.AzureConstants.NotificationHub, Constants.AzureConstants.ListenConnectionString, Android.App.Application.Context);

                Task.Run(() => hub.Register(token, new String[] { }));
            } catch (Exception ex) {
                Log.Error("ERROR", $"Error registering device: {ex.Message}");
            }
        }

        /// <summary>
        /// When the app receives a notification, this method is called
        /// </summary>
        public override void OnMessageReceived(RemoteMessage remoteMessage) {
            Boolean hasTitle = remoteMessage.Data.TryGetValue("title", out String title);
            Boolean hasBody = remoteMessage.Data.TryGetValue("body", out String body);
            Boolean hasArea = remoteMessage.Data.TryGetValue("area", out String area);
            Boolean hasExtraInfo = remoteMessage.Data.TryGetValue("extraInfo", out String extraInfo);

            PushNotificationModel push = new PushNotificationModel {
                Title = hasTitle ? title : String.Empty,
                Body = hasBody ? body : String.Empty,
                Area = hasArea ? area : String.Empty,
                ExtraInfo = hasExtraInfo ? extraInfo : String.Empty
            };

            SendNotification(push);
        }

        /// <summary>
        /// Handles the notification to ensure the Notification manager is updated to alert the user
        /// </summary>
        private void SendNotification(PushNotificationModel push) {
            // Create relevant non-repeatable Id to allow multiple notifications to be displayed in the Notification Manager
            Int32 notificationId = Int32.Parse(DateTime.Now.ToString("MMddHHmmsss"));

            Intent intent = new Intent(this, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
            intent.PutExtra("Area", push.Area);
            intent.PutExtra("ExtraInfo", push.ExtraInfo);

            PendingIntent pendingIntent = PendingIntent.GetActivity(this, notificationId, intent, PendingIntentFlags.UpdateCurrent);
            notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);

            // Creates Notification Channel for Android devices running Oreo (8.0.0) or later
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O) {
                NotificationChannel notificationChannel = new NotificationChannel(NotificationChannelId, NotificationChannelName, NotificationImportance.High) {
                    Description = NotificationChannelDescription
                };

                notificationManager.CreateNotificationChannel(notificationChannel);
            }

            // Builds notification for Notification Manager
            Notification notification = new NotificationCompat.Builder(this, NotificationChannelId)
            .SetSmallIcon(Resource.Drawable.ic_launcher)
            .SetContentTitle(push.Title)
            .SetContentText(push.Body)
            .SetContentIntent(pendingIntent)
            .SetAutoCancel(true)
            .SetShowWhen(false)
            .Build();

            notificationManager.Notify(notificationId, notification);
        }
    }
}