Mobil Programlama

Android

DERS PROGRAMI
Android 301 Ders Programı

Diğer Uygulamaların Sizin Activity'nizi Başlatmasına İzin Vermek

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

Bundan önceki eğitim içeriklerinde genelde şunu yapıyorduk: kendi uygulamamızda başka uygulamaların Activity'sini başlatıyorduk. Uygulamanız başka bir uygulama için kullanışlı olabilecek bir eylemi gerçekleştiriyorsa, onu başka uygulamalardan gelen isteklere yanıt verecek şekilde hazırlamanız gerekir. Örneğin kullanıcının arkadaşlarıyla mesaj veya fotoğraf paylaştığı bir sosyal ağ uygulaması yapıyorsanız, ACTION_SEND Intent'ini desteklemelisiniz ki, kullanıcılar başka bir uygulamadaki "paylaş" eylemini kullandıklarında bu tür eylemleri uygulamanız üzerinden gerçekleştirebilsinler.

Diğer uygulamaların Activity'nizi başlatmasını sağlamak için manifest dosyasında uygun <activity> elementinin içine <intent-filter> elementini koymalısınız.

Uygulamanız cihaza yüklendiğinde, sistem, uygulamanızın Intent filter'ına bakarak buradan ürettiği bilgileri kurulu uygulamaların Intent'lerinden oluşan dâhili bir kataloğa ekler. Başka bir uygulama startActivity() ya da startActivityForResult() metotlarını örtülü (implicit) Intent ile çağırdığında, sistem hangi Activity'lerin çağrıyı cevaplayabileceğini bu kataloğa bakarak bulur.

 

Intent filter ekleme

Activity'nizin karşılayabileceği Intent'leri belirtmek için her birine (Activity'nin kabul ettiği veri ve eyleme özel şekilde) özel intent filter'ı uygun şekilde mümkün mertebe spesifik tanımlamalısınız.

Sistem, eğer Activity'nin aşağıda verilen kriterlere tam uyan intent filter'ı varsa o Activity'ye o anki Intent'i gönderecektir:

 

Action

Gerçekleşecek eylem için string türünden bir isimlendirme. Bunlar genelde platform tarafından gelen ACTION_SEND, ACTION_VIEW gibi değerlerdir.

Bunu intent filter'ınızın içinde <action> elementi ile tanımlayabilirsiniz. Elementin içinde tanımlayacağınız bu değerin API'deki sabitler (aşağıda örneklerini göreceksiniz) yerine, eylemle ilgili tam bir string isim olması gerekiyor.

 

Data

Intent ile ilişkilendirilmiş verinin tanımlaması.

Bunu intent filter'ınızın içinde <data> elementi ile tanımlayabilirsiniz. Bu elementte bir veya birden fazla öznitelik (attribute) kullanacağınızda sadece MIME tipi, URI ön eki, URI şeması veya tüm bunların kombinasyonunu tanımlayabilir ve kabul edilen veri tipini belirtebilirsiniz.

NOT: Eğer veri Uri'si ile ilgili detayları ilan etmeniz gerekmiyorsa, Activity'nizin karşılayabileceği verinin tipini, text/plain ya da image/jpeg gibi sadece android:mimeType özniteliğini kullanarak tanımlamalısınız.

 

Category

Activity'nin karşılayacağı Intent'i karakterize etmek için (genellikle kullanıcının el hareketi veya başlatıldığı yerle ilgili) ek bilgi sağlar. Sistem tarafından desteklenen birkaç farklı kategori de vardır fakat çoğu çok nadiren kullanılır. Bununla beraber varsayılan olarak tüm örtülü (implicit) Intent'ler CATEGORY_DEFAULT ile tanımlanır.

Bunu intent filter'ınızın içine <category> elementi ile tanımlayabilirsiniz.

 

Activity'nizin hangi kriterleri kabul ettiğini <intent-filter> elementinin içinde uygun XML elementleriyle iç içe ilan etmelisiniz.

Aşağıdaki örnekte, ACTION_SEND Intent'ine, veri tipi metin veya resim oldukça karşılık verebilen Activity için tanımlanmış intent filter'ını görüyorsunuz:

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

Uygulamaya gelecek her Intent bir eylem ve bir veri tipiyle gelir. Fakat tanımladığınız her <intent-filter>'ın içinde <action>, <category> ve <data> elementlerinin örneklerini birden fazla ilan edebilirsiniz ki, bu sorun oluşturmayacaktır.

Herhangi iki eylem ve veri çifti birbiriyle çakışıyorsa, onları kabul ettikleri veri tiplerine göre iki ayrı intent filter olarak ayırmalısınız.

Örneğin, Activity'nizin ACTION_SEND ve ACTION_SENDTO Intent'leriyle metin ve resme karşılık verebildiğini varsayın. Böyle bir senaryoda iki ayrı intent filter tanımlamalısınız çünkü ACTION_SENDTO Intent'i send veya sendto Uri şemasını kullanarak, alıcının ismini tanımlarken Uri verisini kullanmaya ihtiyaç duyar. Örneğimizi inceleyelim:

<activity android:name="ShareActivity">
    <!-- metin göndermeye uygun intent-filter; SENDTO eylemini sms URI şemalarıyla kabul eder -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    
    <!-- metin veya resim göndermek için intent-filter; SEND eylemini metin veya resim verisiyle kabul eder -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

NOT: Üstü kapalı (implicit) Intent'leri alabilmek için intent filter'ınıza mutlaka CATEGORY_DEFAULT kategorisini eklemelisiniz. startActivity() ve startActivityForResult() metotları, parametre olarak alacağı Intent'ler ancak CATEGORY_DEFAULT kategorisiyle ilan edilmiş olduğunda işleme koyar. Böyle bir ekleme yapmazsanız üstü kapalı Intent'ler Activity'nizi çözümleyemezler - başka uygulamaların "Paylaş" eylemlerinde sizin uygulamanız listelenmez.

Sosyal paylaşım davranışları gerçekleştirmenize yarayan ACTION_SEND Intent'lerini göndermek ve almak hakkında daha fazla bilgi edinmek istiyorsanız "Diğer Uygulamalardan Veri Almak (Receiving Simple Data from Other Apps)" içeriğine bakınız.

 

Activity içerisinde Intent'in kullanılması

Activity'niz içinde alınacak eyleme karar vermek için öncelikle onu başlatacak olan Intent'i okuyabilmelisiniz. Bunu yapabilmek için Activity'niz başlarken getIntent() metodunu çağırarak onu başlatan Intent'i alabilirsiniz. Bu işlemi Activity'nin herhangi bir yaşam döngüsü olayında yapabilirsiniz fakat genellikle onCreate() ve onStart() gibi ilk sıralarda çalışan callback'ler sırasında yapmanızı öneririz.

Bir örnek:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // bu activity'yi başlatan intent'i alalım
    Intent intent = getIntent();
    Uri data = intent.getData();

    //intent tipipne göre neler yapabileceğimize bakalım
    if (intent.getType().indexOf("image/") != -1) {
        // image verisiyle intent'i kullanalım
    } else if (intent.getType().equals("text/plain")) {
        // metin verisiyle intent'i işleyelim
    }
}

 

