1. Giriş
Telefonlarımızı her yere yanımızda götürüyoruz ancak uygulamaların, deneyimlerini kullanıcının sürekli değişen ortamına ve etkinliğine göre ayarlaması bugüne kadar zordu.
Geçmişte geliştiriciler, yürüme veya araba kullanma gibi bir aktivitenin ne zaman başladığını ya da sona erdiğini belirlemek için çeşitli sinyalleri (konum, sensör vb.) birleştirmek üzere değerli mühendislik zamanı harcıyordu. Daha da kötüsü, uygulamalar kullanıcı etkinliğindeki değişiklikleri bağımsız ve sürekli olarak kontrol ettiğinde pil ömrü olumsuz etkilenir.
Activity Recognition Transition API, tüm işlemleri sizin için yapan ve yalnızca gerçekten ilgilendiğiniz bilgileri (kullanıcının etkinliğinin ne zaman değiştiği) veren basit bir API sağlayarak bu sorunları çözer. Uygulamanız, ilgilendiğiniz etkinliklerdeki geçişlere abone olur ve API, değişiklikler konusunda sizi bilgilendirir.
Örneğin, bir mesajlaşma uygulaması, kullanıcının durumunu meşgul olarak ayarlamak için "Kullanıcı bir araca bindiğinde veya araçtan indiğinde bana bildir" diye sorabilir. Benzer şekilde, bir park yeri algılama uygulaması, kullanıcının park yerini kaydetmek için "Kullanıcı araçtan çıkıp yürümeye başladığında bana söyle" diye sorabilir.
Bu codelab'de, kullanıcının yürüme veya koşma gibi bir etkinliğe ne zaman başladığını/etkinliği ne zaman durdurduğunu belirlemek için Activity Recognition Transition API'yi nasıl kullanacağınızı öğreneceksiniz.
Ön koşullar
Android geliştirme ve geri çağırma işlevleri hakkında bilgi sahibi olmanız gerekir.
Öğrenecekleriniz
- Etkinlik geçişlerine kaydolma
- Bu etkinlikleri işleme
- Artık gerekmediğinde etkinlik geçişleri için kaydı silme
İhtiyacınız olanlar
- Android Studio Bumblebee
- Android cihaz veya emülatör
2. Başlarken
Başlangıç projesi deposunu klonlama
En kısa sürede başlamanız için, üzerine inşa edebileceğiniz bir başlangıç projesi hazırladık. Git yüklüyse aşağıdaki komutu çalıştırmanız yeterlidir. (Terminalde / komut satırında git --version yazarak kontrol edebilir ve doğru şekilde yürütüldüğünü doğrulayabilirsiniz.)
git clone https://github.com/android/codelab-activity_transitionapi
Git'iniz yoksa projeyi zip dosyası olarak alabilirsiniz:
Projeyi içe aktarma
Android Studio'yu başlatın, karşılama ekranında "Open an existing Android Studio project" (Mevcut bir Android Studio projesini aç) seçeneğini belirleyin ve proje dizinini açın.
Proje yüklendikten sonra, Git'in yerel değişikliklerinizin tümünü izlemediğine dair bir uyarı da görebilirsiniz. Bu durumda "Yoksay"ı veya sağ üstteki "X"i tıklayabilirsiniz. (Değişiklikleri Git deposuna geri göndermezsiniz.)
Proje penceresinin sol üst köşesinde, Android görünümündeyken aşağıdaki resme benzer bir görüntü görürsünüz. (Proje görünümündeyken aynı şeyi görmek için projeyi genişletmeniz gerekir.)

İki klasör simgesi (base ve complete) vardır. Bunların her biri "modül" olarak bilinir.
Android Studio'nun projeyi ilk kez arka planda derlemesinin birkaç saniye sürebileceğini unutmayın. Bu süre boyunca Android Studio'nun alt kısmındaki durum çubuğunda bir yükleme simgesi görürsünüz:

Kod değişiklikleri yapmadan önce bu işlemin tamamlanmasını beklemenizi öneririz. Bu işlem, Android Studio'nun gerekli tüm bileşenleri çekmesine olanak tanır.
Ayrıca, "Dil değişikliklerinin geçerli olması için yeniden yükle?" gibi bir istem alırsanız "Evet"i seçin.
Başlangıç projesini anlama
Artık kurulumu tamamladınız ve hareket tanıma özelliğini eklemeye hazırsınız. Bu codelab'in başlangıç noktası olan base modülünü kullanacağız. Diğer bir deyişle, her adımdaki kodu base öğesine eklersiniz.
complete modülü, çalışmanızı kontrol etmek veya sorunlarla karşılaşırsanız başvurmak için kullanılabilir.
Temel bileşenlere genel bakış:
MainActivity: Hareket tanıma için gereken tüm kodu içerir.
Emülatör kurulumu
Android emülatörü kurma konusunda yardıma ihtiyacınız varsa Uygulamanızı çalıştırma başlıklı makaleyi inceleyin.
Başlangıç projesini çalıştırma
Uygulamamızı çalıştıralım.
- Android cihazınızı bilgisayarınıza bağlayın veya bir emülatör başlatın.
- Araç çubuğunda, açılır listeden
baseyapılandırmasını seçin ve yanındaki yeşil üçgen (Çalıştır) düğmesini tıklayın:

- Aşağıdaki uygulamayı görmeniz gerekir:

- Uygulama şu anda mesaj yazdırmanın dışında herhangi bir işlem yapmıyor. Artık hareket tanıma özelliğini ekliyoruz.
Özet
Bu adımda aşağıdaki konular hakkında bilgi edindiniz:
- Codelab için genel kurulum.
- Uygulamamızın temel özellikleri.
- Uygulamanızı dağıtma
3. Kitaplığı inceleyin ve manifeste izin ekleyin
Uygulamanızda Transition API'yi kullanmak için Google Konum ve Hareket Tanıma API'sine bağımlılık beyan etmeniz ve uygulama manifestinde com.google.android.gms.permission.ACTIVITY_RECOGNITION iznini belirtmeniz gerekir.
- build.gradle dosyasında TODO: Review play services library required for activity recognition ifadesini arayın. Bu adım (1. adım) için herhangi bir işlem yapmanız gerekmez. Yalnızca beyan edilen ve gerekli olan bağımlılığı inceleyin. Aşağıdaki gibi görünmelidir:
// TODO: Review play services library required for activity recognition.
implementation 'com.google.android.gms:play-services-location:19.0.1'
basemodülünde,AndroidManifest.xmliçinde TODO: Add both hareket tanıma permissions to the manifest ifadesini arayın ve aşağıdaki kodu<manifest>öğesine ekleyin.
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
Kodunuz artık aşağıdaki gibi görünmelidir:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
...
</manifest>
Yorumlardan da görebileceğiniz gibi, Android 10 için ikinci bir izin eklemeniz gerekiyor. Bu, API sürümü 29'da eklenen çalışma zamanında istenen izin için gereklidir.
İşte bu kadar. Uygulamanız artık hareket tanımayı destekleyebilir. Bu özelliği kullanmak için kodu eklememiz yeterli.
Uygulamayı çalıştır
Uygulamanızı Android Studio'dan çalıştırın. Tamamen aynı görünmelidir. Geçişleri izlemek için henüz herhangi bir kod eklemedik. Bu işlemi sonraki bölümde yapacağız.
4. Android'de çalışma zamanı izinlerini kontrol etme/isteme
API sürümü 28 ve öncesinde izin kapsamındayken API sürümü 29 ve sonrasında çalışma zamanı izinlerini desteklememiz gerekir:
MainActivity.javabölümünde, kullanıcının Android 10 (29) veya sonraki bir sürümü kullanıp kullanmadığı kontrol edilir. Kullanıcı bu sürümlerden birini kullanıyorsa hareket tanıma izinleri kontrol edilir.- İzin verilmezse kullanıcıya, uygulamanın izne neden ihtiyaç duyduğunu açıklayan bir açılış ekranı (
PermissionRationalActivity.java) gösterilir ve izni onaylamasına izin verilir.
Android sürümünü kontrol eden kodu inceleme
base modülünde, MainActivity.java içinde TODO: Review check for devices with Android 10 (29+) ifadesini arayın. Bu kod snippet'ini görmeniz gerekir.
Bu bölüm için herhangi bir işlem yapılmadığını unutmayın.
// TODO: Review check for devices with Android 10 (29+).
private boolean runningQOrLater =
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q;
Daha önce belirtildiği gibi, Android 10 ve sonraki sürümlerde çalışma zamanında istenen izin android.permission.ACTIVITY_RECOGNITION için onay almanız gerekir. Çalışma zamanında istenen izinleri kontrol etmemiz gerekip gerekmediğine karar vermek için bu basit kontrolü kullanırız.
Gerekirse hareket tanıma için çalışma zamanında istenen izin kontrolünü inceleyin
base modülünde, MainActivity.java içinde TODO: Review permission check for 29+ ifadesini arayın. Bu kod snippet'ini görmeniz gerekir.
Bu bölüm için herhangi bir işlem yapılmadığını unutmayın.
// TODO: Review permission check for 29+.
if (runningQOrLater) {
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACTIVITY_RECOGNITION
);
} else {
return true;
}
Çalışma zamanı izinlerini kontrol etmemiz gerekip gerekmediğini görmek için önceki adımda oluşturduğumuz değişkeni kullanırız.
Q ve sonraki sürümlerde, çalışma zamanında istenen izinle ilgili sonucu kontrol edip döndürürüz. Bu, activityRecognitionPermissionApproved() adlı daha büyük bir yöntemin parçasıdır. Bu yöntem, geliştiricinin basit bir çağrıyla izin isteyip istemememiz gerektiğini bilmesini sağlar.
Çalışma zamanı izinleri isteme ve hareket tanıma geçişlerini etkinleştirme/devre dışı bırakma
base modülünde, MainActivity.java bölümünde YAPILACAKLAR: Aktivite izlemeyi etkinleştirin/devre dışı bırakın ve gerekirse izin isteyin ifadesini arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Enable/Disable activity tracking and ask for permissions if needed.
if (activityRecognitionPermissionApproved()) {
if (activityTrackingEnabled) {
disableActivityTransitions();
} else {
enableActivityTransitions();
}
} else {
// Request permission and start activity for result. If the permission is approved, we
// want to make sure we start activity recognition tracking.
Intent startIntent = new Intent(this, PermissionRationalActivity.class);
startActivityForResult(startIntent, 0);
}
Burada, hareket tanıma özelliğinin onaylanıp onaylanmadığını soruyoruz. Bu durum geçerliyse ve hareket tanıma özelliği zaten etkinse bu özelliği devre dışı bırakırız. Aksi takdirde etkinleştiririz.
İzin onaylanmadığında kullanıcıyı, izne neden ihtiyaç duyduğumuzu açıklayan ve izni etkinleştirmesine olanak tanıyan başlangıç ekranı etkinliğine yönlendiririz.
İzin isteği kodunu inceleyin
base modülünde, PermissionRationalActivity.java bölümünde YAPILACAKLAR: Hareket tanıma için izin isteğini inceleyin ifadesini arayın. Bu kod snippet'ini görmeniz gerekir.
Bu bölüm için herhangi bir işlem yapılmadığını unutmayın.
// TODO: Review permission request for activity recognition.
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
PERMISSION_REQUEST_ACTIVITY_RECOGNITION)
Bu, Etkinlik'in en önemli ve incelenmesi gereken kısmıdır. Kod, kullanıcı istediğinde izin isteğini tetikler.
Bunun dışında, PermissionRationalActivity.java sınıfı, kullanıcının hareket tanıma iznini neden onaylaması gerektiğiyle ilgili bir gerekçe gösterir (en iyi uygulama). Kullanıcı, Hayır, teşekkürler düğmesini veya Devam düğmesini (yukarıdaki kodu tetikleyen) tıklayabilir.
Daha fazla bilgi edinmek isterseniz dosyayı inceleyebilirsiniz.
5. Etkinlik geçişleri için alıcıyı kaydetme/kaydını silme
Hareket tanıma kodunu ayarlamadan önce, Etkinliğimizin sistem tarafından oluşturulan geçiş işlemlerini işleyebildiğinden emin olmak istiyoruz.
Geçiş için bir BroadcastReceiver oluşturun
base modülünde, MainActivity.java içinde TODO: Create a BroadcastReceiver to listen for activity transitions (YAPILACAKLAR: Etkinlik geçişlerini dinlemek için bir BroadcastReceiver oluşturun) ifadesini arayın. Aşağıdaki snippet'i yapıştırın.
// TODO: Create a BroadcastReceiver to listen for activity transitions.
// The receiver listens for the PendingIntent above that is triggered by the system when an
// activity transition occurs.
mTransitionsReceiver = new TransitionsReceiver();
Geçiş için bir BroadcastReceiver kaydetme
base modülünde, MainActivity.java içinde TODO: Register a BroadcastReceiver to listen for activity transitions ifadesini arayın. (onStart() içinde bulunur.) Aşağıdaki snippet'i yapıştırın.
// TODO: Register a BroadcastReceiver to listen for activity transitions.
registerReceiver(mTransitionsReceiver, new IntentFilter(TRANSITIONS_RECEIVER_ACTION));
Artık PendingIntent aracılığıyla etkinlik geçişleri oluşturulduğunda güncellemeler alabiliyoruz.
Unregister BroadcastReceiver
base modülünde, MainActivity.java içinde Unregister activity transition receiver when user leaves the app (Kullanıcı uygulamadan çıktığında etkinlik geçişi alıcısının kaydını sil) ifadesini arayın. (onStop() içinde bulunur.) Aşağıdaki snippet'i yapıştırın.
// TODO: Unregister activity transition receiver when user leaves the app.
unregisterReceiver(mTransitionsReceiver);
Activity kapatıldığında alıcının kaydını silmek en iyi uygulamadır.
6. Kurulum etkinliği geçişlerini ayarlama ve güncellemeleri isteme
Etkinlik geçişi güncellemeleri almaya başlamak için şunları uygulamanız gerekir:
- Etkinlik ve geçiş türünü belirten bir ActivityTransitionRequest nesnesi.
- Uygulamanızın bildirim aldığı bir PendingIntent geri araması. Daha fazla bilgi için Bekleyen amaç kullanma başlıklı makaleyi inceleyin.
İzlenecek ActivityTransitions listesi oluşturma
ActivityTransitionRequest nesnesini oluşturmak için izlemek istediğiniz geçişi temsil eden ActivityTransition nesnelerinin bir listesini oluşturmanız gerekir. ActivityTransition nesnesi aşağıdaki verileri içerir:
- DetectedActivity sınıfıyla temsil edilen bir etkinlik türü. Transition API aşağıdaki etkinlikleri destekler:
- ActivityTransition sınıfıyla temsil edilen bir geçiş türü. Geçiş türleri şunlardır:
base modülünde, MainActivity.java içinde TODO: Add activity transitions to track ifadesini arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Add activity transitions to track.
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
Bu kod, izlemek istediğimiz geçişleri daha önce boş olan bir listeye ekler.
PendingIntent oluşturma
Daha önce belirtildiği gibi, ActivityTransitionRequest öğemizde yapılan değişiklikler konusunda uyarılmak istiyorsak PendingIntent öğesine ihtiyacımız var. Bu nedenle, ActivityTransitionRequest öğemizi oluşturmadan önce PendingIntent öğesini oluşturmamız gerekiyor.
base modülünde, MainActivity.java içinde TODO: Initialize PendingIntent that will be triggered when a activity transition occurs ifadesini arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Initialize PendingIntent that will be triggered when a activity transition occurs.
Intent intent = new Intent(TRANSITIONS_RECEIVER_ACTION);
mActivityTransitionsPendingIntent =
PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Artık ActivityTransition işlemlerinden biri gerçekleştiğinde tetikleyebileceğimiz bir PendingIntent'imiz var.
ActivityTransitionRequest oluşturma ve güncellemeleri isteme
ActivityTransitions listesini ActivityTransitionRequest sınıfına ileterek bir ActivityTransitionRequest nesnesi oluşturabilirsiniz.
base modülünde, MainActivity.java içinde İstek oluşturma ve etkinlik değişikliklerini dinleme'yi arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Create request and listen for activity changes.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
Kodu inceleyelim. İlk olarak, etkinlik geçişi listemizden bir ActivityTransitionRequest oluştururuz.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
Ardından, ActivityTransitionRequest örneğinizi ve son adımda oluşturduğumuz PendingIntent nesnemizi requestActivityTransitionUpdates() yöntemine ileterek etkinlik geçişi güncellemelerine kaydoluruz. requestActivityTransitionUpdates() yöntemi, sonraki kod bloğunda gösterildiği gibi başarı veya başarısızlık açısından kontrol edebileceğiniz bir Task nesnesi döndürür:
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
Etkinlik geçişi güncellemelerine başarıyla kaydolduktan sonra uygulamanız, kayıtlı PendingIntent'te bildirimler alır. Kullanıcı düğmeyi tekrar tıkladığında devre dışı bırakıp bırakmayacağımızı/etkinleştirip etkinleştirmeyeceğimizi bilmemizi sağlamak için aktivite izlemenin etkinleştirildiğini belirten bir değişken de ayarlıyoruz.
Uygulama kapatıldığında güncellemeleri kaldırma
Uygulama kapatılırken geçiş güncellemelerini kaldırmamız önemlidir.
base modülünde, MainActivity.java bölümünde Etkinlik değişikliklerini dinlemeyi durdur'u arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Stop listening for activity changes.
ActivityRecognition.getClient(this).removeActivityTransitionUpdates(mActivityTransitionsPendingIntent)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
activityTrackingEnabled = false;
printToScreen("Transitions successfully unregistered.");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions could not be unregistered: " + e);
Log.e(TAG,"Transitions could not be unregistered: " + e);
}
});
Şimdi uygulama kapatılırken yukarıdaki kodu içeren yöntemi çağırmamız gerekiyor.
base modülünde, onPause() içindeki MainActivity.java bölümünde YAPILACAKLAR: Kullanıcı uygulamadan çıktığında etkinlik geçişlerini devre dışı bırakın ifadesini arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Disable activity transitions when user leaves the app.
if (activityTrackingEnabled) {
disableActivityTransitions();
}
Etkinlik geçişlerindeki değişiklikleri izleme işlemi bu kadar. Şimdi güncellemeleri işlememiz gerekiyor.
7. İşleme Etkinlikleri
İstenen etkinlik geçişi gerçekleştiğinde uygulamanız bir Intent geri çağırma alır. ActivityTransitionResult nesnesi, ActivityTransitionEvent nesnelerinin listesini içeren Intent'ten çıkarılabilir. Etkinlikler kronolojik sıraya göre sıralanır. Örneğin, bir uygulama ACTIVITY_TRANSITION_ENTER ve ACTIVITY_TRANSITION_EXIT geçişlerinde IN_VEHICLE etkinlik türünü isterse kullanıcı araba kullanmaya başladığında bir ActivityTransitionEvent nesnesi, başka bir etkinliğe geçtiğinde ise başka bir ActivityTransitionEvent nesnesi alır.
Bu etkinlikleri işleyecek kodu ekleyelim.
base modülünde, daha önce oluşturduğumuz BroadcastReceiver'ın onReceive() bölümündeki MainActivity.java içinde TODO: Extract activity transition information from listener ifadesini arayın. Aşağıdaki kodu yorumun ardından ekleyin.
// TODO: Extract activity transition information from listener.
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
for (ActivityTransitionEvent event : result.getTransitionEvents()) {
String info = "Transition: " + toActivityString(event.getActivityType()) +
" (" + toTransitionType(event.getTransitionType()) + ")" + " " +
new SimpleDateFormat("HH:mm:ss", Locale.US).format(new Date());
printToScreen(info);
}
}
Bu işlem, bilgileri String biçimine dönüştürür ve ekrana yazdırır.
İşlem tamamlandı. Uygulamayı çalıştırmayı deneyin.
ÖNEMLİ NOT: Etkinlik değişikliklerini emülatörde yeniden oluşturmak zor olduğundan fiziksel bir cihaz kullanmanızı öneririz.
Aktivite değişikliklerini izleyebilmelisiniz.
En iyi sonuçları elde etmek için uygulamayı fiziksel bir cihaza yükleyip etrafta dolaşın. :)
8. Kodu İnceleme
Etkinlik geçişlerini izleyen ve bunları ekranda listeleyen basit bir uygulama geliştirdiniz.
Yaptıklarınızı incelemek ve birlikte nasıl çalıştıkları hakkında daha iyi bir fikir edinmek için kodu baştan sona okuyabilirsiniz.