Blog Tutorial Android Bagi Pemula

Sunday, June 28, 2020

Aplikasi Pengingat Tugas (To Do Reminder) Android

Selamat dini hari! Tutorial kali ini kita akan membuat sebuah aplikasi "Pengingat Tugas" atau dalam bahasa batak nya "To Do Reminder" atau "To Do List". Disini kita akan membutuhkan 5 java class termasuk MainActivity, 3 layout resource termasuk layout activity, dan 5 buah icon. Untuk penyimpanan kita akan menggunakan SQL Database. Sebelumnya blog ini belum pernah membahas secara khusus mengenai penyimpanan SQL Database, dan pada tutorial ini juga kita tidak akan membahasnya secara terperinci.


Baik, langkah pertama yang di lakukan tentunya membuat proyeknya terlebih dahulu. Proyek dalam tutorial ini diberikan nama com.gwnbs.proyek8. Supaya nantinya tidak kewalahan, kita buat dulu 5 buah icon melalui vector asset maker. Anda bisa melihat postingan khusus mengenai cara membuat vector icon pada halaman All Post ini. Berikut screenshoot yang memperlihatkan struktur dan penamaan folder dan file pada proyek ini, serta screenshoot aplikasinya saat di jalankan di emulator.



membuat aplikasi to do list di android
Gambar 1 : Menunjukan struktur dan penamaan folder dan file

Berikutnya kita ke activity_main.xml, disini kita hanya menambahkan 2 komponen yaitu sebuah Listview dan Button floating. Karena disini saya memakai floating action Button, maka diperlukan untuk menambahkan library material implementation 'com.google.android.material:material:1.1.0' ke build.gradle (Module : app) lalu lakukan sync gradle. Berikut isi dari activity_main.xml :

activity_main.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">

    <ListView
        android:id="@+id/itemsList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:layout_marginBottom="50dp"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:paddingLeft="6dp"
        android:paddingRight="6dp"/>
    
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="15dp"
        android:backgroundTint="@android:color/holo_blue_dark"
        android:clickable="true"
        android:focusable="true"
        android:src="@drawable/ic_tambah"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        tools:ignore="UnusedAttribute" />
    
</RelativeLayout>

Selanjutnya kita perlu membuat 2 layout resource baru, yang mana kedua layout ini di fungsikan sebagai custom Listview dan custom AlertDialog. Untuk layout custom Listview diberikan nama daftar_todo.xml dan custom AlertDialog diberi nama custom_dialog_todo.xml. Berikut isi dari masing-masing file layout tersebut :

daftar_todo.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"
    tools:ignore="ContentDescription,
    UselessParent,UseCompoundDrawables,HardcodedText">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp">

        <ImageView
            android:id="@+id/delete"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="16dp"
            android:background="@drawable/ic_hapus" />

        <LinearLayout
            android:id="@+id/titleRow"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="UseCompoundDrawables">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="8dp"
                android:background="@drawable/ic_judul"
                android:tint="@android:color/holo_blue_dark" />

            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_marginBottom="8dp"
                android:text="Judul"
                android:textAllCaps="false"
                android:textSize="18sp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/dateRow"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/titleRow"
            android:orientation="horizontal">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="8dp"
                android:background="@drawable/ic_tanggal" />

            <TextView
                android:id="@+id/dateTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:layout_marginBottom="8dp"
                android:text="Tanggal"
                android:textAllCaps="true"
                android:textSize="12sp" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/dateRow"
            android:orientation="horizontal"
            tools:ignore="UseCompoundDrawables">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="16dp"
                android:background="@drawable/ic_waktu"
                tools:ignore="ContentDescription" />

            <TextView
                android:id="@+id/timeTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:layout_marginBottom="16dp"
                android:text="Waktu"
                android:textAllCaps="true"
                android:textSize="12sp" />

        </LinearLayout>
    </RelativeLayout>
</RelativeLayout>

