Smart Mirror Mobile Uygulama

Merhaba arkadaşlar!

Smart Mirror projesi için ihtiyacımız olan diğer bir uygulama akıllı telefonumuz için olacaktır. Akıllı telefona yükleyeceğimiz bu uygulama ile Firebase ortamına etkinlik kaydı yapabilir, var olan kayıtları listeleyebilir veya silebiliriz.

Uygulama arayüzü aşağıdaki gibi olacaktır.

 

Uygulama Ana sayfasında (sağda) kayıtlı olan etkinliklerin listelenmesi sağlanır. Burada sağ alt köşede bulunan butona tıkladığımız zaman “Registration Form” (solda) yani Kayıt Formu başlatılır. Bu arayüzü kullanarak etkinliklerinizi kayıt edebilirsiniz.

 

 

Yukarıda verilen resimde ise kayıt formunda bulunan Time ve Date butonlarına tıklandığı zaman başlatılan saat ve takvimi görebilirsiniz.

Mobile uygulamada geliştireceğimiz bir servis ile zamanı gelen bir etkinlik veya etkinlik grubunu akıllı saatimize göndermeyi sağlayacağız. Akıllı saat uygulamasını daha sonraki yazıda geliştireceğiz.

 

 

Mobil uygulama için geliştireceğimiz sınıflar hiyerarşik olarak şu şekilde olacaktır.

 

 

MyAdapter –> Firebase ortamında kayıtlı olan verileri RecyclerView içinde listeleyen sınıf.

DatePickerFragment –> Takvim uygulamasını gösteren sınıf.

TimePickerFragment –> Saat uygulamasını gösteren sınıf.

Note –> Firebase ortamında kayıtlı olan etkinlikleri key, time, date, title ve description olarak ayrıştırmak için kullanacağımız sınıf.

FirstService –> Zamanı gelen bir etkinliği akıllı saate gönderen servis sınıfı.

MainActivity –> Mobil uygulama anasayfası. Bu sınıf ile kayıtlı etkinlikleri listeleyebilir, yeni bir etkinlik ekleyebilir ve var olan bir etkinliği silebiliriz.

SaveActivity –> Faaliyet kaydını yapmayı sağlayan sınıf. Bu sınıfa MainActivity üzerinden erişerek etkinlik kaydını yapacağız.

Mevcut sınıflar hakkında bu kısa bilgilendirmeden sonra bu sırayı takip ederek kodlarımızı paylaşabiliriz.

 

Kütüphanelerin Eklenmesi

Mobil uygulamayı geliştirmek için öncelikle aşağıda verilen dosyayı açalım.

Dosya yapısının build.gradle <mobile> olduğuna dikkat ediniz. Bu gradle dosyası doğrudan mobil uygulamayı ilgilendiriyor.

Dosyayı açınız ve aşağıda verilen alanı ilgili satırları ekleyiniz.

dependencies {
    ...
    compile 'com.google.firebase:firebase-database:15.0.0'
    compile 'com.google.firebase:firebase-crash:15.0.2'
    compile 'com.google.firebase:firebase-auth:15.1.0'
    compile 'com.android.support:cardview-v7:21.0.3'
    compile 'com.android.support:recyclerview-v7:21.0.3'
    compile 'com.google.android.gms:play-services-wearable:15.0.0'
}

Yukarıda eklediğimiz satırlar ile Firebase, CardView, RecyclerView ve son olarak Wearable servisi ile ilgili kütüphaneleri eklemiş oluruz. Firebase işlemlerini daha önce sizlerle paylaştığım Android Things uygulamasında bulabilirsiniz. Burada o kısma girmeyeceğim. Çünkü bahsi geçen yazımda ilgili bilgileri ayrıntılı olarak anlattım. CardView ve RecyclerView kütüphanelerini, kayıtlı olan faaliyetleri listelemek için kulanacağız. Wearable servisi ise akıllı telefondan akıllı saate veri senkronizasyonunu gerçekleştirmek için ekledik.

 

AndroidManifest.xml

Kütüphaneleri ekledikten sonra AndroidManifest dosyasına aşağıdaki izinleri ekleyiniz.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mas.smartmirror">
    <!--İhtiyaç duyulan izinleri ekledik:
    ACCESS_WIFI_STATE,
    INTERNET,
    WAKE_LOCK
    ve ACCESS_NETWORK_STATE-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--Activity bileşeninde olduğu gibi servislerde manifest
        dosyasına eklenmelidir. Servis tanımlamak için <service>
        etiketi kullanılır.  -->
        <service android:name=".FirstService" />

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".SaveActivity"
            android:label="@string/title_activity_save"
            android:theme="@style/Theme.AppCompat.Light.Dialog" />

    </application>

</manifest>

Şimdi kodlara geçebiliriz.

adapter/MyAdapter

Firebase ortamından alınan faaliyetlerin listelenmesini sağlayan sınıftır. Adapter’lar, veri ile görünüm arasındaki bağlantıyı sağlar. RecyclerView kontrolü, esnek bir kullanıma sahip olduğu için RecyclerView.Adapter sınıfını kullanarak bir Adapter geliştirdik.

package com.mas.smartmirror.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.firebase.database.DatabaseReference;
import com.mas.smartmirror.R;
import com.mas.smartmirror.models.Note;

import java.util.ArrayList;

