Yayınlara genel bakış

Android uygulamaları Android sisteminden anons gönderip alabilir ve Android uygulamalarında yayınla-abone-ol özellikleri inceleyelim. Bu yayınlar, ilgilenilen bir etkinlik gerçekleştiğinde gönderilir. Örneğin, çeşitli sistem etkinlikleri olduğunda Android sistemi yayınlar gönderir. veya cihazın şarj olmaya başlaması gibi durumlarda geçerli olur. Uygulamalar ayrıca özel yayınlar da gönderebilir. Örneğin, ilgilerini çekebilecek bir şeyi (örneğin, bazı yeni verilerde) indirilmiş olması gerekir).

Sistem, yayınlarınızın tutarlılığını korumak için yayınların teslimini optimize eder optimum sistem sağlığına iyi gelir. Bu nedenle, yayınların teslim süreleri garantili. Düşük gecikmeli işlemler arası iletişim gerektiren uygulamalar bağlı hizmetleri göz önünde bulundurun.

Uygulamalar belirli yayınları almak için kaydolabilir. Bir yayın gönderildiğinde sistem, yayınları otomatik olarak abone olan uygulamalara yönlendirir yayın türünü bilmesini sağlayın.

Genel anlamda yayınlar, uygulamalarda mesajlaşma sistemi olarak kullanılabilir. ve normal kullanıcı akışının dışında olmasını sağlar. Ancak, kötüye kullanmamaya ve yayınlara yanıt verme ve gerçek zamanlı olarak çalışan işleri arka planda yürütme fırsatı sistem performansı yavaşlayabilir.

Sistem yayınları hakkında

Çeşitli sistem etkinlikleri gerçekleştiğinde sistem, yayınları otomatik olarak gönderir. örneğin, sistemin uçak moduna girmesi veya kapanması gibi. Sistem bu yayınları almaya abone olan tüm uygulamalara gönderilir unutmayın.

Yayın mesajının kendisi bir Intent içine yerleştirilir. işlem dizesinin gerçekleşen etkinliği tanımladığı nesne (örneğin, android.intent.action.AIRPLANE_MODE) tıklayın. Amaç, şunları da içerebilir: bir araya getirilmiş ek bilgilere yer verir. Örneğin, uçak mod amacı, Uçak olup olmadığını belirten bir ekstra boole değeri içerir Mod açık.

Amaçları okuma ve işlem dizesini alma hakkında daha fazla bilgi için hakkında daha fazla bilgi için Amaçlar ve Amaçlar Filtreler.

Sistem yayını işlemlerinin tam listesi için Android SDK'da BROADCAST_ACTIONS.TXT dosyası var. Her yayın işleminde bir sabit bir alan olacaktır. Örneğin, ACTION_AIRPLANE_MODE_CHANGED android.intent.action.AIRPLANE_MODE. Her yayın işlemiyle ilgili belgeler değeri, ilişkili sabit değer alanında kullanılabilir.

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

Android platformu geliştikçe sistemin yayın yapma biçimi düzenli olarak değişir gösterir. 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ış yayını zamanlamasını belirtir, yayın teslimi optimize edildiğinden emin olun. Örneğin, ACTION_SCREEN_ON olduğu için uygulama önbelleğe alınmış durumdayken ertelenir. Uygulama, önbelleğe alınan klasörden ayrıldığında durumu etkin bir sürece yaşam döngüsü boyunca tüm ertelenmiş yayınlar.

Google Ads Hükümler ve Koşulları'nda belirtilen önemli yayınlar manifest dosyası, önbelleğe alınan uygulamaları geçici olarak kaldırır durumudur.

Android 9

Android 9'dan (API düzeyi 28) itibaren, NETWORK_STATE_CHANGED_ACTION yayını, kullanıcının konumuyla ilgili veya kişisel bilgiler almadığında kişisel verilerdir.

Ayrıca, uygulamanız Android 9 veya sonraki sürümleri çalıştıran bir cihazda yüklüyse kablosuz ağdan yapılan sistem yayınları SSID'leri, BSSID'leri, bağlantıyı içermez veya tarama sonuçları. Bu bilgiyi almak için şu numarayı arayın: getConnectionInfo() .