custom_dialog_todo.xml :
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null"
    android:dividerPadding="0dp"
    android:orientation="vertical"
    android:padding="10dp"
    app:layout_constraintCircleRadius="8dp"
    tools:ignore="UseCompoundDrawables,
    ContentDescription,HardcodedText">

    <LinearLayout
        android:id="@+id/titleLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_judul" />

        <EditText
            android:id="@+id/edit_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:hint="Tugas"
            android:inputType="text"
            tools:ignore="Autofill" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/dateLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/titleLayout"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:background="@drawable/ic_tanggal"/>

        <TextView
            android:id="@+id/date"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Tanggal"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/dateLayout"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:background="@drawable/ic_waktu" />

        <TextView
            android:id="@+id/time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Waktu"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp" />
    </LinearLayout>
</RelativeLayout>




Berikutnya membuat sebuah java class baru sebagai setter dan getter item-item nya, yaitu id, title, date dan time dari aplikasi "Pengingat Tugas" yang segera akan kita selesaikan ini. file ini di beri nama ModelData.java. Berikut isi lengkap dari file ini :

ModelData.java :
package com.gwnbs.proyek8;

public class ModelData {

    int id;
    private String title;
    private String date;
    private String time;

    ModelData(int id, String title, String date, String time) {
        this.id = id;
        this.title = title;
        this.date = date;
        this.time = time;
    }

    int getId() {
        return id;
    }

    String getTitle() {
        return title;
    }

    String getDate() {
        return date;
    }

    String getTime() {
        return time;
    }

}

Langkah berikutnya adalah membuat file java adaptor untuk SQL Database nya. Seperti terlihat pada gambar 1 di atas, file database ini di beri nama DatabaseHelper.java. Fungsinya tentu untuk Create, Read, Update dan Delete (CRUD) data.

DatabaseHelper.java :
package com.gwnbs.proyek8;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String TAG = "DatabaseHelper";

    private static final String TABLE_NAME = "ToDo_Table";
    private static final String COL1 = "ID";
    private static final String COL2 = "Name";
    private static final String COL3 = "Date";
    private static final String COL4 = "Time";

    public DatabaseHelper(Context context) {
        super(context, TABLE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable = "CREATE TABLE " + TABLE_NAME + "("                + COL1 + " integer primary key, "                + COL2 + " TEXT, "                + COL3 + " DATE, "                + COL4 + " TIME" + ")";
        Log.d(TAG, "Creating table " + createTable);
        db.execSQL(createTable);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

        //Memasukkan data ke database
        public boolean insertData(String item, String date, String time) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL2, item);
        contentValues.put(COL3, date);
        contentValues.put(COL4, time);
        Log.d(TAG, "insertData: Inserting " + item + " to " + TABLE_NAME);
        long result = db.insert(TABLE_NAME, null, contentValues);
        db.close();
        return result != -1;
    }

        //Menghapus data dari database
        void deleteData(int id) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_NAME, COL1 + "=" + id, null);
    }

        //Memuat semua data ke listview
        public ArrayList<ModelData> getAllData() {
        ArrayList<ModelData> arrayList = new ArrayList<>();
        SQLiteDatabase db = this.getReadableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME;
        @SuppressLint("Recycle")
        Cursor cursor = db.rawQuery(query, null);

        while (cursor.moveToNext()) {
            int id = cursor.getInt(0);
            String title = cursor.getString(1);
            String date = cursor.getString(2);
            String time = cursor.getString(3);
            ModelData modelData = new ModelData(id, title, date, time);
            arrayList.add(modelData);
        }
        db.close();
        return arrayList;
    }
}

Jika ada kode yang di tandai atau di garis bawahi warna merah (error), abaikan dulu sementara sampai implementasi pembuatan aplikasi ini selesai. Tahap selanjutnya adalah membuat file java adaptor untuk listview. Implementasi penghapusan data dari database juga di lakukan di dalam adaptor ini. File ini diberikan nama ItemAdapter.java. Berikut isi keseluruhan dari file ini.