/*RecyclerView.Adapter: Adapter oluşturmak için
bu sınıf kullanılır. Adapter sınıfları, veri ile
AdapterView arasındaki bağlantıyı sağlar.*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    Context ctx;
    private ArrayList<Note> activities = new ArrayList<>();
    DatabaseReference reference;

    /*Kurucu metot ile ihtiyaç duyulan parametreler alınır.*/
    public MyAdapter(Context ctx, ArrayList<Note> activities, DatabaseReference reference) {
        this.ctx = ctx;
        this.activities = activities;
        this.reference = reference;
    }

    /*RecyclerView ve ListView içerisinde periyodik olarak
    findViewById metodunu çağırmak performansı düşürebilir.
    Bundan dolayı bu işlem için ViewHolder sınıfı kullanılır.
    Bu sınıf ile her bir görünüme tag etiketi atanabilir.
    Bu etiket ile çok kolay bir şekilde erişim sağlanır.
    Yani her defasında findViewById metodunu çağrımak
    zorunda kalmayız.*/
    class ViewHolder extends RecyclerView.ViewHolder {

        public TextView tvTimeDate;
        public TextView tvTitleDescription;
        ImageView imgView;

        public ViewHolder(View v) {
            super(v);
            tvTimeDate = v.findViewById(R.id.tvTimeDate);
            tvTitleDescription = v.findViewById(R.id.tvTitleDescription);
            imgView = v.findViewById(R.id.imgView);
        }
    }


    /*Her bir satır temsil edecek arayüz seçilir.
    Burada single_activites arayüzünü geliştirdik.*/
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        /*View nesnesi oluşturulur.*/
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_activites, parent, false);
        /*ViewHolder sınıfından bir nesne türetilir.
        Parametre olarak View nesnesi atanır*/
        ViewHolder vh = new ViewHolder(v);
        /*ViewHolder ile gelen vh nesnemiz döndürülür.*/
        return vh;
    }


    /*Her bir görünümün içeriği belirlenir.*/
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        /*Her bir kontrol için gelen değerler,
        position kullanılarak set edilir.*/
        viewHolder.tvTimeDate.setText(activities.get(position).getTime() + "\n" + activities.get(position).getDate());
        viewHolder.tvTitleDescription.setText(activities.get(position).getTitle() + "\n" + activities.get(position).getDescription());
        viewHolder.imgView.setTag(viewHolder);

        /*single_activites'de bulunan ImageView
        kontrolüne click olayı tanımlanır.
        Tıklandığı zaman ilgili etkinlik
        Firebase ortamında ve cihazdan silinir.*/
        viewHolder.imgView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                reference.child(activities.get(position).getKey()).removeValue();
                activities.remove(position);
                updateList(activities);

            }
        });


    }

    /*Herhangi bir veri eklendiği veya silindiği
    zaman listenin güncellenmesini sağlar. */
    public void updateList(ArrayList<Note> activities) {
        activities = activities;
        notifyDataSetChanged();
    }

    /*Kayıtlı faaliyetlerin sayısı döndürülür*/
    @Override
    public int getItemCount() {
        return activities.size();
    }
}

 

Adapter ile verileri listelerken her bir satır için ortak bir arayüz tasarımı oluşturduk. Arayüz kodları aşağıdaki gibidir.

single_activites.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="3dp"
    card_view:cardBackgroundColor="#fff">

    <LinearLayout
        android:id="@+id/target_info"
        android:layout_width="match_parent"
        android:layout_height="120dip"
        android:orientation="horizontal"
        android:padding="5dp">

        <!--Kayıtlı faaliyetin saat ve tarih bilgisi-->
        <TextView
            android:id="@+id/tvTimeDate"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_margin="2dp"
            android:layout_weight="0.3"
            android:gravity="left"
            android:text="IoT-ignite"
            android:textColor="@color/colorAccent"
            android:theme="@style/textStyle" />

        <!--Kayıtlı faaliyetin başlık ve açıklama bilgisi. -->
        <TextView
            android:id="@+id/tvTitleDescription"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_margin="2dp"
            android:layout_weight="0.6"
            android:gravity="left"
            android:text="Ocak"
            android:textColor="@android:color/black"
            android:theme="@style/textStyle" />

        <!--Seçili faaliyeti silmeyi sağlayacak icon -->
        <ImageView
            android:id="@+id/imgView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_margin="2dp"
            android:layout_weight="0.1"
            android:gravity="left"
            android:src="@drawable/ic_delete_black_24dp"
            android:visibility="visible" />

    </LinearLayout>

</android.support.v7.widget.CardView>

 

Yukarıdaki arayüz ile birlikte veriler aşağıdaki gibi listelenecektir.

 

DatePickerFragment

Kullanıcı yeni bir etkinlik kayıt ederken tarih seçmesini istediğimizde DialogFragment sınıfını kullanabilirsiniz. DatePickerFragment ile aşağıda gösterildiği üzere kullanıcıdan tarih seçmesini isteyen bir arayüz oluşturacağız.

 

package com.mas.smartmirror.dateandtime;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.widget.DatePicker;
import android.widget.TextView;

import com.mas.smartmirror.R;

import java.util.Calendar;

