我遵循了一些关于自定义服务在应用程序处于后台或被杀死(包括 Xamarin 的)时运行的教程,但我自己没能成功。
我假装的:
1- Firebase 服务向设备发送通知。 此服务确实在后台/被杀死时工作
2- 我的自定义服务必须执行一个小功能只要fcm 服务执行。特别是如果应用程序在后台/被杀死。 如果应用程序在前台运行,我的服务会运行。
有人能指出我哪里失败了吗? (或者帮助我了解更好的后台服务?)
到目前为止我的代码:
定制服务
using Android.App;
using Android.Content;
using Android.OS;
using Android.Util;
using ME.Leolin.Shortcutbadger;
namespace App1
{
[Service]
public class Badge_Service : Service
{
int n = 0;
public IBinder Binder { get; private set; }
public override IBinder OnBind(Intent intent)
{
Log.Debug("SS", "OnBind");
this.Binder = new Badge_Binder(this);
add_up(n); //custom function
return this.Binder;
}
public override bool StopService(Intent name)
{
return base.StopService(name);
}
public void add_up(int count)
{
count++;
ShortcutBadger.ApplyCount(ApplicationContext, count);
}
}
public class Badge_Binder : Binder
{
public Badge_Service Service { get; private set; }
public Badge_Binder(Badge_Service Service)
{
this.Service = Service;
}
}
public class Badge_Conection : Java.Lang.Object, IServiceConnection
{
MyFirebaseMessagingService activity;
public bool IsConnected { get; private set; }
public Badge_Binder Binder { get; private set; }
public Badge_Conection(MyFirebaseMessagingService activity)
{
IsConnected = false;
Binder = null;
this.activity = activity;
}
public void OnServiceDisconnected(ComponentName name)
{
Log.Debug("SS", "Disconnected");
IsConnected = false;
Binder = null;
}
public void OnServiceConnected(ComponentName name, IBinder Service)
{
Binder = Service as Badge_Binder;
IsConnected = this.Binder != null;
Log.Info("SS", "Connected");
}
}
}
Firebase 实现
using Android.App;
using Android.Content;
using Firebase.Iid;
using Android.Support.V7.App;
using Android.Media;
using Firebase.Messaging;
namespace App1
{
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseServices : FirebaseInstanceIdService
{
public override void OnTokenRefresh()
{
base.OnTokenRefresh();
MClass.IDfcm = FirebaseInstanceId.Instance.Token; //MClass just stores variables for later use.
Android.Util.Log.Debug("Refreshed Token:", MClass.IDfcm);
}
}
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
public override void OnMessageReceived(RemoteMessage msg)
{
base.OnMessageReceived(msg);
sendNotification(msg.GetNotification().Body);
Intent serviceToStart = new Intent(this, typeof(Badge_Service));
BindService(serviceToStart, new Badge_Conection(this), Bind.AutoCreate);
}
private void sendNotification(string msg)
{
var activity = new Intent(this, typeof(LogIn)); //LogIn is my MainActivity
activity.AddFlags(ActivityFlags.ClearTop);
var screen = PendingIntent.GetActivity(this, 0, activity, PendingIntentFlags.OneShot);
var sound = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
var notif = new NotificationCompat.Builder(this)
.SetSmallIcon(Resource.Drawable.Icon)
.SetContentTitle("New Notification")
.SetContentText(msg)
.SetAutoCancel(true)
.SetSound(sound)
.SetContentIntent(screen);
var controller = NotificationManager.FromContext(this);
controller.Notify(0, notif.Build());
}
}
}
最佳答案
我前段时间解决了我的问题,因为我看到没有其他人回答过它,我会发布我的解决方案以防其他人遇到这个问题:
失败很简单,因为从未在后台调用 OnMessageReceived。我通过使用 HandleIntent 绕过了这个问题,这使得我的后台服务变得不必要,如下所示:(类是相同的):
public override void HandleIntent(Intent intent)
{
string msg = intent.GetStringExtra("body");
if (msg == null) msg = "New Notification";
ShortcutBadger.ApplyCount(this, Global.countNotifications());
sendNotification(msg);
}
额外说明
HandleIntent 不能使用 RemoteMessage 类型,因此(如果我没记错的话)它无法检索通知的正文。
需要一个自定义通知发送者,以便能够手动检索正文作为 json。
这就是我构建自己的方式:
(警告:代码可能不是那么整洁。我到了用脑袋敲击键盘的阶段 D:):
public static string signalFCM(string msg, string user_firebase_id) //This must be gathered by storing a firebase_id created by an android device.
{
try
{
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = user_firebase_id,
notification = new // *** THIS IS HOW FIREBASE SENDS THEM BY DEFAULT
{
body = msg,
title = "MyAPP",
sound = "Enabled"
},
// **** THIS IS THE CUSTOM EXTRA TO RETRIEVE ITS CONTENT ****
data = new
{
body = msg,
title = "MyAPP",
payload = "1"
}
// ******************
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", APP_KEY)); //This must be gathered from the Firebase Console APP page
tRequest.Headers.Add(string.Format("Sender: id={0}", APP_ID)); //This must be gathered from the Firebase Console APP page
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
return sResponseFromServer;
}
}
}
}
}
catch (Exception ex) { return ex.Message; }
}
}
关于c# - Xamarin 安卓后台服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47291492/