如何在app未运行时将BroadcastReceiver与MvvmCross一起使用

时间:2015-02-10 21:18:05

标签: mvvmcross

我在Android应用程序中工作,我在使用带有MvvmCross的BroadcastReceiver时遇到了一些麻烦。我有广播来接收来自GCM(推送通知)的消息,然后创建一个IntentService,它会在收到消息时执行某些操作。

在我的IntentService中,我使用Mvx.Resolve来调用Core项目。由于应用程序未运行,因此会抛出一个未找到的异常(尝试使用Mvx.Resolve时)。

我尝试在网络上找到解决方案,我得到的最接近的是:How do I initialize the MvvmCross framework without a splash Activity?

所以我尝试使用它,但我收到了另一个例外。

Android.Content.ReceiverCallNotAllowedException: Exception of type 'Android.Content.ReceiverCallNotAllowedException' was thrown

我在尝试在另一个接收器内创建接收器时发现这种情况。

我的广播如下(使用上面堆栈中的代码):

[BroadcastReceiver(Permission= "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "MyPackage" }, Priority = (int)IntentFilterPriority.HighPriority)]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "MyPackage" }, Priority = (int)IntentFilterPriority.HighPriority)]
[IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "MyPackage" }, Priority = (int)IntentFilterPriority.HighPriority)]
public class GCMBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        var setup = MvxAndroidSetupSingleton.EnsureSingletonAvailable(context);
        setup.EnsureInitialized();

        GCMIntentService.RunIntentInService(context, intent);
        SetResult(Result.Ok, null, null);
    }
}

我的IntentService:

[Service]
public class GCMIntentService : IntentService
{
    static PowerManager.WakeLock sWakeLock;
    static object LOCK = new object();

    public static void RunIntentInService(Context context, Intent intent)
    {
        lock (LOCK)
        {
            if (sWakeLock == null)
            {
                // This is called from BroadcastReceiver, there is no init.
                var pm = PowerManager.FromContext(context);
                sWakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "GCM Broadcast Receiver");
            }
        }

        sWakeLock.Acquire();
        intent.SetClass(context, typeof(GCMIntentService));
        context.StartService(intent);
    }

    protected override void OnHandleIntent(Intent intent)
    {
        try
        {
            var context = this.ApplicationContext;
            var action = intent.Action;

            if (action.Equals("com.google.android.c2dm.intent.REGISTRATION"))
            {
                HandleRegistration(context, intent);
            }
            else if (action.Equals("com.google.android.c2dm.intent.RECEIVE"))
            {
                HandleMessage(context, intent);
            }
        }
        finally
        {
            lock (LOCK)
            {
                //Sanity check for null as this is a public method
                if(sWakeLock != null)
                {
                    sWakeLock.Release();
                }
            }
        }

    }

    private void HandleRegistration(Context context, Intent intent)
    {
        var registration = intent.GetStringExtra("registration_id"); 
        if(intent.GetStringExtra("error") != null)
        {
            // Registration failed, should try again later.
        }
        else if(intent.GetStringExtra("unregistered") != null)
        {
            // Unregistered
        }
        else if(registration != null)
        {
            //Do registration
        }
    }

    private void HandleMessage(Context context, Intent intent)
    {
        Task.Factory.StartNew(() =>
        {
            Mvx.Resolve<MyInterface>().DoSomething();
        });
    }
}

我读了相同的堆栈溢出,如果我只使用一个简单的Mvx.Resolve,那么我自己实例化它会更容易。问题是在我的方法“DoSomething”中它使用了更多的Mvx.Resolves而我不想因为Android而改变核心应用程序。

所以我想知道是否有任何方法可以启动框架,这样我就不必更改Core,或者处理这个问题的最佳方法是改变核心。

修改

异常跟踪是(我从logcat得到了这个,因为我无法调试未运行的应用程序):

Android.Content.ReceiverCallNotAllowedException: Exception of type 'Android.Content.ReceiverCallNotAllowedException' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0x00028>
at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x000c3>
at Android.Content.ContextWrapper.RegisterReceiver (Android.Content.BroadcastReceiver,Android.Content.IntentFilter) <0x0018f>
at Thrust.Plugins.Network.Droid.NetworkService.OnNetworkChanged (System.Action`1<Thrust.Plugins.Network.NetworkStatus>) <0x00093>
at Chat.Core.App.Initialize () <0x00533>
at Cirrious.MvvmCross.Platform.MvxSetup.CreateAndInitializeApp (Cirrious.CrossCore.Plugins.IMvxPluginManager) <0x0005b>
at Cirrious.MvvmCross.Platform.MvxSetup.InitializeApp (Cirrious.CrossCore.Plugins.IMvxPluginManager) <0x00027>
at Cirrious.MvvmCross.Platform.MvxSetup.InitializeSecondary () <0x00133>
at Cirrious.MvvmCross.Platform.MvxSetup.Initialize () <0x0002b>
at Cirrious.MvvmCross.Droid.Platform.MvxAndroidSetupSingleton.EnsureInitialized () <0x0011b>
at Chat.Droid.GCM.GCMBroadcastReceiver.OnReceive (Android.Content.Context,Android.Content.Intent) <0x0002b>
at Android.Content.BroadcastReceiver.n_OnReceive_Landroid_content_Context_Landroid_content_Intent_ (intptr,intptr,intptr,intptr) <0x0007b>
at (wrapper dynamic-method) object.0daa077c-c2f5-4cd5-bcbc-bc391ce0b2c3 (intptr,intptr,intptr,intptr) <0x0004b>
--- End of managed exception stack trace ---
android.content.ReceiverCallNotAllowedException: BroadcastReceiver components are not allowed to register to receive intents
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:246)
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:235)
at chat.droid.gcm.GCMBroadcastReceiver.n_onReceive(Native Method)
at chat.droid.gcm.GCMBroadcastReceiver.onReceive(GCMBroadcastReceiver.java:28)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2659)
at android.app.ActivityThread.access$1800(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1383)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
[ERROR] FATAL UNHANDLED EXCEPTION: Android.Content.ReceiverCallNotAllowedException: Exception of type 'Android.Content.ReceiverCallNotAllowedException' was thrown.

0 个答案:

没有答案