/*DialogFragment: Belirli bir işlemi iletişim penceresi olarak
kullanıcıya sunmayı sağlayan sınıf.
DatePickerDialog.OnDateSetListener: Kullanıcının bir tarih seçtikten
sonra seçilen değerin kullanılmasını sağlayan arayüz.
Bu arayüzü uyguladıktan sonra onDateSet() metodunu eklemeniz gerekiyor.*/
public  class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

    TextView tvDate;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        /*Bu fragment bileşenine SaveActivity sınıfından erişeceğiz.
        Amacımız kullanıcı tarih seçtikten sonra SaveActivity'de
        bulunan tvDate id bilgisine sahip kontrolde tarih bilgisini
        göstermektir. Fragment bileşeninden bu kontrole ulaşabilmek için
        getActivity() metodunu kullanırız. */
        tvDate=getActivity().findViewById(R.id.tvDate);
    }

    /*Fragment için bir Dialog oluşturulur.*/
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Calendar c = Calendar.getInstance();

        /*Sistemden alınan yıl, ay ve gün bilgilerine uyumlu olan
        bir dialog oluşturmayı sağlar.*/
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        /*SaveActivity arayüzünde iletişim penceresi
        halinde olan bir takvim başlatılır.*/
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    /*Kullanıcı tarih seçimini yapıp onayladıktan sonra bu metot çağrılır.*/
    public void onDateSet(DatePicker view, int year, int month, int day) {

        /*Seçilen tarih bilgisi textView kontrolünde gösterilir.
        Burada gün, ay ve yıl bilgileri arasında nokta ekledik.*/
        ++month;
        String month1 = month&lt;10 ? "0"+month : ""+month;
        String day1 = day&lt;10 ? "0"+day : ""+day;
        tvDate.setText(day1+"."+month1+"."+year);
    }
}

 

Uygulamayı çalıştırıp tarihi seçtikten sonra sonuç aşağıdaki gibi olur.

 

 

TimePickerFragment

Kullanıcı yeni bir etkinlik kayıt ederken saati seçmesini istediğimizde DialogFragment sınıfını kullanabilirsiniz. TimePickerFragment ile aşağıda gösterildiği üzere kullanıcıdan saati seçmesini isteyen bir arayüz oluşturacağız.

 

 

package com.mas.smartmirror.dateandtime;

import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.format.DateFormat;
import android.widget.TextView;
import android.widget.TimePicker;

import com.mas.smartmirror.R;

import java.util.Calendar;

/*DialogFragment: Belirli bir işlemi iletişim penceresi olarak
kullanıcıya sunmayı sağlayan sınıf.
TimePickerDialog.OnTimeSetListener: Kullanıcının bir saat seçtikten
sonra seçilen değerin kullanılmasını sağlayan arayüz.
Bu arayüzü uyguladıktan sonra onTimeSet() metodunu eklemeniz gerekiyor.*/
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {

   TextView tvTime;
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        /*Bu fragment bileşenine SaveActivity sınıfından erişeceğiz.
        Amacımız kullanıcı saati seçtikten sonra SaveActivity'de
        bulunan tvTime id bilgisine sahip kontrolde saat bilgisini
        göstermektir. Fragment bileşeninden bu kontrole ulaşabilmek için
        getActivity() metodunu kullanırız. */
        tvTime=getActivity().findViewById(R.id.tvTime);
    }

    /*Fragment için bir Dialog oluşturulur.*/
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        /*Sistemden alınan saat ve dakika bilgilerine uyumlu olan
        bir dialog oluşturmayı sağlar.*/
        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
    }

    /*Kullanıcı saat seçimini yapıp onayladıktan sonra bu metot çağrılır.*/
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

        /*Seçilen saat bilgisi textView kontrolünde gösterilir.
        Burada saat ve dakika bilgileri arasında (:) ekledik.*/
        String hour1 = hourOfDay&lt;10 ? "0"+hourOfDay : ""+hourOfDay;
        String minute1 = minute&lt;10 ? "0"+minute : ""+minute;
        tvTime.setText(hour1+":"+minute1);
    }
}

 

Uygulamayı çalıştırıp saati seçtikten sonra sonuç aşağıdaki gibi olur.

 

 

Note

Firebase veritabanından alınan faaliyetlerin tarih, saat, başlık ve açıklama olarak ayrıştırılmasını sağlayacağımız sınıf. Böylece faaliyet bilgileri üzerinde daha rahat çalışabiliriz.

package com.mas.smartmirror.models;

/*Kayıtlı olan faaliyetleri Note sınıfında
bulunan aşağıdaki parametrelere ayrıştıracağız.*/
public class Note {
    String key;
    String time;
    String date;
    String title;
    String description;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

 

FirstService

Mobil uygulamayı çalıştırdıktan sonra bu servis çalışmaya başlayacak ve varsa günlük faaliyet veya faaliyetleri akıllı saate gönderecek. Böylece kullanıcının günlük etkinliklerden haberdar olması sağlanacak.

FirstService kodları şu şekildedir:

package com.mas.smartmirror;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

import com.google.android.gms.wearable.DataClient;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.mas.smartmirror.models.Note;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/*FirstService sınıfını Service üst sınıfından türettik.
Servisler arkaplanda çalışan ve arayüzleri olamayan uygulama
bileşenleridir.
ChildEventListener: Firebase veritabanında bulunan verilere erişmek
veya veri değişimlerini algılamak için bu arayüzü uyguladık.
Bu arayüzü uyguladıktan sonra aşağıdaki metotların eklenmesi gerek:
onChildAdded
onChildChanged
onChildRemoved
onChildMoved
onCancelled
*/
public class FirstService extends Service implements ChildEventListener {
    private FirebaseDatabase mDatabase;
    private DatabaseReference mReference;
    private ArrayList&lt;Note&gt; mNotes = new ArrayList&lt;&gt;();
    private ArrayList&lt;String&gt; mTodayNote;
    private HashMap&lt;String, Note&gt; mMap = new HashMap&lt;String, Note&gt;();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /*onStartCommand: Activity gibi bir bileşenden startService() metodu
    kullanılarak bir servis başlatıldığı zaman sistem onStartCommand()
    metodunu başlatır. Bu metot servisi süresiz olarak başlatmaya yarar.
    Bu şekilde başlattığınız bir metodu sizin kapatmanız gerekmektedir. */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Toast.makeText(this, "Servis başlatıldı.", Toast.LENGTH_SHORT).show();
        getFirebase();

