Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BroadcastReceiver does not receive broadcast

My BroadcastReceiver does not receive anything. Most likely its my setup that is wrong, because I was not able to find any good examples on this. I need my receiver to receive something in my MainActivity, and change a View. I have almost the same code in an Android project, and here it is working, however BroadcastReceivers seems to be implemented a tiny bit differently in Xamarin (in Android, I can make a new BroadcastReceiver almost like an object, but in Xamarin, or C#, it seems I must make my own class and thus do not have the same possibilities to directly reference the views). If I get this to work, I will post a full working example for everyone too.

Here is how I have tried to set it up:

[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();
    }
}

And in my IntentService I have this method that actually runs, but never arrives at my receiver.

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

This is pretty much the same code as I have in my working Android (only tweaked the BroadcastReceiver and minor adjustments to make it compile).

Can anyone see whats wrong??

EDIT Finally got this whole thing to work. You can see my answer for a full, clean example.

like image 999
mathkid91 Avatar asked Jun 02 '16 13:06

mathkid91


2 Answers

Local

You register receiver as global, but send intents via LocalBroadcastManager. If you want to use this manager you should register your receiver like this:

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

You can find more about LocalBroadcastManager here.


Global

Or if you want to use global broadcasts, you should create intent by type:

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

and send it via android Context (in your service):

this.SendBroadcast(intent);

Also you can use intent with action, but it requires IntentFilter attribute on your receiver:

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

like image 62
Kirill Avatar answered Sep 21 '22 00:09

Kirill


For the sake of future search results, here is a clean example of my code with a working 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);
        }
    }
}

And in my 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);
        }
    }
}
like image 39
mathkid91 Avatar answered Sep 23 '22 00:09

mathkid91