BroadcastReceiver 不接收广播

BroadcastReceiver does not receive broadcast

我的 BroadcastReceiver 没有收到任何东西。很可能是我的设置错误,因为我找不到任何好的例子。我需要我的接收器在我的 MainActivity 中接收一些东西,并更改一个视图。我在一个 Android 项目中有几乎相同的代码,它在这里工作,但是 BroadcastReceivers 在 Xamarin 中的实现似乎有点不同(在 Android 中,我可以制作一个新的 BroadcastReceiver 几乎就像一个对象,但在 Xamarin 或 C# 中,似乎我必须自己创建 class,因此没有相同的可能性直接引用视图)。如果我让它工作,我也会 post 为每个人提供一个完整的工作示例。

以下是我尝试设置它的方法:

[Activity(Label = "GetLocation.Droid", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    Button button;
    protected override void OnCreate(Bundle bundle)
    {
        // ... various OnCreate() code

        LocationBroadcastReciever lbr = new LocationBroadcastReciever();
        RegisterReceiver(lbr, new IntentFilter("test"));

    }

    public void SetButtonText(string text)
    {
        button.Text = text;
    }
}

[BroadcastReceiver]
public class LocationBroadcastReciever : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        /* My program never get this far, so I have not been able
           to confirm if the bellow code works or not (its from
           another example I saw). */
        //EDIT: It does NOT work. See my answer for a working example
        string text = intent.GetStringExtra("title");
        ((MainActivity)context).SetButtonText(text);
        InvokeAbortBroadcast();
    }
}

在我的 IntentService 中,我有这个实际运行的方法,但从未到达我的接收器。

    private void SendBroadcast(double lat, double lng, string activity)
    {
        Intent intent = new Intent("test");
        intent.PutExtra("title", "Updated");
        LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
    }

这与我在工作中使用的代码几乎相同 Android(只是调整了 BroadcastReceiver 并进行了一些小的调整以使其编译)。

谁能看出哪里出了问题??

编辑 终于让这一切工作。您可以查看我的完整示例答案。

几件事:

首先,您需要接收器上的 [IntentFilter]。所以它应该看起来像....

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new [] { "test" })]
public class LocationBroadcastReciever : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        /* My program never get this far, so I have not been able
           to confirm if the bellow code works or not (its from
           another example I saw). */
        string text = intent.GetStringExtra("title");
        ((MainActivity)context).SetButtonText(text);
        InvokeAbortBroadcast();
    }
}

这应该可以解决您的问题。

其次,您应该注册和取消注册接收者。因此,您应该在 OnResume 中注册并在 OnPause 中注销。

[Activity(Label = "GetLocation.Droid", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    LocationBroadcastReciever _lbr;
    Button button;

    protected override void OnCreate(Bundle bundle)
    {
        // ... various OnCreate() code
    }

    protected override void OnResume()
    {
        base.OnResume();
        _lbr = new LocationBroadcastReciever();
        RegisterReceiver(lbr, new IntentFilter("test"));
    }

    protected override void OnPause()
    {
        UnregisterReceiver(_lbr);
        base.OnPause();
    }

    public void SetButtonText(string text)
    {
        button.Text = text;
    }
}

注意:这些更改是我看到的您的代码和我的工作广播接收器代码之间的不同之处。我的改变是否必要,我不完全确定。

本地

您将接收器注册为全局,但通过 LocalBroadcastManager 发送意图。如果你想使用这个管理器,你应该像这样注册你的接收器:

LocalBroadcastManager.GetInstance(this).RegisterReceiver(lbr, filter);

您可以找到更多关于 LocalBroadcastManager here


全球

或者如果你想使用全局广播,你应该按类型创建意图:

var intent = new Intent(this, typeof(LocationBroadcastReciever));

并通过 android Context 发送(在您的服务中):

this.SendBroadcast(intent);

您也可以将 intent 与 action 结合使用,但它需要接收器上的 IntentFilter 属性:

[IntentFilter(new []{ "test" })]
[BroadcastReceiver]
public class LocationBroadcastReciever : BroadcastReceiver { ... }

为了将来的搜索结果,这里是我的代码的一个干净示例,其中包含一个有效的 BroadcastReceiver

// ** MainActivity
namespace GetLocation.Droid
{
    [Activity(Label = "GetLocation.Droid", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        //I initialize my view(s) here to access them from outside of OnCreate().
        Button button;
        //I found this in an Android BroadcastReceiver example of how to access the MainActivity from the BroadcastReceiver.
        private static MainActivity ins;
        public static MainActivity getInstace()
        {
            return ins;
        }
        protected override void OnCreate(Bundle bundle)
        {

            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            button = FindViewById<Button>(Resource.Id.myButton);
            ins = this;

            button.Click += delegate
            {
                Intent intent = new Intent(this, typeof(MyIntentService));
                StartService(intent);
            };

            LocationBroadcastReciever lbr = new LocationBroadcastReciever();
            LocalBroadcastManager.GetInstance(this).RegisterReceiver(lbr, new IntentFilter("test"));

        }

        public void SetButtonText(string text)
        {
            button.Text = text;
        }
    }

    [BroadcastReceiver]
    [IntentFilter(new[] { "test" })]
    public class LocationBroadcastReciever : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            string text = intent.GetStringExtra("title");
            MainActivity.getInstace().SetButtonText(text);
        }
    }
}

在我的 IntentService 中

namespace GetLocation.Droid
{
    [Service]
    [IntentFilter(new String[] { "com.mytos.MyIntentService" })]
    public class MyIntentService : IntentService
    {

        protected override void OnHandleIntent(Intent intent)
        {
            SendBroadcast("My message");
        }

        private void SendBroadcast(string message)
        {
            //Here you can of course send whatever variable you want. Mine is a string
            Intent intent = new Intent("test");
            intent.PutExtra("title", message);
            LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
        }
    }
}