        /*mynotes JSON dizisinde meydana gelen silme, ekleme vb.
        olayları algılayan bir olay dinleyici tanımladık.*/
        mReference.addChildEventListener(this);

        /*Kayıtlı olan faaliyetleri sürekli kontrol etmek için handler
        ve timer yapılarını kullandık.*/
        final Handler handler1 = new Handler();
        Timer timer1 = new Timer();
        timer1.schedule(new TimerTask() {
            @Override
            public void run() {
                handler1.post(new Runnable() {
                    @Override
                    public void run() {

                        /*Firebase ortamında bulunan faaliyetlerin tarih bilgisi
                        sürekli kontrol edilir. Eğer uygun bir faaliyet varsa
                        sendWatch metodu ile faaliyet bilgisi akıllı saate gönderilir.*/
                        mTodayNote = new ArrayList&lt;&gt;();
                        for (int i = 0; i &lt; mNotes.size(); i++) {
                            if (getCurrentDate().equalsIgnoreCase(mNotes.get(i).getDate())) {
                                mTodayNote.add(mNotes.get(i).getTime() + "\n" + mNotes.get(i).getTitle());

                            }
                        }
                        if (mTodayNote != null) {
                            if (mTodayNote.size() != 0) sendWatch(mTodayNote);
                        }
                    }
                });
            }
        }, 0, 10000);

        return START_STICKY;
    }

    /*onDestroy:Bir servis uzun bir süre kullanılmadığı zaman veya
    kullanıcı servisin yok edilmesini istediği zaman, sistem bu
    metodu başlatır. */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Servis yok edildi.", Toast.LENGTH_SHORT).show();
    }

    private void getFirebase() {
        /*Firebase veritabanına erişim sağlanır.*/
        mDatabase = FirebaseDatabase.getInstance();

        /*Veritabanında bulunan mynotes JSON dizisine erişim sağlanır.*/
        mReference = mDatabase.getReference("mynotes");
    }

    /*Firebase ortamından alınan herbir faaliyet
    Note yapısına ayrıştırılır*/
    public Note parseNote(DataSnapshot item) {
        /*Gelen faaliyet bilgisi key ve value
        bilgisi alınır değişkenlere atanır.*/
        String note = item.getValue(String.class);
        String key = item.getKey();

        /*Hem mobil hem de web uygulamasında tarih,
        saat, başlık ve açıklam verilerini - karakteri
        ile birleştirdik. Burada - karakteri yardımıyla
        value kısmının bir dizi olarak parçalanması
        sağlanır.*/
        String[] separated = note.split("-");

        /*Dizinin ilk sırasında tarih bilgisi bulunur.*/
        String date = separated[0];

        /*Dizinin ikinci sırasında zaman bilgisi bulunur.*/
        String time = separated[1];

        /*Dizinin üçüncü sırasında başlık bilgisi bulunur.*/
        String title = separated[2];

        /*Dizinin son sırasında açıklama bilgisi bulunur.*/
        String description = separated[3];

        /*Note sınıfından bir nesne oluşturup yukarıda
        elde ettiğimiz verileri ilgili parametrelere atadık.*/
        Note n = new Note();
        n.setKey(key);
        n.setTime(time);
        n.setDate(date);
        n.setTitle(title);
        n.setDescription(description);

        /*Son olarak faaliyeti yani Note nesnesini
        return ile gönderdik.*/
        return n;
    }

    /*sendWatch metodu, akıllı telefondan akıllı saate
    veri göndermeyi sağlar.*/
    private void sendWatch(ArrayList&lt;String&gt; n) {
        /*DataClient sınıf ile Wearable Data Layer'a erişim sağlanır*/
        DataClient mDataClient = Wearable.getDataClient(getApplicationContext());

        /*DataMap: Öncelikle DataMap yapısını oluşturmalıyız.
        Bu yapı içerisine, akıllı saate göndermek istediğimiz
        değerleri eklemeliyiz.*/
        DataMap dataMap = new DataMap();

        /*DataMap sınıfı yapı olarak Bundle sınıfında benzer.
        Veriler key-value olarak tutulur. key ifadesinin bu
        veriye erişmek için kullanacağız. Burada key bilgisi
        note olarak belirledik.*/
        dataMap.putStringArrayList("note", n);

        /*DataMap oluşturduktan sonra PutDataMapRequest nesnesi
        oluşturmalıyız. Bu nesnenin temel amacı, iletilecek verinin path yani yol
        bilgisini belirtmektir. Bunun için create() metodu kullanılır.
        Path bilgisini akıllı saatte bu veriye erişmek için kullanacağız.

        setUrgent(): Eğer yapılacak işlem çok önemli ise setUrgent() metodu ile
        işlemin acil olduğunu belirtmelisiniz. setUrgent() metodu çağırılmadığı
        zaman,  sistem yapılan istekleri 30 dakika kadar geciktirebilir.
        Bu maksimum değerdir. Genellikle birkaç dakika içinde işlem yapılır. */
        PutDataMapRequest putDataMapRequest = PutDataMapRequest.create("/wearable_data").setUrgent();

        /*DataMap ile oluşturulan verilerin, PutDataMapRequest nesnesine
        eklenmesi için getDataMap() ve putAll() metotlarını kullanırız.
        İletilecek veriler aşağıdaki gibi nesneye eklenir.*/
        putDataMapRequest.getDataMap().putAll(dataMap);

        /*PutDataMapRequest içinde bulunan verilere sahip olan PutDataRequest
        nesnesi oluşturulur. */
        PutDataRequest putDataReq = putDataMapRequest.asPutDataRequest();

        /*Son olarak veriler akıllı saate gönderilir. */
        mDataClient.putDataItem(putDataReq);
    }

    /*Bu metot mevcut günün tarih bilgisini dd.MM.yyyy formatında
    hesaplamayı sağlar. Firebase ortamında kayıtlı olan bir verinin
    date bilgisi bu metot ile elde edilen değere eşit ise akıllı saate
    bilgi gönderilmesi sağlanır.*/
    private String getCurrentDate() {
        Date date = Calendar.getInstance().getTime();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
        String today = dateFormat.format(date);
        return today;
    }

    /*onChildAdded: Firebase ortamında bulunan mynotes JSON
    dizisine bir veri eklendiğinde bu metot çağrılır.*/
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        /*Eklenen yeni faaliyet önce map sonra listeye eklenir. */
        Note note = parseNote(dataSnapshot);
        mMap.put(dataSnapshot.getKey(), note);
        mNotes.add(note);
    }

    /*onChildChanged: Firebase ortamında kayıtlı bir veride değişim olduğunda çağrılır.*/
    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {

    }

    /*onChildRemoved:Firebase ortamında bulunan mynotes
    JSON dizisinden bir veri silindiğinde bu metot çağrılır.*/
    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        /*Silinen faaliyet map yapısından silinir.*/
        mMap.remove(dataSnapshot.getKey());

        /*Daha sonra listede bulunan tüm faaliyetler silinir.*/
        mNotes.clear();

        /*Son olarak map yapısında kalan tüm faaliyetler
        listeye yeniden eklenir.*/
        for (Map.Entry&lt;String, Note&gt; entry : mMap.entrySet()) {
            mNotes.add(entry.getValue());
        }
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
}

 

