Yayınlara genel bakış

Android uygulamaları, yayınlama-abone olma tasarım kalıbına benzer şekilde Android sisteminden ve diğer Android uygulamalarından yayın mesajları gönderip alır. Sistem ve uygulamalar genellikle belirli etkinlikler gerçekleştiğinde yayın gönderir. Örneğin, Android sistemi; sistem başlatma veya cihaz şarjı gibi çeşitli sistem etkinlikleri gerçekleştiğinde yayın gönderir. Uygulamalar, diğer uygulamaları ilgilendirebilecek bir şey (ör. yeni veri indirme) hakkında bilgilendirmek için de özel yayınlar gönderir.

Uygulamalar, belirli yayınları almak için kaydolabilir. Sistem, bir yayın gönderildiğinde yayınları otomatik olarak belirli bir yayın türünü almaya abone olan uygulamalara yönlendirir.

Genel olarak yayınlar, uygulamalar arasında ve normal kullanıcı akışının dışında bir mesajlaşma sistemi olarak kullanılabilir. Ancak yayınlara yanıt verme ve arka planda sistem performansını yavaşlatabilecek işler çalıştırma fırsatını kötüye kullanmamaya dikkat etmeniz gerekir.

Sistem duyuruları hakkında

Sistem, çeşitli sistem etkinlikleri (ör. sistem Uçak Modu'na girip çıktığında) gerçekleştiğinde otomatik olarak yayın gönderir. Abone olan tüm uygulamalar bu yayınları alır.

Intent nesnesi, yayın mesajını sarar. action dizesi, gerçekleşen etkinliği tanımlar (ör. android.intent.action.AIRPLANE_MODE). Intent, ek alanına yerleştirilmiş ek bilgiler de içerebilir. Örneğin, Uçak Modu intent'i, Uçak Modu'nun açık olup olmadığını belirten bir boole ek içerir.

Intent'leri okuma ve intent'ten işlem dizesini alma hakkında daha fazla bilgi için Intent'ler ve Intent Filtreleri başlıklı makaleyi inceleyin.

Sistem duyurusu işlemleri

Sistem yayını işlemlerinin tam listesi için Android SDK'sındaki BROADCAST_ACTIONS.TXT dosyasına bakın. Her yayın işleminin kendisiyle ilişkili bir sabit alan vardır. Örneğin, ACTION_AIRPLANE_MODE_CHANGED sabitinin değeri android.intent.action.AIRPLANE_MODE'tır. Her yayın işleminin dokümanları, ilişkili sabit alanında mevcuttur.

Sistem yayınlarında yapılan değişiklikler

Android platformu geliştikçe sistem yayınlarının davranışı da düzenli olarak değişir. Android'in tüm sürümlerini desteklemek için aşağıdaki değişiklikleri göz önünde bulundurun.

Android 14

Uygulamalar önbelleğe alınmış durumdayken sistem, yayın yayınını sistem sağlığı için optimize eder. Örneğin, sistem, uygulama önbelleğe alınmış durumdayken ACTION_SCREEN_ON gibi daha az önemli sistem yayınlarını erteler. Uygulama, önbelleğe alınmış durumdan etkin bir işlem yaşam döngüsüne geçtiğinde sistem, ertelenen tüm yayınları yayınlar.

Manifestte tanımlanan önemli yayınlar, uygulamaların yayınlanması için geçici olarak önbelleğe alınmış durumdan kaldırılır.

Android 9

Android 9'dan (API düzeyi 28) itibaren NETWORK_STATE_CHANGED_ACTION yayını, kullanıcının konumu veya kimliği tanımlayabilecek veriler hakkında bilgi almaz.

Uygulamanız Android 9.0 (API düzeyi 28) veya sonraki bir sürümün yüklü olduğu bir cihaza yüklüyse sistem, kablosuz yayınlarda SSID'leri, BSSID'leri, bağlantı bilgilerini veya tarama sonuçlarını içermez. Bu bilgileri almak için getConnectionInfo() numaralı telefonu arayın.

Android 8.0

Android 8.0 (API düzeyi 26) sürümünden itibaren sistem, manifest dosyasında tanımlanan alıcılara ek kısıtlamalar uygular.

Uygulamanız Android 8.0 veya sonraki sürümleri hedefliyorsa çoğu dolaylı yayın (özellikle uygulamanızı hedeflemeyen yayınlar) için alıcı bildirmek üzere manifest dosyasını kullanamazsınız. Kullanıcı uygulamanızı etkin olarak kullanırken bağlamla kayıtlı alıcı kullanmaya devam edebilirsiniz.

Android 7.0

Android 7.0 (API düzeyi 24) ve sonraki sürümler aşağıdaki sistem yayınlarını göndermez:

Ayrıca, Android 7.0 ve sonraki sürümleri hedefleyen uygulamalar, registerReceiver(BroadcastReceiver, IntentFilter) kullanarak CONNECTIVITY_ACTION yayınını kaydettirmelidir. Manifestte alıcı tanımlamak işe yaramaz.

Yayınları alma

Uygulamalar, yayınları iki şekilde alabilir: bağlama kaydedilmiş alıcılarla ve manifest dosyasında tanımlanmış alıcılarla.

Bağlama göre kayıtlı alıcılar

Bağlama göre kaydedilen alıcılar, kayıt bağlamları geçerli olduğu sürece yayınları alır. Bu genellikle registerReceiver ile unregisterReceiver çağrıları arasında gerçekleşir. Sistem, ilgili bağlamı yok ettiğinde de kayıt bağlamı geçersiz olur. Örneğin, Activity bağlamında kaydolduğunuzda etkinlik etkin olduğu sürece yayın alırsınız. Uygulama bağlamına kaydederseniz uygulama çalışırken yayın alırsınız.

Bir alıcıyı bağlama kaydetmek için aşağıdaki adımları uygulayın:

  1. Uygulamanızın modül düzeyindeki derleme dosyasına AndroidX Core kitaplığının 1.9.0 veya sonraki bir sürümünü ekleyin:

    Eski

    dependencies {
        def core_version = "1.13.1"
    
        // Java language implementation
        implementation "androidx.core:core:$core_version"
        // Kotlin
        implementation "androidx.core:core-ktx:$core_version"
    
        // To use RoleManagerCompat
        implementation "androidx.core:core-role:1.0.0"
    
        // To use the Animator APIs
        implementation "androidx.core:core-animation:1.0.0"
        // To test the Animator APIs
        androidTestImplementation "androidx.core:core-animation-testing:1.0.0"
    
        // Optional - To enable APIs that query the performance characteristics of GMS devices.
        implementation "androidx.core:core-performance:1.0.0"
    
        // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google
        implementation "androidx.core:core-google-shortcuts:1.1.0"
    
        // Optional - to support backwards compatibility of RemoteViews
        implementation "androidx.core:core-remoteviews:1.1.0"
    
        // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12
        implementation "androidx.core:core-splashscreen:1.2.0-alpha02"
    }
    

    Kotlin

    dependencies {
        val core_version = "1.13.1"
    
        // Java language implementation
        implementation("androidx.core:core:$core_version")
        // Kotlin
        implementation("androidx.core:core-ktx:$core_version")
    
        // To use RoleManagerCompat
        implementation("androidx.core:core-role:1.0.0")
    
        // To use the Animator APIs
        implementation("androidx.core:core-animation:1.0.0")
        // To test the Animator APIs
        androidTestImplementation("androidx.core:core-animation-testing:1.0.0")
    
        // Optional - To enable APIs that query the performance characteristics of GMS devices.
        implementation("androidx.core:core-performance:1.0.0")
    
        // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google
        implementation("androidx.core:core-google-shortcuts:1.1.0")
    
        // Optional - to support backwards compatibility of RemoteViews
        implementation("androidx.core:core-remoteviews:1.1.0")
    
        // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12
        implementation("androidx.core:core-splashscreen:1.2.0-alpha02")
    }
    
  2. BroadcastReceiver örneği oluşturun:

    Kotlin

    val myBroadcastReceiver = MyBroadcastReceiver()
    

    Java

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    
  3. IntentFilter örneği oluşturun:

    Kotlin

    val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")
    

    Java

    IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");
    
  4. Yayın alıcısının dışa aktarılıp cihazdaki diğer uygulamalar tarafından görünür olup olmayacağını seçin. Bu alıcı, sistemden veya diğer uygulamalardan (sahip olduğunuz uygulamalar da dahil) gönderilen yayınları dinliyorsa RECEIVER_EXPORTED işaretini kullanın. Bunun yerine bu alıcı yalnızca uygulamanız tarafından gönderilen yayınları dinliyorsa RECEIVER_NOT_EXPORTED işaretini kullanın.

    Kotlin

    val listenToBroadcastsFromOtherApps = false
    val receiverFlags = if (listenToBroadcastsFromOtherApps) {
        ContextCompat.RECEIVER_EXPORTED
    } else {
        ContextCompat.RECEIVER_NOT_EXPORTED
    }
    

    Java

    boolean listenToBroadcastsFromOtherApps = false;
    int receiverFlags = listenToBroadcastsFromOtherApps
            ? ContextCompat.RECEIVER_EXPORTED
            : ContextCompat.RECEIVER_NOT_EXPORTED;
    
  5. registerReceiver() numaralı telefonu arayarak alıcıyı kaydedin:

    Kotlin

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)
    

    Java

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
    
  6. Yayınları almayı durdurmak için unregisterReceiver(android.content.BroadcastReceiver) numaralı telefonu arayın. Artık ihtiyacınız olmadığında veya bağlam geçerli olmadığında alıcının kaydını sildiğinizden emin olun.