Sonuç döndürme

Oluşturduğu Intent ile Activity'nizi çağıran Activity'ye bir sonuç dönmek isterseniz basitçe setResult() metodunu çağırabilir ve sonuç koduyla birlikte sonuç Intent'ini tanımlayabilirsiniz. Bu, şu anlama geliyor: Döneceğiniz sonuç da bir Intent nesnesi ve her sonuca uygun onu diğerlerinden ayırmaya yarayan bir sonuç kodu var.

Sonuç döndürme işlemi tamamlandığında ve kullanıcının orijinal Activity'ye geri dönmesi gerektiğinde finish() metodunu çağırarak Activity'nizi kapatmalısınız. Örneğin:

//sonuç verisi olarak teslim edilecek bir Intent oluşturalım
Intent result = new Intent("org.tcellgy.ornek.RESULT_ACTION", Uri.parse("content://result_uri");
setResult(Activity.RESULT_OK, result);
finish();

Sonuç döndürmek için mutlaka bir "sonuç kodu" tanımlamalısınız. Bu genelde RESULT_OK ya da RESULT_CANCELED gibi bir değer alır ki bunlar Activity sınıfından gelen sabit değerlerdir. Eğer gerekiyorsa bir Intent ile ekstra bilgi sağlayabilirsiniz.

NOT: Sonuç varsayılan olarak RESULT_CANCELED olarak ayarlıdır. Böylece kullanıcı siz sonucu ayarlamadan ve eylemi tamamlamadan önce Geri düğmesine basacak olursa orijinal Activity'ye "iptal edildi" sonucu gönderilir.

Eğer sonuç kodu olarak bir integer değeri döndürmek istiyorsanız, 0'dan büyük herhangi bir değeri kullanabilirsiniz. Sonuç kodu olarak integer kullanacağınızdan, sonuç döndürürken içine Intent'i koymanıza gerek kalmaz; basitçe sonuç kodunu parametre geçerek setResult() metodunu çağırabilirsiniz. Örneğin:

 

setResult(RESULT_COLOR_RED); finish();

 

Böyle yapmayı seçtiğinizde elinizde bir avuç olası sonuç olacak, o da sınıfınızda yerel olarak tanımladığınız integer değer. Böylesi bir yaklaşım, kendi uygulamanızın bir Activity'sine sonuç döndürdüğünüzde gayet iyi çalışacaktır çünkü Activity'niz, sonuç kodlarını belirlemek için kullandığınız public sabit değerleri referans alabilen, kendi uygulamanızın Activity'si.

NOT: Activity'nizin startActivity() ile mi yoksa startActivityForResult() ile mi başlatıldığını doğrulamanıza gerek yoktur. Eğer Activity'nizi başlatan sonuç olarak bir Intent bekliyorsa bekliyorsa basitçe setResult() metodunu çağırabilirsiniz. Eğer meydana getiren Activity startActivityForResult() metodunu çağırmışsa sistem setResult() ile vereceğiniz sonucu ona teslim edecektir. Öteki türlü sonuç göz ardı edilir.

 

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: Allowing Other Apps to Start Your Activity