首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当app被关闭时,还没有收到xamarin android定制推送通知

问当app被关闭时,还没有收到xamarin android定制推送通知
EN

Stack Overflow用户
提问于 2018-04-30 08:57:41
回答 2查看 1.2K关注 0票数 0

到目前为止,我有一个问题让这个设置完全正常运行:

1)创建了蔚蓝通知中心,并安装了ios apn和firebase fcm。

2)将代码添加到ios和android中的xamarin forms应用程序中,以便使用模板接收定制的推送通知。

3)模板版本在ios (杀灭应用程序、后台和前台)接收通知时工作100%。

4)在xamarin上,android实现了前台和后台的协同工作,实现了定制推送通知,并对其进行了处理。

问题:我无法让xamarin显示(在托盘中),甚至不能将定制的推送通知与我的应用程序联系起来。这是我的问题,我找不到办法做这件事?任何帮助的人都很感激。

我的定制模板:

代码语言:javascript
复制
string templateBodyAPNS = "{"data":{"message":"$(titleParam)","name":"$(bodyParam)","image":"$(imageParam)","url":"$(urlParam)"}}";

注意事项:我删除了上述代码中的\“以使其更易读

在所有场景中都很好,但当android应用程序被杀死时,我什么也没有得到。

EN

回答 2

Stack Overflow用户

发布于 2018-04-30 12:27:45

您需要使用Firebase JobDispatcher。您可以找到一些信息这里,并这里的代码。基本上,在可能的时候,保持一个服务来运行它,即使当应用程序被杀死时也是如此。

它的工作方式如下:

这是在FirebaseService中声明的manifest

代码语言:javascript
复制
<service android:name=".services.FirebaseCloudMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

以及执行情况:

代码语言:javascript
复制
public class FirebaseCloudMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Map<String, String> data = remoteMessage.getData();
        Log.i("PUSH", data.toString());
        if (ApplicationContextProvider.isInBackground()) {
            //***********************
            //This is the most important portion of code
            FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(getApplicationContext()));
            Job myJob = dispatcher.newJobBuilder()
                .setService(SyncAppInBackgroundService.class) // the JobService that will be called
                .setTag("my-unique-tag")        // uniquely identifies the job
                .build();

            dispatcher.mustSchedule(myJob);
            //***********************
        } else {
            // This code manage the PushNotification when the user is in the app
            int notificationType = Integer.valueOf(data.get("type"));
            switch (notificationType) {
                case Constants.PushNotification.TYPE_NEW_MESSAGE:
                case Constants.PushNotification.TYPE_CHECK_MESSAGE:
                    if (Chat.TABLE.getByServerId(Long.valueOf(data.get("idChat"))) != null) {
                        new SyncAppHandler(null).execute(SyncAppHandler.SynchronizeTaskType.SynchronizeTaskTypeMessages);
                        break;
                    }
                case Constants.PushNotification.TYPE_NEW_GROUP:
                case Constants.PushNotification.TYPE_EDIT_CHAT_USER:
                    new SyncAppHandler(null).execute(SyncAppHandler.SynchronizeTaskType.SynchronizeTaskTypeChats);
                    break;
            }
        }
    }
}

现在,我们需要创建一个计划好的JobService:

代码语言:javascript
复制
public class SyncAppInBackgroundService extends JobService implements SyncAppDelegate {

    private JobParameters params;

    private SyncAppHandler syncAppHandler;
    private SynchronizeTaskType lastTask = SynchronizeTaskType.SynchronizeTaskTypeLogin;

    @Override
    public boolean onStartJob(JobParameters job) {
        // Do some work here
        params = job;
        syncAppHandler = new SyncAppHandler(this);
        syncAppHandler.execute(lastTask);
        return true; // Answers the question: "Is there still work going on?"
    }

    @Override
    public boolean onStopJob(JobParameters job) {
        return true;// Answers the question: "Should this job be retried?"
    }

    @Override
    public void didFinishExecutingTaskWithResult(SynchronizeTaskType type, int result) {
        //handle the sync and if you finished, call:
        jobFinished(params, true);
    }
}

不要把它添加到清单中:

代码语言:javascript
复制
<service
    android:name=".services.SyncAppInBackgroundService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
    </intent-filter>
</service>

现在您所需要的就是创建您的SyncAppHandler。这个类是我的,不要扩展任何android或库类。只需在那里实现您的业务代码或协商来同步。

额外:

我的方法是问应用程序是否在后台。返回false只有当应用程序在前台,所有其他情况,如手机锁定,应用程序被杀.返回true。

代码语言:javascript
复制
public static boolean isInBackground() {
    RunningAppProcessInfo myProcess = new RunningAppProcessInfo();
    ActivityManager.getMyMemoryState(myProcess);
    if (myProcess.importance != RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
        return true;

    KeyguardManager keyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
    return keyguardManager.inKeyguardRestrictedInputMode(); // app is in foreground, but if screen is locked show notification anyway
}
票数 0
EN

Stack Overflow用户

发布于 2018-04-30 12:59:36

这段代码可以帮助您实现类似于Firebase JobDispacher的东西。

这个例子是关于GCM的,但是这里最重要的是WakefulBroadcastReceiver。

代码语言:javascript
复制
using Android.Support.V4.Content;
using Android.Content;
using Android.App;

[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]

namespace PushNotification.Droid {
    [BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")]
    [IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { Intent.ActionBootCompleted })]
    public class WakefulReceiver : WakefulBroadcastReceiver {
        public override void OnReceive(Context context, Intent intent) {
            StartWakefulService(context, intent);
        }
    }
}

如果应用程序被杀死,WakefulBroadcastReceiver可以运行一个IntentService。因此,当您收到PushNotification时,您可以这样处理它:

代码语言:javascript
复制
using System;
using Android.App;
using Android.Content;
using Android.Support.V4.Content;

namespace PushNotification.Droid {
    [Service(Exported = false), IntentFilter(new[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    public class GCMNotificationIntentService : IntentService {
        public GCMNotificationIntentService() { }

        protected override void OnHandleIntent(Intent intent) {
            try {
                //I try to handle my push notification
                HandlePushNotification(ApplicationContext, intent);
            } finally {
                // But always run my intent with wakeful receiver
                // To ensure that it will be done
                WakefulReceiver.CompleteWakefulIntent(intent);
            }
        }


        private void HandlePushNotification(Context context, Intent intent) {
            Intent notificationReceived = new Intent(PushEventCenter.EVENT_NAMES.PUSH_NOTIFICATION_RECEIVED);
            foreach (String key in intent.Extras.KeySet()) {
                notificationReceived.PutExtra(key, intent.Extras.GetString(key));
            }
            LocalBroadcastManager.GetInstance(this).SendBroadcast(notificationReceived);
        }
    }
}

从API 26开始,WakefulBroadcastReceiver就不再受欢迎了,但它为您提供了一个关于如何确保在我的应用程序不在前台时执行我的代码的想法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50097159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档