Android 8.0

Sistem, Android 8.0 (API düzeyi 26) sürümünden başlayarak, kısıtlamalara tabi olduğunu lütfen unutmayın.

Uygulamanız Android 8.0 veya sonraki bir sürümü hedefliyorsa aşağıdaki işlemler için manifest dosyasını kullanamazsınız: çoğu örtülü yayın (hedeflenmeyen yayınlar) (özellikle de uygulamanızı). Yine de kullanabileceğiniz bir bağlamaya göre kayıtlı alıcı kullandığının bir göstergesidir.

Android 7.0

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

Ayrıca, Android 7.0 ve sonraki sürümleri hedefleyen uygulamalar, CONNECTIVITY_ACTION yayınını kaydetmelidir registerReceiver(BroadcastReceiver, IntentFilter) kullanılıyor. Manifest dosyasında alıcı tanımlama işlemi işe yaramaz.

Yayın alma

Uygulamalar iki şekilde yayın alabilir: manifest tarafından beyan edilen alıcılar aracılığıyla. daha fazla bilgi edineceksiniz.

Manifestte tanımlanan alıcılar

Manifest'inizde bir yayın alıcı bildirirseniz sistem, (uygulama zaten çalışmıyorsa) yayın gönderilir.

Manifest'te bir yayın alıcı bildirmek için aşağıdaki adımları uygulayın:

  1. <receiver> özelliğini belirtin öğesi oluşturun.

    <!-- 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="APP_SPECIFIC_BROADCAST" />
        </intent-filter>
    </receiver>
    

    Amaç filtreleri, alıcınızın abone olduğu yayın işlemlerini belirler.

  2. BroadcastReceiver alt sınıfını ayırın ve onReceive(Context, Intent) uygulayın. İlgili içeriği oluşturmak için kullanılan yayın alıcısını (aşağıdaki örnek günlüklerde bulabilirsiniz) dokunun:

    Kotlin

    private const val TAG = "MyBroadcastReceiver"
    
    class MyBroadcastReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            StringBuilder().apply {
                append("Action: ${intent.action}\n")
                append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
                toString().also { log ->
                    Log.d(TAG, log)
    
                    val binding = ActivityNameBinding.inflate(layoutInflater)
                    val view = binding.root
                    setContentView(view)
    
                    Snackbar.make(view, log, Snackbar.LENGTH_LONG).show()
                }
            }
        }
    }
    

    Java

    public class MyBroadcastReceiver extends BroadcastReceiver {
            private static final String TAG = "MyBroadcastReceiver";
            @Override
            public void onReceive(Context context, Intent intent) {
                StringBuilder sb = new StringBuilder();
                sb.append("Action: " + intent.getAction() + "\n");
                sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
                String log = sb.toString();
                Log.d(TAG, log);
    
                ActivityNameBinding binding =
                        ActivityNameBinding.inflate(layoutInflater);
                val view = binding.root;
                setContentView(view);
    
                Snackbar.make(view, log, Snackbar.LENGTH_LONG).show();
            }
        }
    

    Görünüm bağlamayı etkinleştirmek için modül düzeyinde viewBinding'i yapılandırın build.gradle dosyasını yükleyin.

Sistem paket yöneticisi, uygulama yüklendiğinde alıcıyı kaydeder. Alıcı daha sonra uygulamanıza ayrı bir giriş noktası haline gelir. Bu da, uygulamanın hızlı bir şekilde başlatılmasına izin verilmezse sistemin uygulamayı başlatıp yayını şu anda çalışıyor.

Sistem yeni bir BroadcastReceiver bileşeni oluşturur nesnesini ifade eder. Bu nesne yalnızca geçerli onReceive(Context, Intent) numaralı telefona yapılan çağrı süresince. Kodunuzu bu yöntemden geri dönerse sistem, bileşenin artık etkin.

Bağlama kayıtlı alıcılar