MainActivity

MainActivity sınıfını uygulamanın ana sayfasını oluşturmak için kullanacağız. Öncelikle arayüz ile ilgili xml dosyalarının kodlarını paylaşmak istiyorum.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<!--android.support.design.widget.CoordinatorLayout: isminden de
anlaşılacağı üzere, bu düzenin temel amacı, içerisinde bulunan
görünümleri, koordine etmesidir. Yani; görünümler arasında koordineli
bir geçiş yapılmasını sağlamasıdır. Bu düzeni bir iskelet
yapısı olarak düşünebilirsiniz. Yapısı aşağıdaki gibidir.
<CoordinatorLayout>
<AppBarLayout/>
<ScrollView/>
<FloatingActionButton/>
</CoordinatorLayout>
android:fitsSystemWindows=”true” : bu özellik ile düzenimiz
sistem penceresini tamamen doldurur(status bar yani,
durum çubuğu gibi alanları da kapatır. Bu değişimi
görmek için API 21 olan bir cihazda deneyiniz.)-->

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!--AppBarLayout: LinearLayout düzenine benzeyen
    ve görünümleri dikey olarak hizalayan bir
    düzendir. İçerik kaydırıldığı anda, belirli
    bazı parametrelerle görünümleri yönetebilir.-->
    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <!--CollapsingToolbarLayout: Toolbar nesnesini içine
        alan bir düzendir. İçerik yukarı doğru hareket ettirildiği
        zaman içinde bulunan ImageView kontrolünü gizler ve
        ToolBar nesnesini başlık olarak ayarlar. İçerik yukarı
        sürüklendiği zaman, ImageView kontrolünün gizlenmesi için
        app:contentScrim=”?attr/colorPrimary” özelliği eklenmelidir.
        layout_scrollFlags: Bu özellik aşağıdaki değerleri alabilir.
        scroll: içerik yukarı doğru sürüklendiğinde AppBar
        tamamen gizlenir.
        exitUntilCollapsed: scroll ile kullanıldığında,
        resim gizlenir ve toolbar başlık olarak ayarlanır.-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <!--Resim göstermek isterseniz.-->
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@drawable/smart_mirror"
                android:scaleType="centerCrop"
                android:visibility="invisible"
                app:layout_collapseMode="parallax" />

            <!--Toolbar: AppBar Eklemek için kullanılır.
            Burada en önemli özellik
            app:layout_collapseMode=”pin” özelliğidir.
            Eğer bu ayarlamayı yapmazsak,
            AppBar yukarı sürüklendiğinde, menü simgesi gizlenir.-->
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="wrap_content"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <!--NestedScrollView: ScrollView kontrolünün eksiklerini
    gideren daha kullanışlı ve esnek bir scroll kontrolüdür.
    Özellikle bu tür uygulamalar için çok kullanışlıdır.
    Aradaki farkı daha iyi anlamak için android.support.v4.widget.NestedScrollView
    ifadesini silip ScrollView yazıp, uygulamanızı çalıştırınız.
    Diğer bir kullanım sebebi, tek bir ekranda iki adet ScrollView
    kullanılmaz. Fakat yine de ihtiyaç olursa bu kontrol ScrollView
    içerisinde oluşturulabilir. ScrollView ile benzerliği,
    içerisinde tek bir ana kontrolün olmasına izin vermesidir.
    layout_behavior: Verilen değer ile bu özellik eklenmediği
    zaman, içerik uygulamanın en tepesinde gösterilir.-->
    <android.support.v4.widget.NestedScrollView xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <!--Firebase ortamından veriler yüklenene
             kadar kullanıcıya gösterilir-->
            <ProgressBar
                android:id="@+id/pbLoading"
                style="?android:attr/progressBarStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <!--Faaliyetleri listeleyeceğimiz kontrol -->
            <android.support.v7.widget.RecyclerView
                android:id="@+id/my_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:visibility="gone"
                android:scrollbars="vertical" />

        </LinearLayout>


    </android.support.v4.widget.NestedScrollView>

    <!-- FloatingActionButton: Yüzen eylem butonu olarak bilinir.
    Bu menüde öncelikli işlemler bulunur. Bu buton her zaman
    için ekranda gösterilmek için tasarlandığı için
    yüzen buton olarak isimlendirilir. Buradaki kullanım
    amacı SaveActivity etkinlğini başlatarak faaliyet kaydını
    yapmayı sağlamaktır.-->
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="25dp"
        android:src="@drawable/ic_add"/>
