Bir yayın alıcısını programlı olarak kaydetme


149

Bir yayın alıcısını programlı olarak kaydetmenin en iyi yönteminin / yolunun ne olduğunu bilmek istiyorum. Kullanıcı tercihine göre belirli alıcıları kaydetmek istiyorum.

Kayıt manifest dosyası aracılığıyla yapıldığından, kodda bunu başarmak için uygun bir yol olup olmadığını merak ediyorum.


2
CoderzPassion Broadcast Reciever şimdiye kadarki en iyi ayrıntılı öğretici
karanatwal.github.io

Lütfen bu bağlantıya bakın stackoverflow.com/questions/15698790/…

Yanıtlar:


64

Manifestinizde yayınlanan bileşenlerin etkin olup olmadığını kontrol etmek istediğiniz gibi görünüyor, çalışırken dinamik olarak bir alıcı kaydetme (Context.registerReceiver () aracılığıyla).

Öyleyse, bu bileşenlerin etkin olup olmadığını kontrol etmek için PackageManager.setComponentEnabledSetting () yöntemini kullanabilirsiniz:

http://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)

Yalnızca yayın çalışırken yayın almakla ilgileniyorsanız, registerReceiver () yöntemini kullanmanın daha iyi olacağını unutmayın. Bir alıcı bileşeni, öncelikle yayın her gönderildiğinde uygulamanızın başlatılmasını sağlamak istediğinizde kullanışlıdır.


1
Zekice! Beni düzelttin. Çok teşekkür ederim
CoolStraw

Güzel bir - bunu yapabileceğine dair hiçbir fikrim yoktu :)
Chris Noldus


1
@hackbod Özel alıcıya meta veri etiketi nasıl eklenir? Her hangi bir fikriniz varmı !! Ben androidmanifest.xml kullandığımız meta-veri etiketi eklemeniz gerekir.
Zala Janaksinh

1
Tarihe kadar en iyi öğretici coderzpassion.com/implement-broadcastreceiver-android ve basit bir dilde
Jagjit Singh

269

Senin içinde onCreateyöntemiyle böyle bir alıcıyı kayıt olabilirsiniz:

private BroadcastReceiver receiver;

@Override
public void onCreate(Bundle savedInstanceState){

  // your oncreate code should be

  IntentFilter filter = new IntentFilter();
  filter.addAction("SOME_ACTION");
  filter.addAction("SOME_OTHER_ACTION");

  receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      //do something based on the intent's action
    }
  };
     registerReceiver(receiver, filter);
}

Bunu onDestroyyöntemde çalıştırmayı unutmayın :

 @Override
 protected void onDestroy() {
  if (receiver != null) {
   unregisterReceiver(receiver);
   receiver = null;
  }
  super.onDestroy();
 }

19
Teşekkürler, bu harika çalıştı. Yayını göndermek için Intent i = new Intent ("SOME_ACTION") kodunu kullandım; sendBroadcast (i)
Ben Clayton

7
neden özgeçmiş ve başlangıçta değil?
Syed Raza Mehdi

Yayın alıcısının kaydını iptal etmezsem ne olur? Yeniden başlattıktan sonra bile yayın alıcısını kayıtlı bırakır mı?
Jaydev

5
Aranacakları garanti edilmez onDestroy(), böylece potansiyel bir bellek sızıntısı oluşur. Bu kaydının / kayıt kayıt için iyidir onStart()/ onStop().
Neria Nachum

Bu, bir yayın alıcı sınıfı oluşturmak zorunda olmadığım anlamına mı geliyor? Tüm onReceive () kodumu buraya koyabilirim ve işe yarayabilir mi?
Taslim Oseni

70

İnsanların bahsetmeyi unuttukları önemli noktalardan biri de yaşam süresidir Broadcast Receiver. Programlı olarak kaydetmenin AndroidManifest.xml dosyasına kaydolmanın farkı şudur. Manifest dosyasında, uygulama yaşam süresine bağlı değildir. Programlı olarak kaydederken uygulama yaşam süresine bağlıdır. Bu, AndroidManifest.xml dosyasına kaydolursanız , uygulamanız çalışmıyorken bile yayınlanan hedefleri yakalayabileceğiniz anlamına gelir .