Yayın alıcınızın kaydını iptal etme

Yayın alıcı kayıtlıyken, kaydettiğiniz bağlama referans verir. Alıcının kayıtlı kapsamı, bağlam yaşam döngüsü kapsamını aşarsa bu durum sızıntılara neden olabilir. Örneğin, bir alıcıyı bir etkinlik kapsamına kaydettiğinizde ancak sistem etkinliği yok ettiğinde alıcıyı kaydetmeyi unuttuğunuzda bu durumla karşılaşabilirsiniz. Bu nedenle, yayın alıcınızın kaydını her zaman iptal edin.

Kotlin

class MyActivity : ComponentActivity() {
    private val myBroadcastReceiver = MyBroadcastReceiver()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags)
        setContent { MyApp() }
    }

    override fun onDestroy() {
        super.onDestroy()
        // When you forget to unregister your receiver here, you're causing a leak!
        this.unregisterReceiver(myBroadcastReceiver)
    }
}

Java

class MyActivity extends ComponentActivity {
    MyBroadcastReceiver myBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...
        ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags);
        // Set content
    }
}

Alıcıları en küçük kapsamda kaydetme

Yayın alıcınız yalnızca sonuçla gerçekten ilgilendiğinizde kaydedilmelidir. Mümkün olan en küçük alıcı kapsamını seçin:

  • LifecycleResumeEffect veya etkinlik onResume/onPause yaşam döngüsü yöntemleri: Yayın alıcı yalnızca uygulama devam ettirilmiş durumdayken güncelleme alır.
  • LifecycleStartEffect veya etkinlik onStart/onStop yaşam döngüsü yöntemleri: Yayın alıcı yalnızca uygulama devam ettirilmiş durumdayken güncelleme alır.
  • DisposableEffect: Yayın alıcısı yalnızca derlenebilir öğe kompozisyon ağacındayken güncelleme alır. Bu kapsam, etkinlik yaşam döngüsü kapsamına eklenmemiştir. Alıcının uygulama bağlamına kaydedilmesini sağlayabilirsiniz. Bunun nedeni, derlenebilir öğenin teorik olarak etkinlik yaşam döngüsü kapsamını aşabilmesi ve etkinliği sızdırabilmesidir.
  • Etkinlik onCreate/onDestroy: Yayın alıcı, etkinlik oluşturulmuş durumdayken güncelleme alır. onSaveInstanceState(Bundle) çağrılmayabileceği için onDestroy() adresinde kaydınızı iptal ettiğinizden emin olun.
  • Özel kapsam: Örneğin, bir alıcıyı ViewModelkapsamınıza kaydedebilirsiniz. Böylece, alıcı etkinlik yeniden oluşturulduğunda silinmez. Alıcının etkinlik yaşam döngüsü kapsamını aşması ve etkinliği sızdırması mümkün olduğundan, alıcıyı kaydetmek için uygulama bağlamını kullandığınızdan emin olun.

