Mobil Programlama

Android

İşin Durumunu Raporlamak

Lisans: Creative Commons 26.11.2020 tarihinde güncellendi
Bakabileceğiniz Etiketler: Eğitmen: Geleceği Yazanlar Ekibi

Bu belgede arka planda çalışan bir iş isteğinin durumunu onu çağıran bileşene nasıl raporlayacağınızı görebilirsiniz. Bu sayede örneğin işin durumunu Activity'nin arayüzünde gösterebilirsiniz. Bu işlem için önerilen yol, işin durumunu bir LocalBroadcastManager kullanarak gönderip almak. LocalBroadcastManager, Intent ile yapılan "broadcast"i sınırlayarak, sadece kendi uygulama bileşenleriniz tarafından alınmasını sağlar.

 

Bir IntentService'ten durum raporlamak

Bir IntentService'ten diğer bileşenlere bir iş isteğinin durumunu raporlamak için öncelikle bir Intent oluşturmalısınız. Bu Intent, ekstra veriler kısmında işin durumuna ilişkin bilgiyi tutacak. İsterseniz bu Intent'e bir eylem (action) ve URI verisi de (data) ekleyebilirsiniz.

Sıradaki adım olarak oluşturduğunuz Intent'i, LocalBroadcastManager.sendBroadcast() metodunu çağırarak gönderebilirsiniz. Bu metot parametre olarak aldığı Intent'i, onu almak için kaydolmuş uygulama bileşenine gönderir. LocalBroadcastManager'in bir örneğini (instance) almak için getInstance() metodunu çağırabilirsiniz.

Kısa bir örnek:

public final class Constants {

    ...
    
    // özel bir Intent eylemi tanımlar
    public static final String BROADCAST_ACTION =
        "org.tcellgy.android.servicesample.BROADCAST";
        
    ...
    
    // durum için Intent'in ekstra veriler
    // kısmına girecek anahtarı tanımlar
    public static final String EXTENDED_DATA_STATUS =
        "org.tcellgy.android.servicesample.STATUS";
        
    ...
}
public class RSSPullService extends IntentService {

    ...
    
    /*
     * Bir Uri nesnesi olan yeni bir Intent oluşturur
     * BROADCAST_ACTION da özel Intent'in eylemidir
     */
    Intent localIntent =
            new Intent(Constants.BROADCAST_ACTION)
            // durumu Intent'in içine yazar           
            .putExtra(Constants.EXTENDED_DATA_STATUS, status);
    // Intent'i uygulamadaki alıcılara yayınlar
    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
    
    ...
}

Bundan sonraki adım, özgün iş isteğini gönderen bileşenin, servis tarafından yayınlanan Intent'i nasıl yöneteceği.

 

IntentService'ten gelen durum yayınlarını almak

Intent nesneleri şeklinde gelen yayınları almak için BroadcastReceiver'dan oluşturduğunuz bir alt sınıfı kullanabilirsiniz. Bu alt sınıfta BroadcastReceiver.onReceive() isimli callback metodunu uyarlamalısınız. Bu metotta BroadcastReceiver.onReceive() metoduna gelen Intent, bir Intent.LocalbroadcastManager tarafından alınır.

Bir örnek:

// IntentService'ten gelen durum güncellemelerini
// alacak BroadcastReceiver
private class ResponseReceiver 
extends BroadcastReceiver {
    // yapılandırıcı metodu private yapmak, keyfî örneklemelerin önüne geçer
    private DownloadStateReceiver() {
    }
    
    // BroadcastReceiver'a almak için kaydolduğu 
    // bir Intent geldiğinde çağrılır
    @override
    public void onReceive(Context context, Intent intent) {
    ...
        /*
         * Burada Intent'ler üzerine iş yapılır
         */
    ...
    }
}

BroadcastReceiver'ı bir kere tanımladıktan sonra, onunla eşleşecek belli eylemler, kategoriler ve veriler için de filtreler tanımlayabilirsiniz. Bunun için bir IntentFilter oluşturmalısınız. İlk kod parçacığı nasıl filtre tanımlayacağınızı gösteriyor:

// fotoğraf gösterecek bir sınıf olsun
public class DisplayActivity extends FragmentActivity {
    ...
    public void onCreate(Bundle stateBundle) {
        ...
        super.onCreate(stateBundle);
        ...
        // filtre BROADCAST_ACTION eylemi için olsun
        IntentFilter mStatusIntentFilter = new IntentFilter(
                Constants.BROADCAST_ACTION);
    
        // HTTP şeması için bir veri filtresi ekleyelim
        mStatusIntentFilter.addDataScheme("http");
        ...

BroadcastReceiver'ı ve IntentFilter'ı sisteme kaydetmek için LocalBroadcastManager'ın bir örneğini almalı ve bu örneği registerReceiver() metoduyla çağırmalısınız. Sıradaki kod parçası bir BroadcastReceiver'ın ve onun IntentFilter'ının kaydedilişini gösteriyor:

// Yeni bir DownloadStateReceiver örnekleyelim
DownloadStateReceiver mDownloadStateReceiver =
        new DownloadStateReceiver();
// DownloadStateReceiver'ı ve onun intent filtelerini kaydedelim
LocalBroadcastManager.getInstance(this).registerReceiver(
        mDownloadStateReceiver,
        mStatusIntentFilter);
...

Tek başına bir BroadcastReceiver birden fazla tipte yayın Intent'ini her birinin kendi eylemleriyle idare edebilir. Bu özellik sayesinde her eylem için başka bir BroadcastReceiver tanımlamaya gerek kalmayan farklı kodlar çalıştırabilirsiniz. Aynı BroadcastReceiver için başka bir IntentFilter tanımlamak isterseniz, yeni bir IntentFilter oluşturun ve registerReceiver() çağrısını tekrar edin. Mesela şöyle:

/*
 * Yeni bir eylem filtresi örnekler.
 * Veri filtresine burada gerek yok
 */
statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);

...

// alıcıyı yeni filtresiyle kaydeder
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
        mDownloadStateReceiver,
        mIntentFilter);

Yayın Intent'inin gönderilmesi bir Activity'yi başlatmaz (start) veya devam ettirmez (resume). Bir Activity için kaydedilen BroadcastReceiver, uygulama arka planda çalıştığı zaman bile Intent nesnelerini alabilir ve işleyebilir. Bunu yaparken uygulamanızı ön plana çıkarmaya zorlamaz. Arka planda gerçekleşen bir olayla ilgili kullanıcıyı bilgilendirmek istiyorsanız, bir Notification kullanabilirsiniz. Asla gelen yayın Intent'ine yanıt vermek için bir Activity başlatmayın.

 

Bu sayfadaki parçalar Android Open Source Project kapsamında oluşturulmuş ve paylaşılmış içeriğin küçük değişiklikler yapılmış hâlidir ve Creative Commons 2.5 Attribution License'ta belirlenen koşullara göre kullanılmıştır.

Bu eğitim içeriğinin orijinal hâline buradan ulaşabilirsiniz: Reporting Work Status