Smart Mirror Wear OS (Android Wear) Uygulama Kodları
Merhaba Arkadaşlar
Smart Mirror projemizde bitiş çizgisindeyiz. Bu son makalede Wear OS (Android Wear) yani akıllı saatimiz için bir uygulama geliştireceğiz. Uygulama akıllı telefondan gelen günlük faaliyeti(leri) kullanıcıya göstermeyi sağlayacaktır.Akıllı saat uygulama arayüzü aşağıdaki gibidir.
Uygulama kodlarına geçmeden önce Wear uygulaması dosya hiyerarşisini göstermek istiyorum.
Geliştireceğimiz kodlar yukarıda verilen sınıflarda olacak. Bu sınıflar ve temel işlevleri aşağıda verilmiştir.
CreateList –> Akıllı telefon uygulamasından alınan günlük faaliyet veya faaliyetleri listelemeyi sağlayan sınıf.
ListenerService –> Akıllı telefondan akıllı saate veri gönderimi yapıldığı anda bu sınıfta bulunan kodlar icra edilir. Wearable Data Layer’dan alınan verilere bu servisten erişim sağlayacağız.
MainActivity –> Wear OS uygulamasının ana sayfası olup burada herhangi bir işlem yapılmayacaktır.
NotesListActivity –> CreateList sınıfını kullanarak gelen faaliyetlerin liste halinde kullanıcıya sunulmasını sağlar. ListenerService sınıfı ile bu activity bileşeni kullanıcıya gösterilir.
Bu kısa bilgilendirmeden sonra uygulama kodlarına geçebiliriz.
CreateList
Akıllı telefondan alınan günlük faaliyetleri listelemeyi sağlayan sınıftır. Bu sınıf BaseAdapter sınıfından extend edilerek belirli bir tasarım ile verileri kullanıcıya göstermeyi sağlar.
Burada verilerin listeleneceği ortak bir tasarım oluşturduk. Kodlar aşağıdaki gibidir:
row_list.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/singleRow" android:layout_width="match_parent" android:layout_height="wrap_content"> <!--ListView için her bir satırın tasarımını tanımladık. Kontrolün her bir satırına 1 adet TextView kontrolü ekledik.--> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Ayarlar" android:padding="5dp" android:gravity="center" android:textColor="@color/black" android:textSize="15sp"/> </RelativeLayout>
CreateList sınıfı kodları şöyledir.
package com.mas.smartmirror.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.mas.smartmirror.R; import java.util.ArrayList; /*BaseAdapter en çok kullanılan ve tercih edilen bir Adapter sınıfıdır. BaseAdapter sınıfını kullanmak için başka bir sınıfın bu sınıftan extend, yani türetilmesi gerekiyor. Bu sınıf, verileri düzene eklemek için kullanılır. Bu sınıf aşağıda verilen dört adet metoda sahiptir. İlk olarak kurucu metot başlatılır. Dışarıdan gelen parametreler sınıf içindeki değişkenlere atanır.*/ public class CreateList extends BaseAdapter { Context ctx; public ArrayList<String> allActivities; /*Kurucu metot ile dışarıdan gelen parametreler alınır*/ public CreateList(Context ctx, ArrayList<String> allActivities) { this.ctx = ctx; this.allActivities = allActivities; } /*Burada kaç adet satır oluşturulacağı tespit edilir. Dizimiz kaç elemanlı ise o kadar oluşturabiliriz.*/ @Override public int getCount() { return allActivities.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View row, ViewGroup parent) { /*Asıl işlemin yapıldığı yer burasıdır. Öncelikle LayoutInflater ile düzeni dolduracak olan xml dosyasına erişim sağlanır. Row_list isimli düzene erişim sağlanır. Bu düzene eriştikten sonra burada bulunan her bir kontrol için atama işlemini yani veriyle doldurmayı sağlarız.*/ LayoutInflater layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = layoutInflater.inflate(R.layout.row_list, parent, false); /*allActivities içinde bulunan veri alınır ve değişkene atanır.*/ String activity = allActivities.get(position); /*Erişim sağlanan kontrollere atama yapılır.*/ TextView textView = row.findViewById(R.id.textView); textView.setText(activity); /*Erişilen row_list düzeni return edilir.*/ return row; } }
Bu işlemle birlikte veriler aşağıdaki gibi kullanıcıya gösterilir.
ListenerService
Akıllı telefondan akıllı saate gelen faaliyet veya faaliyetleri almak ve kullanıcıya göstermek için öncelikle Wearable Data Layer’da meydana gelen veri değişimlerini algılamak gerekiyor. Bunun için kullanacağımız kodlar aşağıdaki gibidir.
package com.mas.smartmirror; import android.content.Intent; import com.google.android.gms.wearable.DataEvent; import com.google.android.gms.wearable.DataEventBuffer; import com.google.android.gms.wearable.DataMap; import com.google.android.gms.wearable.DataMapItem; import com.google.android.gms.wearable.WearableListenerService; /*WearableListenerService: Bu sınıf, veri katmanı olaylarını (data layer event) bir servis içinde dinlemeyi sağlar. Servisin yaşam döngüsü sistem tarafından yönetilir. Veri öğeleri ve mesajları göndermek istediğinizde servise bağlanılır, aksi durumda yani ihtiyaç olmayan durumlarda bağlantı kesilir. Servislerle çalışmak için bu sınıf kullanılır.*/ public class ListenerService extends WearableListenerService { /* onDataChanged(): Data Layer da meydana gelen veri değişiklikleri algılayan metodumuz */ @Override public void onDataChanged(DataEventBuffer dataEventBuffer) { /*Akıllı saatte veri olaylarını kontrol eden döngümüz*/ for (DataEvent event : dataEventBuffer) { /*DataEvent.TYPE_CHANGED: Data Layer üzerinde veri değişikliği olduğunda (örneğin data layer’a yeni bir veri eklendiğinde) yapılacak işlemleri belirlemede kullanılır.*/ if (event.getType() == DataEvent.TYPE_CHANGED) { /*Verinin path bilgisi alınır ve değişkene atanır. Bu bilgi mobil uygulama tarafında geliştirdiğimiz FirstService isimli sınıftan gelmektedir. Bu sınıfta yazdığımız sendWatch() isimli metot içinde bulunan aşağıdaki kod ile path bilgisini "/wearable_data" olarak belirledik. PutDataMapRequest.create("/wearable_data").setUrgent();*/ String path = event.getDataItem().getUri().getPath(); /*Path bilgisi /wearable_data ise, akıllı telefondan faaliyet listesi gönderildiği anlaşılır.*/ if (path.equalsIgnoreCase("/wearable_data")) { /*DataItem yapısında gönderilen faaliyeti dataMap nesnesine atarız*/ DataMap dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); /*Yeni bir intent oluşturduk. Bu intent ile NotesListActivity isimli etkinlik başlatılacaktır.*/ Intent i = new Intent(this, NotesListActivity.class); /*Aldığımız DataMap verisini intent içerisine ekleriz. DataMap doğrudan eklenemediği için toBundle() metodu ile veri Bundle nesnesine dönüştürülür. NotesListActivity isimli etkinlikte veriyi almak için “note” key değerini kullanırız.*/ i.putExtra("note", dataMap.toBundle()); /*Etkinlik için bayrak tanımladık. Her veri değişiminde etkinlik yeniden başlatılır ve gelen yeni veriyi kullanıcıya gösterir. FLAG_ACTIVITY_CLEAR_TASK: Çalışan bir görev varsa temizlemeyi sağlar. FLAG_ACTIVITY_NEW_TASK: Etkinliği yeni bir görev içinde başlatır.*/ i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); /*Etkinlik başlatılır.*/ startActivity(i); } } } } }
Akıllı saat ve akıllı telefon arasında veri iletimini yapmak için oluşturduğumuz bu servisi aşağıdaki gibi manifest dosyasına bildirmeniz gerekiyor. Aksi taktirde veri iletişimi gerçekleşmeyecektir.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mas.smartmirror"> <application ...> <!-- <service android:name=”.ListenerService”> <intent-flter> <action android:name=”com.google.android.gms.wearable.DATA_CHANGED” /> </intent-flter> </service> Servisin mutlaka yukarıdaki gibi bildirilmesi gerekiyor. Bu satırlar ile ListenerService servisi, Wearable Data Layer'da meydan gelecek olan Data yani veri değişimi durumlarınaü duyarlı hale gelecektir.--> <service android:name=".ListenerService"> <intent-filter> <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> <!--Bu servis için bir tane <data> etiketi tanımladık. Burada path bilgisinin /wearable_data olarak belirlendiğine dikkat ediniz. Eğer bunu yapmazsanız Data Change olaylarında bu path ile çalışamayız--> <data android:host="*" android:path="/wearable_data" android:scheme="wear" /> </intent-filter> </service> </application> </manifest>
NotesListActivity
ListenerService ile Wearable Data Layer’dan alınan faaliyetlerin listelenmesini sağlayan sınıftır. Öncelikle arayüz kodlarını paylaşalım.
activity_notes_list.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" tools:deviceIds="wear" android:orientation="vertical"> <!--Başlık etiketi --> <TextView android:id="@+id/myNotes" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/title_notes_list" android:padding="25dp" android:textSize="16sp" android:background="@color/color_red" android:textColor="@color/white" android:textStyle="bold"/> <!--Gelen tüm faaliyetlerin listelendiği kontrol--> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"/> </LinearLayout>
Şimdi Java kodlarımızı paylaşalım.
package com.mas.smartmirror; import android.os.Bundle; import android.support.wearable.activity.WearableActivity; import android.widget.ListView; import com.mas.smartmirror.adapter.CreateList; import java.util.ArrayList; /*ListenerService ile akıllı telefondan gelen faaliyet veya faaliyetler buraya gönderilir.*/ public class NotesListActivity extends WearableActivity { private ArrayList<String> notes = null; private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notes_list); /*Arayüzde bulunan ListView kontrolüne erişim sağlarız. Gelen tüm veriler burada listelenir.*/ listView = findViewById(R.id.listView); /*Başlangıçta listview içeriğini temizliyoruz.*/ listView.setAdapter(null); /*ListenerService ile gönderdiğimiz Bundle nesnesine erişmek için key bilgisi olarak "note" bilgisini kullandık.*/ Bundle data = getIntent().getBundleExtra("note"); /*Eğer data içeriği null değilse,*/ if (data != null) { /*Veriler note key bilgisi ile ArrayList tipindeki notes nesnesine atanır.*/ notes = data.getStringArrayList("note"); } /*CreateList sınıfından bir nesn oluşturulur ve gelen veriler ListView içinde listelenir.*/ listView.setAdapter(new CreateList(getApplicationContext(),notes)); } }
Tüm bu kodlardan sonra verilerimiz aşağıdaki gibi listelenir.
Smart Mirror veya Akıllı Ayna projesi için ihtiyacımız olan tüm kodları sizlerle paylaştım. Sonraki makalede kaynak kodlarının GitHub linkini sizlerle paylaşacağım.