ItemAdapter.java :
package com.gwnbs.proyek8;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class ItemAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<ModelData> arrayList;

    public ItemAdapter(Context context, ArrayList<ModelData> arrayList) {
        super();
        this.context = context;
        this.arrayList = arrayList;
    }

    @Override
    public int getCount() {
        return this.arrayList.size();
    }

    @Override
    public Object getItem(int position) {
        return arrayList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @SuppressLint({"ViewHolder", "InflateParams"})
    @Override
    public View getView(int position, View convertView, final ViewGroup parent) {
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        assert layoutInflater != null;
        convertView = layoutInflater.inflate(R.layout.daftar_todo, null);
        TextView titleTextView = convertView.findViewById(R.id.title);
        TextView dateTextView = convertView.findViewById(R.id.dateTitle);
        TextView timeTextView = convertView.findViewById(R.id.timeTitle);
        final ImageView delImageView = convertView.findViewById(R.id.delete);
        delImageView.setTag(position);

        //Menghapus tugas dari database saat icon hapus di klik
        delImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final int pos = (int) v.getTag();
                deleteItem(pos);
            }
        });

        ModelData modelData = arrayList.get(position);
        titleTextView.setText(modelData.getTitle());
        dateTextView.setText(modelData.getDate());
        timeTextView.setText(modelData.getTime());
        return convertView;
    }

        //Menghapus tugas dari listview
        private void deleteItem(int position) {
        deleteItemFromDb(arrayList.get(position).getId());
        arrayList.remove(position);
        notifyDataSetChanged();
    }

        //Menghapus tugas dari database
        private void deleteItemFromDb(int id) {
        DatabaseHelper databaseHelper = new DatabaseHelper(context);
        try {
            databaseHelper.deleteData(id);
            toastMsg("Tugas di hapus");
        } catch (Exception e) {
            e.printStackTrace();
            toastMsg("Oppss.. ada kesalahan saat menghapus");
        }
    }

        //Metode pesan toast
        private void toastMsg(String msg) {
        Toast t = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        t.setGravity(Gravity.CENTER,0,0);
        t.show();
    }
}

Dan kelas java terakhir yang perlu dibuat adalah kelas Notifikasi.java. Kelas ini tentunya berfungsi untuk menghantarkan notifikasi ke smartphone pengguna setelah waktu pengingat di setel. Setelah kelas ini di buat, pada AndroidManifest.xml kita perlu melakukan pembaharuan, yaitu dengan menambahkan kelas ini sebagai receiver, juga kita perlu  menambahkan beberapa izin yang di perlukan. Berikut isi lengkap dari masing-masing file ini :

Notifikasi.java :
package com.gwnbs.proyek8;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class Notifikasi extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification-id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = intent.getParcelableExtra(NOTIFICATION);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel notificationChannel = new NotificationChannel(MainActivity.NOTIFICATION_CHANNEL_ID,
                    "Pengingat", importance);
            assert notificationManager != null;
            notificationManager.createNotificationChannel(notificationChannel);
        }
        int id = intent.getIntExtra(NOTIFICATION_ID, 0);
        if (notificationManager != null) {
            notificationManager.notify(id, notification);
        }
    }
}

AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gwnbs.proyek8">

    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <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 android:name=".MainActivity"
            android:label="Daftar Tugas | gwnbs.com">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>



Sekali lagi jika ada kode yang di warnai merah atau error, di abaikan dulu. Kecuali jika sudah selesai tutorial ini dan ada yang di tandai error barulah silahkan mencari dimana letak kesalahan nya.

Baik, tahap terakhir MainActivity.java. Cukup banyak koding yang di lakukan pada file ini, jika di jelaskan bisa panjang urusan nya. Pada setiap metode kodingan sudah saya buat sedikit-sedikit penjelasan nya. Jadi langsung saja berikut isi keseluruhan pada file activity ini :

MainActivity.java :
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.DatePickerDialog;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.widget.AbsListView;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import static java.util.Calendar.MINUTE;

public class MainActivity extends AppCompatActivity {