Durum bilgisine sahip ve durum bilgisi olmayan birleştirilebilir öğeler oluşturun

Compose'da durum bilgisi olan ve durum bilgisi olmayan bileşenler bulunur. Bir yayın alıcısını bir bileşiğe kaydettirmek veya kaydını kaldırmak, yayın alıcısını duruma duyarlı hale getirir. composable, aynı parametreler ile kullanıldığında aynı içeriği oluşturan deterministik bir işlev değildir. Dahili durum, kayıtlı yayın alıcısına yapılan çağrılara bağlı olarak değişebilir.

Compose'da en iyi uygulama olarak, derlenebilir öğelerinizi durum bilgisine sahip ve durum bilgisi olmayan sürümlere ayırmanızı öneririz. Bu nedenle, yayın alıcısını durum bilgisi içermeyecek şekilde oluşturmak için Composable'dan kaldırmanızı öneririz:

@Composable
fun MyStatefulScreen() {
    val myBroadcastReceiver = remember { MyBroadcastReceiver() }
    val context = LocalContext.current
    LifecycleStartEffect(true) {
        // ...
        ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, flags)
        onStopOrDispose { context.unregisterReceiver(myBroadcastReceiver) }
    }
    MyStatelessScreen()
}

@Composable
fun MyStatelessScreen() {
    // Implement your screen
}

