Forum Xamarin.Android

Class extends BroadcastReceiver with custom event doesn't work

CortezCortez USMember ✭✭✭

Hello!

Again me. I found a strange problem. Is it possible, that i miss something but i can't solve the problem.

I created a service. This service only get my current GPS position every 1 minute. I found one working method to update UI with this Position from service: Send broadcast message. If i get the position i send to broadcast:
Intent broadcastIntent = new Intent("NewCoordinate"); broadcastIntent.PutExtra("Latitude", Location.Latitude); broadcastIntent.PutExtra("Longitude", Location.Longitude); SendBroadcast(broadcastIntent);

It is working very well, i can catch it in another class or any other other class as i want. In the Main activity i can't catch this broadcast message because the class needs to extends with "BroadcastReceiver" and the Main class already extends the "Activity". Ok then i created a class that extends with "BroadcastReceiver". And then i send this position back to the Main with an Event. On the Main class i get this position and add in the listview. But the event is everytime null.

PositionListener
[BroadcastReceiver] [IntentFilter (new[] {"NewCoordinate"})] class PositionListener : BroadcastListener { public override void OnReceive(Context context, Intent intent) { if(intent.Action == "NewCoordinate") { RefreshPositionsEvent(intent.GetDoubleExtra("Latitude",0), intent.GetDoubleExtra("Longitude",0)); //NullReferenceException } } }

Main
`
PositionAdapter positionAdapter;
...
PositionListener posListener = new PositionListener();
posListener.RefreshPositionsEvent += () =>
{
RunOnUiThread(() =>
{
positionAdapter.NotifyDataSetChanged();
});
}

positionAdapter = new PositionAdapter(this, Resource.Layout.PositionListItem, posListener.Positions);
lvPositions.Adapter = positionAdapter;
`

I know that the positionAdapter is null when i initialize the posListener instance but when i want to initialize the positionAdapter first, the posListener's Positions property is not available yet.

Strange situation, but i don't know the proper way to connect the posListener with positionAdapter. They need eachother. The posListener needs to notify the positionAdapter to data set changed but the positionListener needs the posListener's Positions too.

Anyway. I got NullReferenceException when i call the event in the PositionListener class.
posListener.RefreshPositionsEvent += () =>

On this row the debug prompt always green, not yellow as normally. The debugger stay on this row when i want to step to the next row more time with green color. I think this is a sign.

Answers

  • CortezCortez USMember ✭✭✭

    PositionListener
    [BroadcastReceiver] [IntentFilter (new[] {"NewCoordinate"})] class PositionListener : BroadcastListener { public override void OnReceive(Context context, Intent intent) { if(intent.Action == "NewCoordinate") { RefreshPositionsEvent( intent.GetDoubleExtra("Latitude",0), intent.GetDoubleExtra("Longitude",0)); //NullReferenceException } } }

    Main
    `PositionAdapter positionAdapter;
    ...
    PositionListener posListener = new PositionListener();
    posListener.RefreshPositionsEvent += () =>
    {
    RunOnUiThread(() =>
    {
    positionAdapter.NotifyDataSetChanged();
    });
    }

    positionAdapter = new PositionAdapter(this, Resource.Layout.PositionListItem, posListener.Positions); lvPositions.Adapter = positionAdapter;`

  • FZelleFZelle DEMember ✭✭✭

    Very easy to implement with https://github.com/grumpydev/TinyMessenger instead of the Broadcastlistener

  • CortezCortez USMember ✭✭✭

    I found it very complex at the first. Can you explain it? How it is work? It is working like BroadcastSend/Receive. I send a message with this TinyMessenger from Service to PositionListener class. The TinyMessenger.cs file i just need to copy into my project and use it like in the .Tests ?

  • CortezCortez USMember ✭✭✭

    I try to update the adapter from another place. I definied a Timer in Main and after 10 sec elapsed in the Elapsed event i call the adapter.NotifyDataSetChanged(). But the new list item not showed in the listview. The Position's FillView(View v) didn't called. This problem again.

  • FZelleFZelle DEMember ✭✭✭

    It's not really that complex.

    You need to use the same TinyMessenger ( that's what an IOC like TinyIOC is for ) and then use my_messenger.subscribe on the listener side and my_messenger.publish on the sending side.

    You call the NotifyDataSetChanged from the UI Thread?
    Timer most of the time are running in their own thread.

  • CortezCortez USMember ✭✭✭

    Yes i placed the NotifyDataSetChanged in RunOnUiThread. It happens before. But the compiler notitfy me with exception than. I think something missed or wrong definied. But i created some ListView - ArrayAdapter - DataSource connections. And i checked more the code and nothing. But i like to use this broadcastsending. In a future project i will try this TinyMessenger. I am using the BroadcastSending first. Both of them could be the first time to use.

  • FZelleFZelle DEMember ✭✭✭

    Compiler gives an exception?

  • CortezCortez USMember ✭✭✭

    Nop. I would be happy if i receive an exception because i know that wher is the problem. But now. I didn't get exception but the information don't appear in the listview. The GetView method not called. The event problem is ok. With a timer i can refresh the listview.

  • CortezCortez USMember ✭✭✭

    In the same project on another layout i have a listview too. There i use a custom listview item(checkbox with textview) and there is working. Ok but by the initialize i have the list already. Not need add items and notifty the adapter. But its working.

  • CortezCortez USMember ✭✭✭

    It is working now, what i explained in another topic. Before the class name i setted two attributes: [BroadcastReceiver] [IntentFilter (new [] {"NewCoordinate"})]. The broadcast message catched but the event was always null. When i deleted the two attributes and register it myself it is solved my problem. Before i give for this class the main activity's reference and try to call the method directly through the instance. In the constructor it wasn't null but in my OnReceive() method was, as by the event.

Sign In or Register to comment.