    public static final String NOTIFICATION_CHANNEL_ID = "10001";
    private final static String default_notification_channel_id = "default";
    private static final String TAG = "MainActivity";
    private DatabaseHelper databaseHelper;
    private ListView itemsListView;
    private FloatingActionButton fab;
    private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.3F);

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

        databaseHelper = new DatabaseHelper(this);
        fab = findViewById(R.id.fab);
        itemsListView = findViewById(R.id.itemsList);

        populateListView();
        onFabClick();
        hideFab();
    }

    //Mengatur notifikasi
    private void scheduleNotification(Notification notification, long delay) {
        Intent notificationIntent = new Intent(this, Notifikasi.class);
        notificationIntent.putExtra(Notifikasi.NOTIFICATION_ID, 1);
        notificationIntent.putExtra(Notifikasi.NOTIFICATION, notification);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getLayoutInflater().getContext().getSystemService(Context.ALARM_SERVICE);
        if (alarmManager != null) {
            alarmManager.set(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
        }
    }

    private Notification getNotification(String content) {

        //Saat notifikasi di klik di arahkan ke MainActivity
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(getLayoutInflater().getContext(), default_notification_channel_id);
        builder.setContentTitle("Pengingat");
        builder.setContentText(content);
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_judul);
        builder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND);
        builder.setChannelId(NOTIFICATION_CHANNEL_ID);
        builder.setPriority(NotificationCompat.PRIORITY_HIGH);
        return builder.build();
    }

    //Memasukkan data ke database
    private void insertDataToDb(String title, String date, String time) {
        boolean insertData = databaseHelper.insertData(title, date, time);
        if (insertData) {
            try {
                populateListView();
                toastMsg("Tugas di tambahkan");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else
             toastMsg("Opps.. terjadi kesalahan saat menyimpan!");
    }

    //Mengambil seluruh data dari database ke listview
    private void populateListView() {
        try {
            ArrayList<ModelData> items = databaseHelper.getAllData();
            ItemAdapter itemsAdopter = new ItemAdapter(this, items);
            itemsListView.setAdapter(itemsAdopter);
            itemsAdopter.notifyDataSetChanged();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //Menyembunyikan tombol floating tambah saat listview di scroll
    private void hideFab() {
        itemsListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (scrollState == SCROLL_STATE_IDLE) {
                    fab.show();
                }else{
                    fab.hide();
                }
            }
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });
    }

    private void onFabClick() {
        try {
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    v.startAnimation(buttonClick);
                    showAddDialog();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //Implementasi klik dari tombol tambah
    @SuppressLint("SimpleDateFormat")
    private void showAddDialog() {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getLayoutInflater().getContext());
        LayoutInflater inflater = this.getLayoutInflater();
        @SuppressLint("InflateParams")
        final View dialogView = inflater.inflate(R.layout.custom_dialog_todo, null);
        dialogBuilder.setView(dialogView);

        final EditText judul = dialogView.findViewById(R.id.edit_title);
        final TextView tanggal = dialogView.findViewById(R.id.date);
        final TextView waktu = dialogView.findViewById(R.id.time);

        final long date = System.currentTimeMillis();
        SimpleDateFormat dateSdf = new SimpleDateFormat("d MMMM");
        String dateString = dateSdf.format(date);
        tanggal.setText(dateString);

        SimpleDateFormat timeSdf = new SimpleDateFormat("hh : mm a");
        String timeString = timeSdf.format(date);
        waktu.setText(timeString);

        final Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());

        //Set tanggal
        tanggal.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(View v) {
                final DatePickerDialog datePickerDialog = new DatePickerDialog(getLayoutInflater().getContext(),
                        new DatePickerDialog.OnDateSetListener() {
                            @SuppressLint("SetTextI18n")
                            @Override
                            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                                String newMonth = getMonth(monthOfYear + 1);
                                tanggal.setText(dayOfMonth + " " + newMonth);
                                cal.set(Calendar.YEAR, year);
                                cal.set(Calendar.MONTH, monthOfYear);
                                cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                            }
                        }, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
                datePickerDialog.show();
                datePickerDialog.getDatePicker().setMinDate(date);
            }
        });

        //Set waktu
        waktu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TimePickerDialog timePickerDialog = new TimePickerDialog(getLayoutInflater().getContext(),
                        new TimePickerDialog.OnTimeSetListener() {
                            @Override
                            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                                String time;
                                @SuppressLint("DefaultLocale") String minTime = String.format("%02d", minute);
                                if (hourOfDay >= 0 && hourOfDay < 12) {
                                    time = hourOfDay + " : " + minTime + " AM";
                                } else {
                                    if (hourOfDay != 12) {
                                        hourOfDay = hourOfDay - 12;
                                    }
                                    time = hourOfDay + " : " + minTime + " PM";
                                }
                                waktu.setText(time);
                                cal.set(Calendar.HOUR, hourOfDay);
                                cal.set(Calendar.MINUTE, minute);
                                cal.set(Calendar.SECOND, 0);
                                Log.d(TAG, "onTimeSet: Time has been set successfully");
                            }
                        }, cal.get(Calendar.HOUR), cal.get(MINUTE), false);
                timePickerDialog.show();
            }
        });

        dialogBuilder.setTitle("Buat tugas baru");
        dialogBuilder.setPositiveButton("Tambah", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                String title = judul.getText().toString();
                String date = tanggal.getText().toString();
                String time = waktu.getText().toString();
                if (title.length() != 0) {
                    try {
                        insertDataToDb(title, date, time);
                        scheduleNotification(getNotification(title), cal.getTimeInMillis());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    toastMsg("Oops, Gak bisa kosong tugas nya.");
                }
            }
        });
        dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.cancel();
            }
        });
        AlertDialog b = dialogBuilder.create();
        b.show();
    }

    //Metode pesan toast
    private void toastMsg(String msg) {
        Toast t = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
        t.setGravity(Gravity.CENTER, 0,0);
        t.show();
    }

    //Mengkonversi bulan dari huruf menjadi angka
    private String getMonth(int month) {
        return new DateFormatSymbols().getMonths()[month - 1];
    }
}