Bağlama kayıtlı alıcılar, kaydoldukları sürece bağlam geçerlidir. Örneğin, Activity. etkinlik yok edilmediği sürece yayınları alırsınız. Şu durumda: Uygulama bağlamına kaydolduğunuzda, uygulamanız olduğu sürece yayınları alırsınız. çalışıyor.

Alıcıyı bağlamla birlikte kaydetmek için aşağıdaki adımları uygulayın:

  1. Uygulamanızın modül düzeyindeki derleme dosyasına AndroidX Core kitaplığı:

    Modern

    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-alpha01"
    }
    

    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-alpha01")
    }
    
  2. Şunun bir örneğini oluştur: BroadcastReceiver:

    Kotlin

    val br: BroadcastReceiver = MyBroadcastReceiver()
    

    Java

    BroadcastReceiver br = new MyBroadcastReceiver();
    
  3. Şunun bir örneğini oluştur: IntentFilter:

    Kotlin

    val filter = IntentFilter(APP_SPECIFIC_BROADCAST)
    

    Java

    IntentFilter filter = new IntentFilter(APP_SPECIFIC_BROADCAST);
    
  4. Yayın alıcısının dışa aktarılıp aktarılmayacağını ve bu kişiler tarafından görüntülenip görüntülenmeyeceğini seçin. cihazdaki diğer uygulamalar. Bu alıcı, gönderilen yayınları dinliyorsa sistem veya diğer uygulamalar (sahip olduğunuz diğer uygulamalar dahil) RECEIVER_EXPORTED işareti. Bunun yerine bu alıcı yalnızca şu dili dinliyor: uygulamanız tarafından gönderilen yayınlar için 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;
    if (listenToBroadcastsFromOtherApps) {
        receiverFlags = ContextCompat.RECEIVER_EXPORTED;
    } else {
        receiverFlags = ContextCompat.RECEIVER_NOT_EXPORTED;
    }
    
  5. Şu numarayı arayarak alıcıyı kaydettirin: registerReceiver():

    Kotlin

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

    Java

    ContextCompat.registerReceiver(context, br, filter, receiverFlags);
    
  6. Anons almaya son vermek için unregisterReceiver(android.content.BroadcastReceiver) numaralı telefonu arayın. Artık ihtiyacınız kalmadığında alıcının kaydını iptal etmeyi veya bağlam artık geçerli değil.

    Alıcının kayıt ve kaydını iptal ettiğiniz durumlara dikkat edin. Örneğin, etkinliğin bağlamını kullanarak onCreate(Bundle) ürününe bir alıcı kaydederseniz şu işlemleri yapmak için onDestroy() alanındaki kaydını iptal etmelidir: alıcıyı etkinlik bağlamının dışına sızdırmayı önler. Kaydolduğunuzda onResume() kullanıyorsanız engellemek için onPause() alanındaki kaydını iptal et birden fazla kez kaydettirmek (yayınlanan uyarıları almak istemiyorsanız devre dışı bırakılır ve bu, gereksiz sistem ek yükünü azaltabilir). Şunları yapmayın: onSaveInstanceState(Bundle) uygulamasındaki kaydını iptal et, çünkü kullanıcı geçmiş yığınına geri dönerse bu çağrılmaz.

İşlem durumu üzerindeki etkiler

BroadcastReceiver olup olmadığı dahili işlemini etkilemesi veya etkilememesi, olasılığından bahsedeceğiz. Ön plan işlemi, alıcının onReceive() yöntemini yürütür. İlgili içeriği oluşturmak için kullanılan sistem, aşırı bellek baskısı altında olmadıkça işlemi çalıştırır.