</android.support.design.widget.CoordinatorLayout>

 

MainActivity sınıfı için yukarıdaki arayüzü kullanacağız. Tasarımdan sonra kodlarımız aşağıdaki gibidir.

 

package com.mas.smartmirror;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.ProgressBar;
import com.google.android.gms.wearable.DataClient;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.mas.smartmirror.adapter.MyAdapter;
import com.mas.smartmirror.models.Note;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements ChildEventListener, View.OnClickListener {

    private Toolbar mToolbar;
    private ProgressBar mProgressBar;
    private FloatingActionButton mFab;
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private FirebaseDatabase mDatabase;
    private DatabaseReference mReference;
    private ArrayList&lt;Note&gt; mNotes = new ArrayList&lt;&gt;();
    private ArrayList&lt;String&gt; mTodayNote = new ArrayList&lt;&gt;();
    private HashMap&lt;String, Note&gt; mMap = new HashMap&lt;String, Note&gt;();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getControls();
        getFirebase();
        setRecyclerView();
        setEventListener();

        /*Aşağıdaki kodlar ile FirstService sınıfı yani
        servis başlatılır.*/
        Intent i = new Intent(MainActivity.this,FirstService.class);
        startService(i);
    }

    /*activity_main'de bulunan kontrollere erişim sağlanır.*/
    private void getControls() {
        mToolbar = findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        mProgressBar = findViewById(R.id.pbLoading);
        mRecyclerView = findViewById(R.id.my_recycler_view);
        mFab = findViewById(R.id.fab);
    }

    private void getFirebase() {
       /*Firebase veritabanına erişim sağlanır.*/
        mDatabase = FirebaseDatabase.getInstance();

        /*Veritabanında bulunan mynotes JSON dizisine erişim sağlanır.*/
        mReference = mDatabase.getReference("mynotes");
    }

    /*RecyclerView için ihtiyaç duyulan özellikleri
    set eden metodumuz*/
    private void setRecyclerView() {
        /*Bu özelliği set ettiğimizde performansı arttırır.
        Eğer içeriğin değişmesi, RecyclerView düzen boyutunu
        değiştirmiyorsa bu özelliği set edebilirsiniz.*/
        mRecyclerView.setHasFixedSize(true);

        /*Her bir satırın nasıl hizalanacağı belirlenir.
        Her satır dikey olarak hizalanır.*/
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        /*Adapter nesnesi oluşturulur. Parametre olarak
        faaliyetleri tutan liste kullanılır.*/
        mAdapter = new MyAdapter(getApplicationContext(), mNotes, mReference);

        /*RecyclerView, adapter ile doldurulur.*/
        mRecyclerView.setAdapter(mAdapter);
    }

    private void setEventListener() {
        /*mynotes JSON dizisinde meydana gelen silme, ekleme vb.
        olayları algılayan bir olay dinleyici tanımladık.*/
        mReference.addChildEventListener(this);

        /*FloatingActionButton için click olayı tanımladık.*/
        mFab.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.fab:
                /*FloatingActionButton kontrolüne tıklandığı zaman
                SaveActivity arayüzü başlatılır. Kullanıcı bu arayüzü
                kullanarak Firebase ortamına faaliyet kaydını
                yapabilir.*/
                Intent i = new Intent(MainActivity.this, SaveActivity.class);
                startActivity(i);
                break;
        }
    }

    /*Firebase ortamından alınan herbir faaliyet
    Note yapısına ayrıştırılır*/
    public Note parseNote(DataSnapshot item) {
        /*Gelen faaliyet bilgisi key ve value
        bilgisi alınır değişkenlere atanır.*/
        String note = item.getValue(String.class);
        String key = item.getKey();

        /*Hem mobil hem de web uygulamasında tarih,
        saat, başlık ve açıklam verilerini - karakteri
        ile birleştirdik. Burada - karakteri yardımıyla
        value kısmının bir dizi olarak parçalanması
        sağlanır.*/
        String[] separated = note.split("-");

        /*Dizinin ilk sırasında tarih bilgisi bulunur.*/
        String date = separated[0];

        /*Dizinin ikinci sırasında zaman bilgisi bulunur.*/
        String time = separated[1];

        /*Dizinin üçüncü sırasında başlık bilgisi bulunur.*/
        String title = separated[2];

        /*Dizinin son sırasında açıklama bilgisi bulunur.*/
        String description = separated[3];

        /*Note sınıfından bir nesne oluşturup yukarıda
        elde ettiğimiz verileri ilgili parametrelere atadık.*/
        Note n = new Note();
        n.setKey(key);
        n.setTime(time);
        n.setDate(date);
        n.setTitle(title);
        n.setDescription(description);

        /*Son olarak faaliyeti yani Note nesnesini
        return ile gönderdik.*/
        return n;
    }

    /*onChildAdded: Firebase ortamında bulunan mynotes JSON
    dizisine bir veri eklendiğinde bu metot çağrılır.*/
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        /*Eklenen yeni faaliyet önce map sonra listeye eklenir. */
        Note note = parseNote(dataSnapshot);
        mMap.put(dataSnapshot.getKey(), note);
        mNotes.add(note);

        /*Listenin güncellenmesi sağlanır.
        Böylece yeni bir faaliyet eklediğinizde
        arayüzde bulunan listenin uzadığını görürsünüz.*/
        mAdapter.notifyDataSetChanged();
        mProgressBar.setVisibility(View.GONE);
        mRecyclerView.setVisibility(View.VISIBLE);
    }

    /*onChildChanged: Firebase ortamında kayıtlı bir veride değişim olduğunda çağrılır.*/
    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {

    }

    /*onChildRemoved:Firebase ortamında bulunan mynotes
    JSON dizisinden bir veri silindiğinde bu metot çağrılır.*/
    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        /*Silinen faaliyet map yapısından silinir.*/
        mMap.remove(dataSnapshot.getKey());

        /*Daha sonra listede bulunan tüm faaliyetler silinir.*/
        mNotes.clear();

        /*Son olarak map yapısında kalan tüm faaliyetler
        listeye yeniden eklenir.*/
        for (Map.Entry&lt;String, Note&gt; entry : mMap.entrySet()) {
            mNotes.add(entry.getValue());
        }

        /*Silme işleminin arayüzde bulunan ve kullanıcaya
        gösterilen listeye uygulanmasını sağlar.
        Eğer bunu yapmazsanız silinen veri arayüzde
        listelenmeye devam eder.*/
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }

}

 