Manifest'te tanımlanan alıcılar

Manifest dosyanızda bir yayın alıcısını beyan ederseniz sistem, yayın gönderildiğinde uygulamanızı başlatır. Uygulama çalışmıyorsa sistem uygulamayı başlatır.

Manifestte bir yayın alıcısını bildirmek için aşağıdaki adımları uygulayın:

  1. Uygulamanızın manifest dosyasında <receiver> öğesini belirtin.

    <!-- If this receiver listens for broadcasts sent from the system or from
         other apps, even other apps that you own, set android:exported to "true". -->
    <receiver android:name=".MyBroadcastReceiver" android:exported="false">
        <intent-filter>
            <action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
        </intent-filter>
    </receiver>
    

    Intent filtreleri, alıcınızın abone olduğu yayın işlemlerini belirtir.

  2. BroadcastReceiver alt sınıfını oluşturun ve onReceive(Context, Intent) sınıfını uygulayın. Aşağıdaki örnekteki yayın alıcısı, yayının içeriğini kaydeder ve gösterir:

    Kotlin

    class MyBroadcastReceiver : BroadcastReceiver() {
    
        @Inject
        lateinit var dataRepository: DataRepository
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "com.example.snippets.ACTION_UPDATE_DATA") {
                val data = intent.getStringExtra("com.example.snippets.DATA") ?: "No data"
                // Do something with the data, for example send it to a data repository:
                dataRepository.updateData(data)
            }
        }
    }
    

    Java

    public static class MyBroadcastReceiver extends BroadcastReceiver {
    
        @Inject
        DataRepository dataRepository;
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Objects.equals(intent.getAction(), "com.example.snippets.ACTION_UPDATE_DATA")) {
                String data = intent.getStringExtra("com.example.snippets.DATA");
                // Do something with the data, for example send it to a data repository:
                if (data != null) { dataRepository.updateData(data); }
            }
        }
    }
    

Sistem paket yöneticisi, uygulama yüklendiğinde alıcıyı kaydeder. Ardından alıcı, uygulamanıza ayrı bir giriş noktası olur. Bu, sistem uygulamayı başlatıp yayını sunabilir (uygulama çalışmıyorsa).

Sistem, aldığı her yayını işlemek için yeni bir BroadcastReceiver bileşen nesnesi oluşturur. Bu nesne yalnızca onReceive(Context, Intent) çağrısı sırasında geçerlidir. Kodunuz bu yöntemden döndükten sonra sistem, bileşenin artık etkin olmadığını düşünür.

İşlem durumu üzerindeki etkiler

BroadcastReceiver'inizin çalışıp çalışmaması, içerdiği işlemi etkiler. Bu da sistemin çalışmasını durdurma olasılığını değiştirebilir. Ön planda çalışan bir işlem, alıcının onReceive() yöntemini yürütür. Sistem, aşırı bellek baskısı altında olmadığı sürece işlemi çalıştırır.

Sistem, onReceive() saat sonra BroadcastReceiver'ü devre dışı bırakır. Alıcının ana makine sürecinin önemi, uygulama bileşenlerine bağlıdır. Bu işlem yalnızca manifest ile tanımlanmış bir alıcı barındırıyorsa sistem, daha kritik diğer işlemler için kaynakları boşaltmak üzere onReceive() sonra işlemi sonlandırabilir. Bu durum, kullanıcının hiç veya yakın zamanda etkileşime girmediği uygulamalarda yaygındır.