BroadcastReceiver onReceive() tarihinden sonra devre dışı bırakılır. Alıcının ana makinesi en az uygulama bileşenleri kadar önemli. Bu işlem yalnızca ana makinelerde manifest beyan edilen alıcı (kullanıcının hiçbir zaman veya yakın zamanda etkileşimde bulunmamışsa sistem, onReceive() sonra şunu iptal edebilir: diğer kritik süreçler için kullanılabilir kaynaklar var.

Bu nedenle, yayın alıcıları uzun süreli arka plan iş parçacıkları başlatmamalıdır. Sistem, onReceive() tarihinden sonra yeniden hak talebinde bulunmak için işlemi herhangi bir anda durdurabilir. iş parçacığı sonlandırılır. Süreci devam ettirmek için JobService. alıcıdan JobScheduler kullanarak Böylece sistem, sürecin devam ettiğini anlar. Arka Planda Çalışmaya Genel Bakış daha fazla ayrıntı sağlar.

Yayın gönderiliyor

Android, uygulamaların yayın göndermek için üç yol sunar:

  • sendOrderedBroadcast(Intent, String) yöntemi, her seferinde bir alıcıya yayın gönderir. Her alıcı devam ederken sonucu bir sonraki alıcıya iletebilir veya diğer kullanıcılara iletilmemesi için yayını tamamen iptal edebilir. alıcı'lar. Alıcıların çalıştırıldığı sıra, Eşleşen amaç filtresinin android:öncelik özelliği; daha fazla aynı öncelik rastgele bir sırada çalıştırılır.
  • sendBroadcast(Intent) yöntemi, tüm alıcılara tanımlanmamış bir sırada yayınlar. Buna Normal adı verilir Yayınla. Bu daha verimlidir ancak alıcıların okuyamadığını gösterir. diğer alıcılardan gelen sonuçları göndermek, yayından alınan verileri yaymak veya yayını iptal edebilir.

Aşağıdaki kod snippet'i, Amaç ve sendBroadcast(Intent) çağrısı.

Kotlin

Intent().also { intent ->
    intent.setAction("com.example.broadcast.MY_NOTIFICATION")
    intent.putExtra("data", "Nothing to see here, move along.")
    sendBroadcast(intent)
}

Java

Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data", "Nothing to see here, move along.");
sendBroadcast(intent);

Yayın mesajı bir Intent nesnesine sarmalanmış. Niyetin işlem dizesi, uygulamanın Java paket adı söz dizimini sağlamalı ve benzersiz bir şekilde tanımlar. Web sitemiz g.co/newsinitiative/labs üzerinden putExtra(String, Bundle) ile amaca göre şekillendirin. Ayrıca bir yayını aynı kuruluştaki bir uygulama grubuyla sınırlayabilirsiniz. setPackage(String) kasıtlı olarak çağrılıyor.

İzinlerle yayınları kısıtlama

İzinler, yayınları muhafaza eden uygulama grubuyla kısıtlamanıza olanak tanır. bazı izinler verebilirsiniz. Gönderen veya erişim için kısıtlama uygulayabilirsiniz. yayın alıcısı.

İzinlerle gönderiliyor

sendBroadcast(Intent, String) numaralı telefonu aradığınızda veya sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) için bir değer belirtebilirsiniz: izin parametresine izin verin. Yalnızca etiketini eklemesi gerekir (ve daha sonra tehlikeli bir durum söz konusuysa) yayını alabilir. Örneğin, aşağıdaki kod bir yayın gönderir:

Kotlin

sendBroadcast(Intent(BluetoothDevice.ACTION_FOUND),
              Manifest.permission.BLUETOOTH_CONNECT)

Java

sendBroadcast(new Intent(BluetoothDevice.ACTION_FOUND),
              Manifest.permission.BLUETOOTH_CONNECT)

Yayını almak için alıcı uygulamanın izni şu şekilde istemesi gerekir: aşağıda gösterilmiştir:

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

Mevcut bir sistem iznini, örneğin, BLUETOOTH_CONNECT. veya <permission> öğesi. Örneğin, genel olarak izinler ve güvenlikle ilgili daha fazla bilgi için Sistem İzinler.

İzinlerle alma

Bir yayın alıcısını kaydederken izin parametresi belirtirseniz (registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) ile veya <receiver> etiketi, manifestosunu içeriyorsa), yalnızca <uses-permission> etiketi (ve daha sonra izin verilen bir durum varsa izin verilmişse) tehlikeli) alıcıya bir Intent gönderebilir.

Örneğin, alıcı uygulamanızda aşağıda gösterilmiştir:

<receiver android:name=".MyBroadcastReceiver"
          android:permission="android.permission.BLUETOOTH_CONNECT">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_FOUND"/>
    </intent-filter>
</receiver>

Alıcı uygulamanızın aşağıda gösterildiği gibi bağlama kayıtlı bir alıcısı da vardır:

Kotlin

var filter = IntentFilter(Intent.ACTION_FOUND)
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null )

Java

IntentFilter filter = new IntentFilter(Intent.ACTION_FOUND);
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null );

Ardından, bu alıcılara anons gönderebilmek için gönderen uygulamanın aşağıda gösterildiği gibi izin isteyebilirsiniz:

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

Güvenlikle ilgili olarak göz önünde bulundurulması gerekenler ve en iyi uygulamalar

Aşağıda güvenlikle ilgili göz önüne alınması gereken bazı noktalar ve en iyi uygulamalar belirtilmiştir: yayınları alıyor:

  • Birden fazla uygulama, kendi cihazlarında aynı yayını almak için kaydolmuşsa bunun sonucunda sistemin çok sayıda uygulama başlatmasına hem cihaz performansını hem de kullanıcı deneyimini önemli ölçüde etkiler. Kaçınılması gerekenler manifest beyanı yerine bağlam kaydını kullanmayı tercih edin. Bazen Android sisteminin kendisi bağlama kayıtlı alıcı'lar. Örneğin, CONNECTIVITY_ACTION yayını yalnızca bağlama kayıtlı alıcılara özeldir.

  • Hassas bilgileri üstü kapalı bir amaç kullanarak yayınlamayın. İlgili içeriği oluşturmak için kullanılan bu bilgiler, yayını almak için kaydolan herhangi bir uygulama tarafından okunabilir. Yayınlarınızı kimlerin alabileceğini denetlemenin üç yolu vardır:

    • Yayın gönderirken bir izin belirtebilirsiniz.
    • Android 4.0 ve sonraki sürümlerde, şununla birlikte package: setPackage(String) yayınla. Sistem, yayını eşleştirmeye karar veriyorum.
  • Bir alıcıyı kaydettiğinizde tüm uygulamalar kötü amaçlı olabilecek uygulamanızın alıcısına yayınlar. Arama trafiğini sınırlamanın birkaç yolu vardır. uygulamanızın aldığı yayınlar:

    • Bir yayın alıcısını kaydederken izin belirtebilirsiniz.
    • Manifest tarafından beyan edilen alıcılar için android:exported özelliğini "false" olarak ayarlayın dosyası olarak gönderin. Alıcı şunları almaz: .
  • Yayın işlemleri için ad alanı globaldir. İşlem adlarının ve diğer dizeler size ait bir ad alanında yazıldığından yanlışlıkla diğer uygulamalarla çakışabilir.

  • Alıcının onReceive(Context, Intent) yöntemi şurada çalıştığı için: ana iş parçacığına sahipse yürütülür ve hızlı bir şekilde geri döner. Gerekirse uzun süreli işler yapmak istiyorsanız, ileti dizileri oluşturma veya başlatma aşamasında dikkatli olun. arka plan hizmetlerini kullanabilir çünkü sistem onReceive() iade edildi. Daha fazla bilgi için bkz. İşleme etkisi durum Uzun süreli işler yapabilmek için öneri:

    • goAsync() aranıyor alıcının onReceive() yöntemini kullanmasını ve BroadcastReceiver.PendingResult öğesini bir arka plan ileti dizisine iletmesini gerektirir. Bu işlem, onReceive() konumundan döndükten sonra yayını etkin tutar. Ancak bu yaklaşımda bile sistem, hızlı bir şekilde (10 saniyeden kısa sürede) yayın yapar. Hareket etmeniz için ana iş parçacığında hata oluşmasını önlemek için başka bir iş parçacığına geçin.
    • JobScheduler ile bir iş planlayın. Daha fazla daha fazla bilgi için Akıllı İş Planlama.
  • Kullanıcı deneyimi nedeniyle yayın alıcılarından etkinlik başlatmayın kasvetli, (özellikle birden fazla alıcı varsa). Bunun yerine Bir bildirim görüntüleyerek.