Bu kodları çalıştırdıktan sonra arayüz aşağıdaki gibi olur.

 

 

Son olarak faaliyet kaydını yapan SaveActivity sınıfının kodlarını paylaşıp bu makaleyi sonlandıralım.

SaveActivity

Kullanıcının faaliyet kaydını yapmasını sağlayan sınıftır. Bu sınıf için arayüz kodları aşağıdaki gibidir.

activity_save.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:padding="8dp"
    tools:context="com.mas.smartmirror.SaveActivity">

    <!--Kullanıcının saat seçmesini sağlayan buton.
    Buna tıkladığımız zaman TimePickerFragment fragment
    bileşeni kullanıcıya gösterilir. Kullanıcı buradan saat
    seçebilir.-->
    <ImageButton
        android:id="@+id/imgTimePicker"
        android:layout_width="@dimen/ic_dimen"
        android:layout_height="@dimen/ic_dimen"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/etDescription"
        android:layout_marginTop="15dp"
        android:background="@drawable/ic_alarm_black_24dp"
        android:text="@string/activity_save_image_button_time" />

    <!--Kullanıcının tarih seçmesini sağlayan buton.
    Buna tıkladığımız zaman DatePickerFragment fragment
    bileşeni kullanıcıya gösterilir. Kullanıcı buradan tarih
    seçebilir.-->
    <ImageButton
        android:id="@+id/imgDatePicker"
        android:layout_width="@dimen/ic_dimen"
        android:layout_height="@dimen/ic_dimen"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@+id/imgTimePicker"
        android:layout_marginEnd="117dp"
        android:layout_marginRight="117dp"
        android:background="@drawable/ic_date_range_black_24dp"
        android:text="@string/activity_save_image_button_date" />

    <!--Bu butona basıldığı zaman led yanar veya led_status ifadesine true değeri atanır-->
    <Button
        android:id="@+id/btnSave"
        android:layout_width="match_parent"
        android:background="@color/colorAccent"
        android:textColor="@color/saveBtnTextColor"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/tvTime"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="16dp"
        android:text="@string/activity_save_btn_save" />

    <!--Faaliyet için başlık girmemizi sağlayan kontrol -->
    <EditText
        android:id="@+id/etTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/edittext_shape"
        android:ems="10"
        android:fontFamily="sans-serif-condensed"
        android:hint="@string/activity_save_title"
        android:inputType="textPersonName"
        android:textColor="#aa001c" />

    <!--Faaliyet için açıklama girmemizi sağlayan kontrol -->
    <EditText
        android:id="@+id/etDescription"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/etTitle"
        android:layout_marginTop="12dp"
        android:background="@drawable/edittext_shape"
        android:ems="10"
        android:fontFamily="sans-serif-condensed"
        android:gravity="left|top"
        android:hint="@string/activity_save_description"
        android:inputType="textMultiLine"
        android:textAlignment="gravity"
        android:textColor="#aa001c"
        android:textDirection="firstStrong" />

    <!--Faaliyet için seçilen saat bilgisi buraya yazılır -->
    <TextView
        android:id="@+id/tvTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imgTimePicker"
        android:layout_toEndOf="@+id/imgTimePicker"
        android:layout_toRightOf="@+id/imgTimePicker"
        android:text="@string/activity_save_image_button_time"
        android:textColor="@color/colorAccent"
        android:textSize="15sp" />

    <!--Faaliyet için seçilen tarih bilgisi buraya yazılır -->
    <TextView
        android:id="@+id/tvDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/tvTime"
        android:layout_alignBottom="@+id/tvTime"
        android:layout_alignLeft="@+id/imgDatePicker"
        android:layout_alignStart="@+id/imgDatePicker"
        android:layout_marginLeft="37dp"
        android:layout_marginStart="37dp"
        android:text="@string/activity_save_image_button_date"
        android:textColor="@color/colorAccent"
        android:textSize="15sp" />