Bu nedenle, yayın alıcıları uzun süre çalışan arka plan iş parçacıkları başlatmamalıdır. Sistem, belleği geri almak için onReceive()'ten sonra işlemi istediği zaman durdurabilir ve oluşturulan mesaj dizisini sonlandırır. Sistemin sürecin hâlâ çalıştığını bilmesi için işlemin devam etmesini sağlamak üzere JobScheduler kullanarak alıcıdan bir JobService planlayın. Arka Plan Çalışmalarına Genel Bakış bölümünde daha fazla bilgi verilmektedir.

Yayın gönderme

Android, uygulamaların yayın göndermesi için iki yöntem sunar:

  • sendOrderedBroadcast(Intent, String) yöntemi, yayınları tek seferde bir alıcıya gönderir. Her alıcı sırayla yürütülürken bir sonucu bir sonraki alıcıya iletebilir. Ayrıca, diğer alıcılara ulaşmaması için yayını tamamen iptal edebilir. Alıcıların çalıştırılma sırasını kontrol edebilirsiniz. Bunu yapmak için eşleşen intent-filter öğesinin android:priority özelliğini kullanın. Aynı önceliğe sahip alıcı, rastgele bir sırada çalıştırılır.
  • sendBroadcast(Intent) yöntemi, yayınları tüm alıcılara tanımlanmamış bir sırada gönderir. Buna normal yayın denir. Bu daha verimlidir ancak alıcıların diğer alıcılardan gelen sonuçları okuyamayacağı, yayından alınan verileri dağıtamayacağı veya yayını iptal edemeyeceği anlamına gelir.

Aşağıdaki kod snippet'inde, Intent oluşturarak ve sendBroadcast(Intent) çağrısı yaparak nasıl yayın gönderileceği gösterilmektedir.

Kotlin

val intent = Intent("com.example.snippets.ACTION_UPDATE_DATA").apply {
    putExtra("com.example.snippets.DATA", newData)
    setPackage("com.example.snippets")
}
context.sendBroadcast(intent)

Java

Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
intent.putExtra("com.example.snippets.DATA", newData);
intent.setPackage("com.example.snippets");
context.sendBroadcast(intent);

Yayın mesajı bir Intent nesnesine sarılır. Intent'in action dizesi, uygulamanın Java paket adı söz dizimini sağlamalıdır ve yayın etkinliğini benzersiz şekilde tanımlamalıdır. putExtra(String, Bundle) ile intent'e ek bilgiler ekleyebilirsiniz. Ayrıca, intent üzerinde setPackage(String) çağrısı yaparak yayını aynı kuruluştaki bir uygulama grubuyla sınırlayabilirsiniz.

İzinlerle yayınları kısıtlama

İzinler, yayınları belirli izinlere sahip uygulama grubuyla kısıtlamanıza olanak tanır. Bir yayının gönderenine veya alıcısına kısıtlama uygulayabilirsiniz.

İzinlerle yayın gönderme

sendBroadcast(Intent, String) veya sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) işlevini çağırırken izin parametresi belirtebilirsiniz. Yalnızca manifest'lerinde <uses-permission> etiketiyle bu izni isteyen alıcılar yayını alabilir. İzin tehlikeliyse alıcının yayını alabilmesi için izni vermeniz gerekir. Örneğin, aşağıdaki kod bir izinle yayın gönderir:

Kotlin

context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)

Java

context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);

Alıcının uygulamanın yayını alabilmesi için aşağıdaki şekilde izin istemelidir:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

BLUETOOTH_CONNECT gibi mevcut bir sistem iznini belirtebilir veya <permission> öğesini kullanarak özel bir izin tanımlayabilirsiniz. Genel olarak izinler ve güvenlik hakkında bilgi edinmek için Sistem İzinleri başlıklı makaleyi inceleyin.

İzinlerle yayın alma

Bir yayın alıcısını kaydederken izin parametresi belirtirseniz (manifestinizde registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) veya <receiver> etiketiyle) yalnızca manifestlerinde <uses-permission> etiketiyle izin isteyen yayıncılar alıcıya Intent gönderebilir. İzin tehlikeliyse yayıncıya da izin verilmelidir.

Örneğin, alıcı uygulamanızda aşağıdaki gibi manifest ile beyan edilmiş bir alıcı olduğunu varsayalım:

<!-- If this receiver listens for broadcasts sent from the system or from
     other apps, even other apps that you own, set android:exported to "true". -->
<receiver
    android:name=".MyBroadcastReceiverWithPermission"
    android:permission="android.permission.ACCESS_COARSE_LOCATION"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
    </intent-filter>