Begitu saja, silahkan langsung di publish ke Google Play Store. Sekian dan terima kasih! Jika ada pertanyaan silahkan di pertanyakan di kolom komentar atau kontak form yang ada di bilah samping kiri.

UPDATE !

Berhubung adanya permintaan repositori github untuk tutorial ini, repositori nya pun sudah dibuat dan dapat di lihat di https://github.com/DaltrayNababan/pengingat.tugas
Share:

20 comments:

  1. apakah ada file nya biar makin mudah dipelajari, soalnya saya masih awam

    ReplyDelete
  2. apakah ada file nya biar makin mudah dipelajari, soalnya saya masih awam

    ReplyDelete
  3. Tidak ada. Saya tidak pernah menyimpan project baik di online seperti github, ataupun saat membuat contoh tutorial file nya langsung saya hapus.

    Nanti seiring waktu juga jadi master kok, yg penting minat dan gak frustasi.

    ReplyDelete
  4. Kok tidak keluar kak notifnya

    ReplyDelete
    Replies
    1. Kenapa bisa begitu, coba diperiksa lagi kelas java notifikasi dan androidmanifest nya apakah sama seperti contoh. Trims

      Delete
    2. Coba bagi dong ka file mentahannya. Please

      Delete
    3. bagi file mentahan nya dong ka,, Pleasee

      Delete
    4. Baik, akan saya buat ulang dulu proyek tutorial ini, nanti saya posting di github, nanti saya kabari ya.

      Delete
    5. Silahkan di cek repositori nya di https://github.com/DaltrayNababan/pengingat.tugas

      Delete
  5. ini apa bisa offline ya?saya coba waktu aplikasinya keluar notifnya tidak keluar waktu offline tapi kalau aplikasinya tetap berjalan notifikasi baru bisa berjalan

    ReplyDelete
    Replies
    1. Bisa gan. Nanti saya coba buatkan dulu repositori github untuk tutorial ini. Nanti silahkan di cek apakah sudah sama apa belum file-file dan isinya.

      Delete
    2. Silahkan di cek repositori nya di https://github.com/DaltrayNababan/pengingat.tugas

      Delete
  6. kak mau tanya dong ini kalau formatnya jadi 24 jam gimana ya, bingung saya

    ReplyDelete
  7. kak kalo tambah update jadi gimana?

    ReplyDelete
  8. kalau nambah fitur edit gimana a kak ? saya coba olah sama tutor yang Contoh Sederhana Menggunakan SQLite Database Android (Aplikasi Catatan) gabisa kak

    ReplyDelete
  9. kak mau tanya kok notifnya tidak ada suaranya ya

    ReplyDelete
  10. kak kok di saya tidak ada suara dari notifnya ya

    ReplyDelete
  11. saya mau bertnya kak,, saya mencoba memodifikasi programnya dengan menambahkan inputan baru berupa catatan tapi ketika saya tambhkan kolom didatabase malah nama kolomnya tidak dikenali.
    errornya seperti ini :
    table ToDo_Table has no column named Note in "INSERT INTO ToDo_Table(Date,Name,Note,Time)

    ReplyDelete
  12. kakk mau tanya ini pakai metode apa ya kak namanya

    ReplyDelete

Hubungi Saya

Name

Email *

Message *

Terlaris 30 Hari Terakhir