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&lt;String&gt; allActivities;

    /*Kurucu metot ile dışarıdan gelen parametreler alınır*/
    public CreateList(Context ctx, ArrayList&lt;String&gt; 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.