Düzenleme: Söz konusu not artık Android 3.1'den itibaren geçerli değildir, ilgili uygulama kullanıcı tarafından hiç başlatılmamışsa veya kullanıcı uygulamayı Android menüsü aracılığıyla ( Yönet → Uygulama). https://developer.android.com/about/versions/android-3.1.html

Bu, ek bir güvenlik özelliğidir, çünkü kullanıcı yalnızca başlattığı uygulamaların yayın hedefleri alacağından emin olabilir.

Dolayısıyla, Uygulamaya programlı olarak kaydedilen alıcıların yukarıdaki Android 3.1'den AndroidManifest.xml'deonCreate() beyan edilenlerle aynı etkiye sahip olacağı anlaşılabilir .


1
Bu iyi bir not. Aslında android hakkında okuduğum bir kitaba bakıyorum ve her iki yayın yönteminin neden yapıldığını merak ediyorum. Bana geriye dönük uyumluluk gibi geliyor. Ama emin değilim.
Neon Warge

Peki, düzenlemenin gerçekten doğru olduğu bir şey var mı? Son cümleyi kastediyorum. Android, uygulamanızı herhangi bir zamanda öldürecektir, bu da programlı olarak kayıtlı alıcılarınızın artık çalışmamasına neden olacaktır, ancak kayıtlı manifest hala çalışacaktır.
JacksOnF1re

40

Etkinlik / Parçanın herhangi bir yerinde yayın alıcısını şu şekilde tanımlayın:

mReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
     Log.d(TAG," onRecieve"); //do something with intent
   }
 };

IntentFilter öğesini tanımlayın onCreate()

mIntentFilter=new IntentFilter("action_name");

Şimdi BroadcastReciever'ı onResume()kaydedin ve Kaydını kaldırın onPause()[çünkü etkinlik duraklatılmışsa yayın kullanılmaz].

@Override
protected void onResume() {
     super.onResume();
     registerReceiver(mReceiver, mIntentFilter);
}

@Override
protected void onPause() {
    if(mReceiver != null) {
            unregisterReceiver(mReceiver);
            mReceiver = null;
    }
    super.onPause();
}

Ayrıntılı eğitim için, yayın alıcısına bir göz atın -uygulamak için iki yol .


şimdiye kadar bulduğum en iyi örnek! Teşekkürler!
Ayush Goyal

1
@SohailAziz Bağlantı iyi bir cevap veriyor. Bağlantının bağlamını cevabınıza koyabilir misiniz, böylece bağlantı koparsa cevabınız alakalı kalır mı?
iRuth

kişisel görüşlerime göre, yayın önerdiğiniz gibi onResume ve onPause'a kaydedilmelidir, ancak bazı insanlar onCreate ve onDestroy'da olması gerektiğini söylüyor, her ikisi için de artılarını ve eksilerini açıklayabilir misiniz?
Syed Raza Mehdi

2
@SyedRazaMehdi yayın UI'yi güncellemek için kullanılıyorsa (çoğu durumda) onResume'a kaydetmeli ve onPause'a kayıt olmalısınız, çünkü yayın aksi takdirde işe yaramaz.
SohailAziz

Teşekkürler.Bu en iyi cevap.
Saeid Z

4
package com.example.broadcastreceiver;


import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

   UserDefinedBroadcastReceiver broadCastReceiver = new UserDefinedBroadcastReceiver();

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }

   /**
    * This method enables the Broadcast receiver for
    * "android.intent.action.TIME_TICK" intent. This intent get
    * broadcasted every minute.
    *
    * @param view
    */
   public void registerBroadcastReceiver(View view) {

      this.registerReceiver(broadCastReceiver, new IntentFilter(
            "android.intent.action.TIME_TICK"));
      Toast.makeText(this, "Registered broadcast receiver", Toast.LENGTH_SHORT)
            .show();
   }

   /**
    * This method disables the Broadcast receiver
    *
    * @param view
    */
   public void unregisterBroadcastReceiver(View view) {

      this.unregisterReceiver(broadCastReceiver);

      Toast.makeText(this, "unregistered broadcst receiver", Toast.LENGTH_SHORT)
            .show();
   }
}

