2016-06-02 5 views
4

My BroadcastReceiver ничего не получает. Скорее всего, моя настройка неправильная, потому что я не смог найти никаких хороших примеров. Мне нужен мой приемник, чтобы получить что-то в моей MainActivity и изменить вид. У меня почти такой же код в Android-проекте, и здесь он работает, однако BroadcastReceivers, похоже, немного отличается по-разному в Xamarin (в Android я могу сделать новый BroadcastReceiver почти как объект, но в Xamarin или C# , мне кажется, что я должен сделать свой собственный класс и, следовательно, не иметь одинаковых возможностей напрямую ссылаться на представления). Если я получу это для работы, я отправлю полный рабочий пример для всех тоже.BroadcastReceiver не принимает широковещательные сообщения

Вот как я попытался установить его:

[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 и незначительные изменения, чтобы сделать его компиляции).

Может ли кто-нибудь увидеть, что не так ???

EDIT Наконец-то получил все это для работы. Вы можете увидеть мой ответ на полный, чистый пример.

ответ

7

Local

Вы регистрируетесь приемник как глобальные, но отправить намерение через LocalBroadcastManager. Если вы хотите использовать этот менеджер, вы должны зарегистрировать приемник, как это:

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

Вы можете найти больше о LocalBroadcastManagerhere.


Global

Или, если вы хотите использовать глобальные трансляции, вы должны создать намерение по типу:

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

и отправить его с помощью андроида Context (в службе):

this.SendBroadcast(intent); 

Также вы можете использовать намерение с действием, но для этого требуется атрибут IntentFilter. Ваш приемник:

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

+0

Спасибо! Я не знал о местных и глобальных, а также пропускал IntentFilter на BroadcastReceiver, как предлагалось оба ответа. – mathkid91

+0

@ mathkid91, вы можете найти это сообщение интересным: http://codetheory.in/android-broadcast-receivers/ – g4s8

1

Пара вещей:

Во-первых, вам нужно [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; 
    } 
} 

Примечание: эти изменения являются тем, что я видел между кодом и кодом для рабочего приемника. Являются ли мои изменения необходимыми или нет, я не совсем уверен.

2

Ради будущих результатов поиска, вот чистый пример моего кода с рабочим 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); 
     } 
    } 
} 
+0

Если вы используете 'LocalBroadcastManager', вы можете удалить атрибуты BroadcastReceiver и IntentFilter из своего ресивера. Они необходимы только для глобальных передач. – g4s8

+0

@ g4s8 вы уверены? я думаю, что они необходимы, есть ли у вас какой-нибудь пример? – CDrosos

+0

@CDrosos, да, как вы можете видеть здесь. Https://developer.xamarin.com/api/type/Android.App.IntentFilterAttribute/ 'IntentFilterAttribute' генерирует элемент' намерение-фильтр' в 'AndroidManifest.xml'. Но 'LocalBroadcastManager' не требует фильтра намерения манифеста, вместо этого он требует фильтра в качестве аргумента для' registerReceiver (receiver, aimFilter) '. https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter) – g4s8

Смежные вопросы