</RelativeLayout>

 

SaveActivity sınıfı kodları aşağıdaki gibidir.

 

package com.mas.smartmirror;

import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.mas.smartmirror.dateandtime.DatePickerFragment;
import com.mas.smartmirror.dateandtime.TimePickerFragment;

public class SaveActivity extends AppCompatActivity implements View.OnClickListener {
    private Button mBtnSave;
    private ImageButton mTimePicker, mDatePicker;
    private FirebaseDatabase mDatabase;
    private DatabaseReference mReference;
    private TextView mTime, mDate;
    private EditText mTitle, mDescription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activitiy_save);
        getControls();
        getFirebase();
        setEventListener();
    }

    /*activity_save arayüzünde bulunan kontrollere
    erişim sağlarız.*/
    private void getControls() {
        mTime = findViewById(R.id.tvTime);
        mDate = findViewById(R.id.tvDate);
        mTitle = findViewById(R.id.etTitle);
        mDescription = findViewById(R.id.etDescription);
        mBtnSave = findViewById(R.id.btnSave);
        mTimePicker = findViewById(R.id.imgTimePicker);
        mDatePicker = findViewById(R.id.imgDatePicker);
    }

    private void getFirebase() {
        /*Firebase veritabanına erişim sağlanır.*/
        mDatabase = FirebaseDatabase.getInstance();

        /*Veritabanında bulunan mynotes JSON dizisine erişim sağlanır.*/
        mReference = mDatabase.getReference("mynotes");
    }

    /*Butonlara tıklama olayı tanımladık*/
    private void setEventListener() {
        mBtnSave.setOnClickListener(this);
        mTimePicker.setOnClickListener(this);
        mDatePicker.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnSave:
                /*btnSave id bilgisine sahip
                butona tıklandığı zaman
                faaliyet kaydı yapılır.*/
                saveMyNote();
                break;

            case R.id.imgTimePicker:
                /*imgTimePicker id bilgisine sahip
                butona tıklandığı zaman
                saat seçimini yapmayı
                sağlayan Fragment açılır.*/
                showTimePickerDialog();
                break;

            case R.id.imgDatePicker:
                /*imgDatePicker id bilgisine sahip
                butona tıklandığı zaman
                tarih seçimini yapmayı
                sağlayan Fragment açılır.*/
                showDatePickerDialog();
                break;

        }
    }

    /*Kullanıcının girdiği başlık, açıklama,
    saat ve tarih bilgileri Firebase ortamına kayıt edilir.*/
    private void saveMyNote() {
        long i = System.currentTimeMillis();
        DatabaseReference newNote = mReference.child(String.valueOf(i));

        /*Veriler arasına - karakteri eklediğimize dikkat ediniz.
        Daha sonra bu karakteri kullanarak split metodu ile bir dizi
        oluşturacağız.*/
        newNote.setValue(mDate.getText().toString()
                + "-" + mTime.getText().toString()
                + "-" + mTitle.getText().toString()
                + "-" + mDescription.getText().toString());

        /*Kayıt işleminden sonra SaveActivity
        sonlandırılır.*/
        finish();
    }

    /*Kullanıcının saat seçebilmesini sağlayan
    showTimePickerDialog fragment bileşeni başlatılır.*/
    public void showTimePickerDialog() {
        DialogFragment newFragment = new TimePickerFragment();
        newFragment.show(getSupportFragmentManager(), "timePicker");

    }

    /*Kullanıcının tarih seçebilmesini sağlayan
    DatePickerFragment fragment bileşeni başlatılır.*/
    public void showDatePickerDialog() {
        DialogFragment newFragment = new DatePickerFragment();
        newFragment.show(getSupportFragmentManager(), "datePicker");
    }
}

 

Uygulama kodlarını yazdıktan sonra kayıt işlemini yapan arayüz aşağıdaki gibi olur.

 

 

Sonraki makalede akıllı saat uygulamasını geliştireceğiz. Görüşmek üzere…