1
OP'ye bunun neden en iyi uygulama olduğunu açıklayabilir misiniz?
Martin Prikryl

1
Onlar açıklamıyorlar, "onlar" her zaman posta kodu, çünkü daha iyi biliyorsun. -sarcasm
Neon Warge

2

Genel Mesajları Dinleme ve Yayınlama ve Ortak Görevlerde Alarm Ayarlama ve Android'de Nasıl Yapılır :

Alıcı sınıf, bildiriminde kullanılarak kayıtlı değilse, Context.registerReceiver () öğesini çağırarak bir alıcıyı dinamik olarak başlatabilir ve kaydedebilirsiniz .

Bir de göz atın registerReceiver (BroadcastReceiver alıcısı, IntentFilter filtresi) daha fazla bilgi için.


1
aramayı denedim context.registerReceiverama çağrılmıyor musunuz bu soruya bakabilir misiniz stackoverflow.com/questions/13238600/…
Hunt

2

Alıcıyı kaydederken her zaman izin vermek en iyi yöntemdir, aksi takdirde eşleşen bir niyet gönderen herhangi bir uygulama için alırsınız. Bu, kötü amaçlı uygulamaların alıcınıza yayın yapmasına izin verebilir.


1

için LocalBroadcastManager

   Intent intent = new Intent("any.action.string");
   LocalBroadcastManager.getInstance(context).
                                sendBroadcast(intent);

ve kayıt ol onResume

LocalBroadcastManager.getInstance(
                    ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);

ve Kaydını Sil onStop

LocalBroadcastManager.getInstance(
                ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);

ve alın ..

mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.e("mBroadcastReceiver", "onReceive");
        }
    };

burada IntentFilter

 new IntentFilter("any.action.string")

1

İki seçenek

1) Yayını yalnızca Etkinlik görünür olduğunda okumak istiyorsanız,

registerReceiver(...) içeri onStart()ve unregisterReceiver(...)içerionStop()

2) Etkinlik Arka Plan'da olsa bile Yayını okumak istiyorsanız,

registerReceiver(...)içeri onCreate(...)ve unregisterReceiver(...)içerionDestroy()

Bonus:

Eğer tembelsen

Bir BroadcastReceiver'ı her bir Faaliyette tekrar tekrar kaydetmek ve kayıttan kaldırmak için ortak etiket kodu yazmak istemiyorsanız,

  1. Soyut bir Etkinlik oluşturma
  2. Etkinlikte kaynak kodu yazma
  3. Uygulamayı soyut yöntemler olarak bırak

Kod pasajı şöyledir:

Soyut Etkinlik

public abstract class BasicActivity extends AppCompatActivity {

    private BroadcastReceiver broadcastReceiver;
    private IntentFilter filter;
    private static final String TAG = "BasicActivity";

    /**********************************************************************
    *                   Boilerplate code
    **********************************************************************/

    @Override
    public void onCreate(Bundle sis){
        super.onCreate(sis);
        broadcastReceiver = getBroadcastReceiver();
        filter = getFilter();
    }

    @Override
    public void onStart(){
        super.onStart();
        register();
    }

    @Override
    public void onStop(){
        super.onStop();
        unregister();
    }

    private void register(){
        registerReceiver(broadcastReceiver,filter);
    }

    private void unregister(){
        unregisterReceiver(broadcastReceiver);
    }

    /**********************************************************************
    *                   Abstract methods
    **********************************************************************/

    public abstract BroadcastReceiver getBroadcastReceiver();

    public abstract IntentFilter getFilter();

}

Bu yaklaşımı kullanarak ortak animasyonlar yazma, bir hizmete bağlanma vb. Gibi daha fazla kaynak plakası yazabilirsiniz.

Kodun tamamını görün:

BURAYA


0

Yayın alıcısı oluşturma

[BroadcastReceiver (Etkin = doğru, Dışa aktarıldı = yanlış)]

public class BCReceiver : BroadcastReceiver
{

    BCReceiver receiver;

    public override void OnReceive(Context context, Intent intent)
    {
        //Do something here
    }
}

Etkinliğinizden bu kodu ekleyin:

LocalBroadcastManager.getInstance(ApplicationContext)
    .registerReceiver(receiver, filter);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.