</receiver>

Alternatif olarak, alıcı uygulamanızda aşağıdaki gibi bağlama kayıtlı bir alıcı var:

Kotlin

ContextCompat.registerReceiver(
    context, myBroadcastReceiver, filter,
    android.Manifest.permission.ACCESS_COARSE_LOCATION,
    null, // scheduler that defines thread, null means run on main thread
    receiverFlags
)

Java

ContextCompat.registerReceiver(
        context, myBroadcastReceiver, filter,
        android.Manifest.permission.ACCESS_COARSE_LOCATION,
        null, // scheduler that defines thread, null means run on main thread
        receiverFlags
);

Ardından, bu alıcılara yayın gönderebilmek için gönderen uygulamanın izni aşağıdaki şekilde istemesi gerekir:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Güvenlikle ilgili olarak göz önünde bulundurulması gerekenler

Yayın gönderme ve alma ile ilgili bazı güvenlik önlemleri:

  • Manifestlerinde aynı yayını almak için kayıtlı çok sayıda uygulama varsa sistem çok sayıda uygulamayı başlatabilir. Bu da hem cihaz performansını hem de kullanıcı deneyimini önemli ölçüde etkileyebilir. Bunu önlemek için manifest beyanı yerine bağlam kaydı kullanmayı tercih edin. Bazen Android sisteminin kendisi, bağlama kaydedilmiş alıcıları kullanmayı zorunlu kılar. Örneğin, CONNECTIVITY_ACTION yayını yalnızca bağlama kayıtlı alıcılara yayınlanır.

  • Hassas bilgileri, dolaylı intent kullanarak yayınlamayın. Yayını almak için kayıt yapan tüm uygulamalar bu bilgileri okuyabilir. Yayınlarınızı kimlerin alabileceğini üç şekilde kontrol edebilirsiniz:

    • Yayın gönderirken izin belirtebilirsiniz.
    • Android 4.0 (API düzeyi 14) ve sonraki sürümlerde, yayın gönderirken setPackage(String) ile bir paket belirtebilirsiniz. Sistem, yayını paketle eşleşen uygulama grubuyla kısıtlar.
  • Bir alıcı kaydettiğinizde, herhangi bir uygulama, uygulamanızın alıcısına kötü amaçlı olabilecek yayınlar gönderebilir. Uygulamanızın aldığı yayınları sınırlamanın birkaç yolu vardır:

    • Yayın alıcısını kaydederken izin belirtebilirsiniz.
    • Manifest'te tanımlanan alıcılarda, manifest'te android:exported özelliğini "false" olarak ayarlayabilirsiniz. Alıcı, uygulama dışındaki kaynaklardan yayın almaz.
  • Yayınlama işlemlerinin ad alanı geneldir. İşlem adlarının ve diğer dizelerin, sahibi olduğunuz bir ad alanında yazıldığından emin olun. Aksi takdirde, diğer uygulamalarla istemeden çakışabilirsiniz.

  • Alıcı onReceive(Context, Intent) yöntemi ana iş parçacığında çalıştığından hızlı bir şekilde yürütülüp döndürülmelidir. Uzun süren bir çalışma yapmanız gerekiyorsa sistem, onReceive() döndükten sonra tüm süreci sonlandırabileceğinden iş parçacıkları oluşturma veya arka plan hizmetlerini başlatma konusunda dikkatli olun. Daha fazla bilgi için İşlem durumu üzerindeki etki başlıklı makaleyi inceleyin. Uzun süren işlemler yapmak için şunları öneririz:

    • Alıcının onReceive() yönteminde goAsync() çağrısını yapıp BroadcastReceiver.PendingResult öğesini arka plan iş parçacığına iletin. Bu sayede, onReceive()'ten döndükten sonra yayın etkin kalır. Ancak bu yaklaşımda bile sistem, yayını çok hızlı bir şekilde (10 saniyeden kısa sürede) bitirmenizi bekler. Ana iş parçacığında hata oluşmasını önlemek için çalışmayı başka bir iş parçacığına taşımanıza olanak tanır.
    • JobScheduler ile bir iş planlama. Daha fazla bilgi için Akıllı İş Planlama başlıklı makaleyi inceleyin.
  • Özellikle birden fazla alıcı varsa kullanıcı deneyimi rahatsız edici olacağından etkinlikleri yayın alıcılarından başlatmayın. Bunun yerine bildirim göstermeyi deneyebilirsiniz.