• Uncategorized
  • 0

PAB2018-M8-SI-39-04-M.ZAHID SYAFNEL

Bab 8: Memicu, Menjadwalkan, dan Mengoptimalkan Tugas Latar Belakang

8.1: Notifikasi

Tugas 1: Membuat notifikasi dasar

1.1 Membuat Proyek

  1. Buat proyek baru bernama “Notify Me!”, terima opsi default dan gunakan template kosong.
  2. Dalam file activity_main.xml file, ubah elemen rootview ke LinearLayout vertikal dan atribut gravity disetel ke “center”.
  3. Tambahkan tombol dengan atribut berikut ini untuk menggantikan TextView default-nya:
Atribut Nilai
android:id “@+id/notify”
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:text “Notify Me!”
android:layout_margin “4dp”

 

  1. Buat stub metode untuk metode sendNotification(). Metode seharusnya tidak mengambil argumen dan mengembalikan void

 

 

 

 

 

 

  1. Buat variabel anggota untuk Tombol Notifikasi.
  2. Inisialisasi tombol dalam onCreate()dan buat onClickListener untuk tombol tersebut
  3. Panggil sendNotification()dari metode onClick.

 

1.2 Membuat notifikasi pertama

  1. Buka File > New > Image Asset.

 

  1. Dari menu tarik turun Icon Type, pilih Notification Icons.
  2. Klik pada ikon di sebelah item Clip Artuntuk memilih ikon materi yang akan Anda gunakan sebagai ikon untuk notifikasi. Pada contoh ini, Anda bisa menggunakan ikon Android.

 

 

 

  1. Ganti nama ic_android sumber daya dan klik Next and Finish. Ini akan membuat beberapa file drawable dengan resolusi berbeda untuk level API yang berbeda.
  2. Buat variabel anggota di MainActivity untuk menyimpan Pengelola Notifikasi

 

 

 

 

 

 

 

  1. Buat variabel konstanta untuk ID Notifikasi. Karena hanya akan ada satu notifikasi aktif pada satu waktu, kita bisa menggunakan ID yang sama untuk semua notifikasi

 

  1. Buat instance Pengelola Notifikasi dalam onCreate menggunakan getSystemService()

 

 

 

 

 

 

 

 

 

  1. Bangun dan buat instance Builder Notifikasi dalam metode sendNotification()

 

  1. Setel Judul Notifikasi ke “You’ve been notified!”.

 

 

 

 

  1. Setel Teks Notifikasi ke “This is your notification text.”
  2. Setel ikon Notifikasi ke ikon Android yang Anda tambahkan.

 

 

 

 

 

 

 

 

  1. Panggil notify()pada Pengelola Notifikasi di bagian akhir metode sendNotification(), meneruskan ID notifikasi dan notifikasi tersebut:

 

1.3 Menambahkan intent konten

  1. Buat intent eksplisit dalam metode sendNotification()untuk meluncurkan kelas MainActivity:

 

 

 

 

  1. Dapatkan PendingIntent menggunakan getActivity(), yang meneruskan konstanta ID notifikasi untuk requestCode dan menggunakan bendera FLAG_UPDATE_CURRENT:

 

  1. Tambahkan PendingIntent ke Notifikasi menggunakan setContentIntent()dalam NotificationCompat.Builder:

 

 

 

1.4 Tambahkan prioritas dan default ke notifikasi Anda

  1. Tambahkan baris berikut ke Builder Notifikasi untuk menyetel prioritas notifikasi ke HIGH

 

  1. Opsi default dalam Builder digunakan untuk menyetel suara, getar, pola warna LED untuk notifikasi Anda (jika perangkat pengguna memiliki indikator LED). Dalam contoh ini, Anda akan menggunakan opsi default dengan menambahkan baris berikut ke Builder Anda

 

 

 

 

Tugas 2. Memperbarui dan membatalkan notifikasi

2.1 Menambahkan tombol update dan cancel

 

  1. Dalam file layout, buat dua salinan tombol “Notify Me!”.
  2. Ubah atribut teks dalam salinan ke “Update Me!” dan “Cancel Me!”.
  3. Ubah id ke “update” dan “cancel”, berturut-turut.
  4. Buat dia metode dalam MainActivity yang tidak memerlukan parameter dan mengembalikan kosong

 

2.2 Mengimplementasikan metode notifikasi pembatalan dan pembaruan

  1. Unduh di gambar dan letakkan di dalam folder res/drawable.

 

 

  1. Dalam metode updateNotification(), konversi drawable ke bitmap

 

  1. Salin Intent dan PendingIntent yang dibuat dalam sendNotification()ke updateNotification(), karena Anda akan menggunakan PendingIntent yang sama sebagai Intent Content.

 

 

 

  1. Ubah gaya notifikasi dalam NotificationCompat.Builder yang sama, setel gambar dan “Judul Konten Besar”

 

  1. Ubah prioritas Builder ke default agar Anda tidak mendapatkan notifikasi awal saat diperbarui (notifikasi awal hanya dapat ditampilkan dalam gaya default).

 

 

 

 

 

 

 

 

  1. Panggil notify()pada Pengelola Notifikasi, meneruskan ID notifikasi yang sama seperti sebelumnya.

 

2.3 Mengalihkan keadaan tombol

Berikut kode toggle status aktif untuk setiap metode:

onCreate():

mNotifyButton.setEnabled(true);

mUpdateButton.setEnabled(false);

mCancelButton.setEnabled(false);

 

sendNotification():

mNotifyButton.setEnabled(false);

mUpdateButton.setEnabled(true);

mCancelButton.setEnabled(true);

 

updateNotification():

mNotifyButton.setEnabled(false);

mUpdateButton.setEnabled(false);

mCancelButton.setEnabled(true);

 

cancelNotification():

mNotifyButton.setEnabled(true);

mUpdateButton.setEnabled(false);

mCancelButton.setEnabled(false);

 

Tugas 3. Menambahkan tindakan notifikasi

3.1 Mengimplementasikan tindakan “Learn More”

  1. Buat variabel String anggota yang berisi URL ke panduan Desain Material untuk notifikasi:https://developer.android.com/design/patterns/notifications.html.
  2. Buat Intent implisit yang membuka URL tersimpan dalam metodesendNotification()sebelum membuat notifikasi.
  3. Buat PendingIntent dari intent implisit, menggunakan bendera FLAG_ONE_SHOT agar PendingIntent tidak bisa digunakan kembali

 

 

 

 

 

 

 

 

 

  1. Tambahkan ikon dan kode baris ini menggunakan Image Asset Studio, dan sebut ikon ic_learn_more:

 

3.2 Mengimplementasikan tindakan “Update”

  1. Buat subkelas BroadcastReceiver sebagai kelas bagian dalam pada MainActivity dan ganti metode onReceive(). Jangan lupa untuk menyertakan konstruktor kosong

 

 

 

  1. Dalam metode onReceive(), panggil updateNotification().
  2. Buat variabel anggota kontan dalam MainActivity untuk mewakili tindakan notifikasi pembaruan untuk BroadcastIntent. Pastikan variabel dimulai dengan nama paket untuk memastikan keunikannya

 

 

 

 

 

 

 

  1. Buat variabel anggota untuk penerima dan inisialisasikan menggunakan konstruktor default.
  2. Dalam metode onCreate(), daftarkan Penerima Siaran untuk menerima intent ACTION_UPDATE_NOTIFICATION
  3. Ganti metode onDestroy()Aktivitas untuk berhenti mendaftarkan penerima

Buat Tindakan Pembaruan

  1. Buat Intent siaran dalam metode sendNotification()menggunakan tindakan pembaruan khusus.
  2. Dapatkan PendingIntent menggunakan getBroadcast():
  3. Buat ikon ini menggunakan Image Asset Studio, beri nama ic_update.
  4. Tambahkan tindakan ke builder dalam metode sendNotification(), beri judul “Update”

Aplikasi Ketika Dijalankan

 

 

 

Ketika di klik tombol Notify Me

 

Ketika Diklik Update Me

 

 

 

 

Ketika Di Klik Cancel Me

 

Source Code :

AndroidManifest.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.example.android.notifyme”>

<application
android:allowBackup=”true”
android:icon=”@mipmap/ic_launcher”
android:label=”@string/app_name”
android:supportsRtl=”true”
android:theme=”@style/AppTheme”>
<activity android:name=”com.example.android.notifyme.MainActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

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

</manifest>

MainActivity.java

package com.example.android.notifyme;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private NotificationManager mNotifyManager;

private static final int NOTIFICATION_ID = 0;
private static final String NOTIFICATION_GUIDE_URL =
“https://developer.android.com/design/patterns/notifications.html”;
private static final String ACTION_UPDATE_NOTIFICATION =
“com.example.android.notifyme.ACTION_UPDATE_NOTIFICATION”;
private static final String ACTION_CANCEL_NOTIFICATION =
“com.example.android.notifyme.ACTION_CANCEL_NOTIFICATION”;

private Button mNotifyButton;
private Button mUpdateButton;
private Button mCancelButton;

private NotificationReceiver mReceiver = new NotificationReceiver();

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

mNotifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

mNotifyButton = (Button) findViewById(R.id.notify);
mUpdateButton = (Button) findViewById(R.id.update);
mCancelButton = (Button) findViewById(R.id.cancel);

mNotifyButton.setEnabled(true);
mUpdateButton.setEnabled(false);
mCancelButton.setEnabled(true);

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_UPDATE_NOTIFICATION);
intentFilter.addAction(ACTION_CANCEL_NOTIFICATION);
registerReceiver(mReceiver, intentFilter);

mNotifyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification();
}
});

mUpdateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
updateNotification();
}
});

mCancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
cancelNotification();
}
});

}

@Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}


public void sendNotification() {

Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity
(this, NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);

Intent learnMoreIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(NOTIFICATION_GUIDE_URL));
PendingIntent learnMorePendingIntent = PendingIntent.getActivity
(this, NOTIFICATION_ID, learnMoreIntent, PendingIntent.FLAG_ONE_SHOT);

Intent updateIntent = new Intent(ACTION_UPDATE_NOTIFICATION);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, updateIntent, PendingIntent.FLAG_ONE_SHOT);

NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_text))
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(notificationPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.addAction(R.drawable.ic_learn_more, getString(R.string.learn_more),
learnMorePendingIntent)
.addAction(R.drawable.ic_update, getString(R.string.update), updatePendingIntent)
.setDeleteIntent(cancelPendingIntent);

mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());

mNotifyButton.setEnabled(false);
mUpdateButton.setEnabled(true);
mCancelButton.setEnabled(true);

}


private void updateNotification() {

Bitmap androidImage = BitmapFactory.decodeResource(getResources(),R.drawable.mascot_1);

Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity
(this, NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);

Intent learnMoreIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(NOTIFICATION_GUIDE_URL));
PendingIntent learnMorePendingIntent = PendingIntent.getActivity
(this, NOTIFICATION_ID, learnMoreIntent, PendingIntent.FLAG_ONE_SHOT);

NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_text))
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(notificationPendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setDeleteIntent(cancelPendingIntent)
.addAction(R.drawable.ic_learn_more, getString(R.string.learn_more),
learnMorePendingIntent)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle(getString(R.string.notification_updated)));

mNotifyButton.setEnabled(false);
mUpdateButton.setEnabled(false);
mCancelButton.setEnabled(true);

Notification myNotification = notifyBuilder.build();
mNotifyManager.notify(NOTIFICATION_ID, myNotification);

}

private void cancelNotification() {
//Cancel the notification
mNotifyManager.cancel(NOTIFICATION_ID);

//Resets the buttons
mNotifyButton.setEnabled(true);
mUpdateButton.setEnabled(false);
mCancelButton.setEnabled(false);
}


private class NotificationReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action){
case ACTION_CANCEL_NOTIFICATION:
cancelNotification();
break;
case ACTION_UPDATE_NOTIFICATION:
updateNotification();
break;
}
}
}
}

 

Activity_main.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:layout_width=”match_parent”
android:layout_height=”match_parent”
android:gravity=”center”
android:orientation=”vertical”
android:paddingBottom=”@dimen/activity_vertical_margin”
android:paddingLeft=”@dimen/activity_horizontal_margin”
android:paddingRight=”@dimen/activity_horizontal_margin”
android:paddingTop=”@dimen/activity_vertical_margin”
tools:context=”com.example.android.notifyme.MainActivity”>

<Button
android:id=”@+id/notify”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_margin=”4dp”
android:text=”@string/notify_me” />

<Button
android:id=”@+id/update”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_margin=”4dp”
android:text=”@string/update_me” />

<Button
android:id=”@+id/cancel”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_margin=”4dp”
android:text=”@string/cancel_me” />
</LinearLayout>

 

8.2: Alarm Manager

Tugas 1. Menyiapkan Stand Up! Proyek dan Tampilan

1.1 Membuat Stand Up! Layout proyek

  1. Membuat proyek baru bernama “Stand Up!, menerima opsi default dan menggunakan template aktivitas kosong.
  2. Hapus TextView default dan tambahkan elemen berikut:
TextView Atribut Nilai
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:layout_above “@+id/alarmToggle”
android:layout_centerHorizontal “true”
android:layout_margin “8dp”
android:text “Stand Up Alarm”
android:textAppearance @style/TextAppearance.AppCompat.Headline
ToggleButton Atribut Nilai
android:id “@+id/alarmToggle”
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:layout_centerHorizontal “true”
android:layout_centerVertical “true”

1.2 Menyiapkan metode setOnCheckedChangeListener()

  1. Dalam metode MainActivity onCreate(), temukan Alarm Toggle menurut id.
  2. Panggil setOnCheckedChangeListener()pada instance tombol alih, dan mulai mengetik “new OnCheckedChangeListener”. Android Studio akan menyelesaikan metode untuk Anda secara otomatis, termasuk metode penggantian onCheckedChanged() yang diperlukan. Metode ini memiliki dua parameter: CompoundButton yang diklik (dalam kasus ini tombol Toggle Alarm), dan boolean yang mewakili status Tombol Toggle saat ini (yakni, apakah tombol alih saat ini diaktifkan atau dinonaktifkan).

  1. Akan sangat berguna jika pengguna menerima masukan selain tombol alih yang diaktifkan dan dinonaktifkan untuk menujukkan bahwa alarm memang disetel (Anda belum mengimplementasikan alarm, ini akan dilakukan pada bagian berikutnya). Setel blok if/else menggunakan parameter boolean dalam metode onCheckedChanged()yang mengirimkan pesan toast untuk memberi tahu pengguna apakah alarm diaktifkan atau dinonaktifkan. Jangan lupa untuk mengekstrak sumber daya string.

 

Tugas 2. Menyiapkan Notifikasi

2.1 Membuat notifikasi

  1. Buat variabel anggota dalam MainActivity bernama mNotificationManager dari tipe NotificationManager.
  2. Inisialisasikan dalam onCreate()dengan memanggil getSystemService()

Intent Konten Notifikasi

  1. Buat Intent dalam onCreate()yang akan Anda gunakan untuk Intent Konten notifikasi

 

 

  1. Buat PendingIntent dari Intent konten tepat di bawah definisi contentIntent menggunakan metode getActivity(), meneruskan ID notifikasi dan menggunakan FLAG_UPDATE_CURRENT flag

Judul dan Teks Notifikasi

  1. Buat sumber daya string dalam file strings.xml bernama notification_title. Setel agar setara dengan “Stand Up Alert”.
  2. Buat sumber daya string dalam file strings.xml bernama notification_text. Setel agar setara dengan “You should stand up and walk around now!”.

Ikon Notifikasi

  1. Tambahkan aset gambar untuk digunakan sebagai ikon notifikasi (gunakan Image Asset Studio). Pilih ikon apa pun yang Anda rasa cocok untuk alarm ini:

 

 

 

 

 

 

 

 

 

 

Buat notifikasi

  1. Gunakan NotificationCompat.Builder untuk membuat notifikasi dalam metode deliverNotification()menggunakan judul, teks, ikon, dan intent konten notifikasi di atas.
  2. Setel prioritas Notifikasi ke PRIORITY_HIGH

 

 

 

 

 

  1. Tambahkan opsi ke builder untuk menyetel AutoCancel ke true, dan opsi lainnya untuk menggunakan lampu, suara dan pola getar default

 

Kirim notifikasi

  1. Gunakan NotificationManager untuk mengirimkan notifikasi:
  2. Panggil deliverNotification()saat tombol alih alarm diaktifkan, meneruskan konteks aktivitas:
  3. Panggil cancelAll()pada NotificationManager jika tombol alih dinonaktifkan untuk menghapus notifikasi.

 

 

Tugas 3. Membuat Alarm Berulang

3.1 Menyiapkan intent tertunda siaran

  1. Buat konstanta string sebagai variabel anggota dalam MainActivity untuk digunakan sebagai tindakan intent siaran yang akan mengirimkan notifikasi
  2. Buat Intent bernama notifyIntent dalam onCreate()dengan string khusus sebagai tindakannya

 

  1. Buat PendingIntent notifikasi menggunakan konteks, variabel NOTIFICATION_ID, intent notifikasi baru, dan bendera PendingIntent UPDATE_CURRENT

 

3.2 Menyetel alarm berulang

  1. Inisialisasi AlarmManager dalam onCreate()dengan memanggil getSystemService()
  2. Dalam metode onCheckedChanged(), panggil setInexactRepeating()pada instance alarm manager saat pengguna mengeklik “ON” pada Alarm (Parameter keduanya adalah true). Anda akan menggunakan alarm setInexactRepeating() karena lebih efisien sumber daya untuk menggunakan penentuan waktu yang tidak tepat (sistem dapat membundel alarm dari beberapa aplikasi yang berbeda) dan alarm tidak perlu pas berulang setiap 15 menit. Metode setInexactRepeating()mengambil 4 argumen:
  3. Jenis alarm. Pada kasus ini Anda menggunakan tipe waktu yang sudah lewat sejak boot, karena hanya waktu relatif yang penting. Anda juga akan mengaktifkan perangkat jika tertidur, sehingga jenis alarmnya adalah ELAPSED_REALTIME_WAKEUP.
  4. Waktu pemicu dalam milidetik. Untuk ini, gunakan waktu yang sudah lewat, plus 15 menit. Untuk mendapatkan waktu yang sudah lewat, Anda bisa memanggil elapsedRealtime(). Lalu Anda bisa menggunakan konstanta AlarmManager untuk menambahkan 15 menit ke waktu yang sudah lewat: AlarmManager.INTERVAL_FIFTEEN_MINUTES.
  5. Interval waktu dalam milidetik. Anda ingin agar notifikasi diposting setiap 15 menit. Anda bisa menggunakan konstanta AlarmManager.INTERVAL_FIFTEEN_MINUTES lagi.
  6. PendingIntent yang akan dikirim. Anda membuat PendingIntent pada tugas sebelumnya
  7. Hapus panggilan ke deliverNotification()dalam metode onCheckedChanged().
  8. Jika tombol alih alarm dinonaktifkan (dengan mengeklik toggle dalam status ON), batalkan alarm dengan memanggil cancel()pada AlarmManager, yang meneruskan intent tertunda yang digunakan untuk membuat alarm.

 

 

 

3.3 Membuat Penerima Siaran

  1. Dalam Android Studio, klik File > New > Other > Broadcast Receiver.
  2. Masukkan AlarmReceiver sebagai namanya, pastikan kotak centang Exported sudah tidak dicentang (untuk memastikan aplikasi lain tidak dapat memanggil Penerima Siaran ini). Anda juga bisa mengubah setelan ini dalam AndroidManifest dengan menyetel atribut android:exportedke false. Android Studio akan membuat subkelas BroadcastReceiver dengan metode yang diperlukan (onReceive()), dan menambahkan penerima ke AndroidManifest. Anda mungkin perlu menambahkan Filter Intent ke tag <receiver> dalam AndroidManifest untuk memilih Intent Siaran masuk yang tepat.
  3. Dalam Manifes Android, buat <intent-filter>tag pembuka dan penutup di antara tag <receiver>buat sebuah item <action> dalam filter maksud dengan android:name disetel ke string tindakan ACTION_NOTIFY khusus yang Anda buat

 

  1. Salin dan tempel metode deliverNotification()ke metode onReceive() dalam BroadcastReceiver dan panggil dari onReceive(). Pengelola notifikasi dan id notifikasi belum diinisialisasi dalam kelas BroadcastReceiver jadi akan disorot dengan warna merah.
  2. Salin variabel NOTIFICATION_ID dari MainActivity ke dalam kelas BroadcastReceiver.
  3. Inisialisasi NotificationManager di awal metode onReceive(). Anda harus memanggil getSystemService() dari yang diteruskan dalam Konteks

3.5 Memeriksa Status Alarm

  1. Buat boolean yang benar jika PendingIntent tidak null, dan sebaliknya salah, menggunakan strategi ini. Gunakan boolean untuk menyetel status ToggleButton dengan benar saat aplikasi dimulai. Kode ini harus datang sebelum PendingIntent dibuat, atau kode akan selalu mengembalikan benar

 

 

 

  1. Setel keadaan tombol alih segera setelah Anda mendefinisikan boolean alarmUp

 

 

Tampilan menjalankan Aplikasi

 

 

 

Source Code

AndroidManifest.xml

<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.example.android.standup”>

<application
android:allowBackup=”true”
android:icon=”@mipmap/ic_launcher”
android:label=”@string/app_name”
android:supportsRtl=”true”
android:theme=”@style/AppTheme”>
<activity android:name=”.MainActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

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

<receiver
android:name=”.AlarmReceiver”
android:enabled=”true”
android:exported=”false”>
</receiver>
</application>

</manifest>

 

 

 

AlarmReceiver.java

package com.example.android.standup;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;

public class AlarmReceiver extends BroadcastReceiver {

private static final int NOTIFICATION_ID = 0;

public AlarmReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);

//Create the content intent for the notification, which launches this activity
Intent contentIntent = new Intent(context, MainActivity.class);
PendingIntent contentPendingIntent = PendingIntent.getActivity
(context, NOTIFICATION_ID, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);

//Build the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_stand_up)
.setContentTitle(context.getString(R.string.notification_title))
.setContentText(context.getString(R.string.notification_text))
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL);

//Deliver the notification
notificationManager.notify(NOTIFICATION_ID, builder.build());
}

}

 

MainActivity.java

package com.example.android.standup;

import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.widget.CompoundButton;
import android.widget.Toast;
import android.widget.ToggleButton;

public class MainActivity extends AppCompatActivity {

private NotificationManager mNotificationManager;

private static final int NOTIFICATION_ID = 0;

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

mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
final AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

ToggleButton alarmToggle = (ToggleButton) findViewById(R.id.alarmToggle);

//Set up the Notification Broadcast Intent
Intent notifyIntent = new Intent(this, AlarmReceiver.class);

//Check if the Alarm is already set, and check the toggle accordingly
boolean alarmUp = (PendingIntent.getBroadcast(this, 0, notifyIntent,
PendingIntent.FLAG_NO_CREATE) != null);

alarmToggle.setChecked(alarmUp);

//Set up the PendingIntent for the AlarmManager
final PendingIntent notifyPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

alarmToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
String toastMessage;
if(isChecked){
long triggerTime = SystemClock.elapsedRealtime()
+ AlarmManager.INTERVAL_FIFTEEN_MINUTES;

long repeatInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;

//If the Toggle is turned on, set the repeating alarm with a 15 minute interval
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
triggerTime, repeatInterval, notifyPendingIntent);

//Set the toast message for the “on” case
toastMessage = getString(R.string.alarm_on_toast);
} else {
//Cancel the alarm and notification if the alarm is turned off
alarmManager.cancel(notifyPendingIntent);
mNotificationManager.cancelAll();

//Set the toast message for the “off” case
toastMessage = getString(R.string.alarm_off_toast);
}

//Show a toast to say the alarm is turned on or off
Toast.makeText(MainActivity.this, toastMessage, Toast.LENGTH_SHORT)
.show();
}
});

}
}

 

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:id=”@+id/activity_main”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:paddingBottom=”@dimen/activity_vertical_margin”
android:paddingLeft=”@dimen/activity_horizontal_margin”
android:paddingRight=”@dimen/activity_horizontal_margin”
android:paddingTop=”@dimen/activity_vertical_margin”
tools:context=”com.example.android.standup.MainActivity”>

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_above=”@+id/alarmToggle”
android:layout_centerHorizontal=”true”
android:layout_margin=”8dp”
android:text=”@string/toggle_label”
android:textAppearance=”@style/TextAppearance.AppCompat.Headline” />

<ToggleButton
android:id=”@+id/alarmToggle”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerHorizontal=”true”
android:layout_centerVertical=”true” />

</RelativeLayout>

 

 

Strings.xml

<resources>
<string name=”app_name”>Stand Up!</string>
<string name=”alarm_on_toast”>Stand Up Alarm On!</string>
<string name=”alarm_off_toast”>Stand Up Alarm Off!</string>
<string name=”notification_title”>Stand Up Alert!</string>
<string name=”notification_text”>You should stand up and walk around now!</string>
<string name=”toggle_label”>Stand Up Alarm</string>
</resources>

 

8.3: Job Scheduler

Tugas 1. Mengimplementasikan JobService

1.1 Membuat Proyek dan NotificationJobService

  1. Gunakan template kosong, dan buat proyek baru bernama “Notification Scheduler”.
  2. Buat kelas baru bernama NotificationJobService yang memperluas JobService.

 

 

 

 

 

  1. Tambahkan metode yang diperlukan: onStartJob()dan onStopJob().
  2. Dalam file AndroidManfiest.xml, daftarkan JobService dengan izin berikut dalam tag <application>

 

 

 

1.2 Mengimplementasikan onStartJob()

  1. Tambahkan ikon notifikasi untuk notifikasi “Job Running”.
  2. Dalam onStartJob(), buat PendingIntent untuk meluncurkan MainActivity aplikasi untuk digunakan sebagai intent konten untuk notifikasi Anda.

 

 

  1. Dalam onStartJob(), konstruksi dan kirimkan notifikasi dengan atribut berikut:
Atribut Judul
Content Title “Job Service”
Content Text “Your Job is running!”
Content Intent contentPendingIntent
Small Icon R.drawable.ic_job_running
Priority NotificationCompat.PRIORITY_HIGH
Defaults NotificationCompat.DEFAULT_ALL
AutoCancel true

 

 

 

 

 

 

  1. Pastikan onStartJob()mengembalikan false, karena semua pekerjaan diselesaikan dalam callback itu.
  2. Buat onStopJob()mengembalikan true, agar pekerjaan dijadwalkan ulang jika gagal.

 

Tugas 2. Mengimplementasikan kondisi kerja

2.1 Mengimplementasikan batasan jaringan

  1. Dalam file activity_main.xml, ubah elemen rootview ke LinearLayout vertical.
  2. Ubah TextView agar memiliki atribut berikut:
Atribut Nilai
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:text “Network Type Required: “
android:textAppearance “@style/TextAppearance.AppCompat.Subhead”
android:layout_margin “4dp”

 

  1. Tambahkan elemen kontainer RadioGroup di bawah TextView dengan atribut berikut:
Atribut Nilai
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:orientation “horizontal”
android:id “@+id/networkOptions”
android:layout_margin “4dp”

 

  1. Tambahkan tiga RadioButton sebagai anak ke RadioGroup dengan tinggi dan lebar layout yang disetel ke “wrap_content” dan atribut berikut ini:
RadioButton 1
android:text “None”
android:id “@+id/noNetwork”
android:checked true
RadioButton 2
android:text “Any”
android:id “@+id/anyNetwork”
RadioButton 3
android:text “Wifi”
android:id “@+id/wifiNetwork”

 

  1. Tambahkan dua tombol di bawa grup tombol radio dengan tinggi dan lebar yang disetel ke “wrap_content” dengan atribut berikut ini:
Button 1
android:text “Schedule Job”
android:onClick “scheduleJob”
android:layout_gravity “center_horizontal”
android:layout_margin “4dp”
Button 2
android:text “Cancel Jobs”
android:onClick “cancelJobs”
android:layout_gravity “center_horizontal”
android:layout_margin “4dp”

 

 

  1. Tambahkan stub metode untuk kedua metode onClick()di MainActivity.

 

 

 

 

 

 

 

 

 

 

Dapatkan opsi jaringan pilihan

  1. Dalam scheduleJob(), temukan RadioGroup menurut id dan simpan dalam variabel instance bernama networkOptions.
  2. Dapatkan id jaringan pilihan dan simpan dalam variabel integer

 

  1. Buat variabel integer opsi jaringan pilihan dan setel agar setara dengan opsi jaringan default (jaringan tidak diperlukan)

 

 

 

 

 

  1. Buat pernyataan switch dengan id jaringan pilihan, dan tambahkan kasus untuk setiap id yang mungkin

 

  1. Tetapkan opsi jaringan pilihan ke konstanta jaringan JobInfo yang sesuai, tergantung kasusnya

 

 

 

 

 

 

 

 

Buat JobScheduler dan objek JobInfo

  1. Dalam MainActivity, buat variabel anggota untuk JobScheduler, dan inisialisasikan di scheduleJob()menggunakan getSystemService():

 

  1. Buat konstanta anggota untuk JOB_ID, dan setel agar setara dengan 0.

 

 

 

 

 

  1. Buat objek Builderdalam scheduleJob(). Konsruktor untuk kelas JobInfo.Buildermemerlukan dua parameter:
  • ComponentName untuk JobService yang Anda buat. ComponentName digunakan untuk mengidentifikasi JobService dengan objek JobInfo.

 

  1. Panggil setRequiredNetworkType()pada objek JobInfo.Builder, meneruskan opsi jaringan pilihan

 

 

 

 

  1. Panggil schedule()pada objek JobScheduler, meneruskan objek JobInfo dengan metode build()

 

 

  1. Tampilkan pesan Toast, beri tahu pengguna bahwa pekerjaan dijadwalkan.

 

 

 

  1. Dalam metode cancelJobs(), periksa apakah objek JobScheduler adalah null, dan jika tidak, panggil cancelAll()pada metode untuk menghapus semua pekerjaan yang tertunda, setel ulang JobScheduler ke null, dan tampilkan pesan Toast untuk memberi tahu pengguna bahwa pekerjaan dibatalkan

 

2.2 Memeriksa batasan

  1. Buat variabel boolean bernama constraintSet yang true jika opsi jaringan pilihannya bukan default JobInfo.NETWORK_TYPE_NONE

 

 

 

  1. Buat blok if/else menggunakan boolean constraintSet.
  2. Pindahkan kode yang menjadwalkan tugas dan menampilkan pesan Toast ke dalam blok if.
  3. Jika constraintSetadalah false, tampilkan pesan Toast ke pengguna untuk menyetel paling tidak satu batasan. Jangan lupa untuk mengekstrak sumber daya string

 

 

2.3 Mengimplementasikan batasan Device Idle dan Device Charging

  1. Dalam file activity_main.xml, salin TextView label jenis jaringan dan salin di bawah RadioGroup.
  2. Ubah atribut android:textke “Requires:”.
  3. Di bawah textview ini, sisipkan LinearLayout horizontal dengan margin 4dp.
  4. Buat dua tampilan Switch sebagai anak bagi LinearLayout horizontal dengan tinggi dan lebar yang disetel ke “wrap_content” dan atribut berikut ini:
Switch 1
android:text “Device Idle”
android:id “@+id/idleSwitch”
Switch 2
android:text “Device Charging”
android:id “@+id/chargingSwitch”

Tambahkan kode untuk batasan baru

  1. Dalam MainActivity, buat variabel anggota, mDeviceIdledan mDeviceCharging, untuk switch dan inisialisasikan switch di onCreate().
  2. Dalam metode scheduleJob(), tambahkan panggilan berikut untuk menyetel batasan pada JobScheduler berdasarkan pilihan pengguna dalam switch
  3. Perbarui kode yang menyetel constraintSetuntuk mempertimbangkan batasan baru ini

 

2.4 Mengimplementasikan batasan Batas Waktu Pengganti

  1. Buat LinearLayout horizontal di bawah LinearLayout yang ada dengan switch-nya, yang akan berisi label untuk SeekBar.
  2. SeekBar akan memiliki dua label: label statis seperti label untuk RadioGroup tombol, dan label dinamis yang akan diperbarui dengan nilai dari SeekBar. Tambahkan dua TextView ke LinearLayout dengan atribut berikut ini:
TextView 1
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:text “Override Deadline: “
android:id “@+id/seekBarLabel”
android:textAppearance “@style/TextAppearance.AppCompat.Subhead”
TextView 2
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:text “Not Set”
android:id “@+id/seekBarProgress”
android:textAppearance “@style/TextAppearance.AppCompat.Subhead”

 

 

  1. Tambahkan tampilan SeekBar di bawah LinearLayout dengan atribut berikut ini:
Atribut Nilai
android:layout_width “match_parent”
android:layout_height “wrap_content”
android:id “@+id/seekBar”
android:layout_margin “4dp”

 

 

Tulis kode untuk menambahkan batas waktu

  1. Dalam MainActivity, buat variabel anggota untuk SeekBar dan inisialisasikan di onCreate()

 

 

 

 

 

  1. Buat variabel akhir untuk kedua TextView (yang akan diakses dari kelas bagian dalam) dan inisialisasikan di onCreate()

 

  1. Dalam onCreate(), panggil setOnSeekBarChangeListener()di SeekBar, yang meneruskan OnSeekBarChangeListener baru (Android Studio harus membuat metode yang diperlukan)

 

 

 

 

 

 

  1. Argumen kedua onProgressChanged()adalah nilai saat ini dari SeekBar. Dalam callback onProgressChanged(), periksa apakah nilai integer lebih besar dari 0 (berarti nilai telah ditetapkan oleh pengguna), dan jika iya, setel label kemajuan SeekBar ke nilai integer, yang diikuti dengan “s” untuk menunjukkan detik

 

  1. Jika tidak, setel TextView agar terlihat sebagai “Not Set”

 

 

 

 

 

 

 

  1. Batas waktu pengganti seharusnya hanya disetel jika nilai integer SeekBar lebih besar dari 0. Dalam metode scheduleJob(), buat integer untuk menyimpan kemajuan SeekBar dan variabel boolean yang true jika SeekBar memiliki nilai integer yang lebih besar dari 0.

 

  1. Jika boolean ini true, panggil setOverrideDeadline()pada JobInfo.Builder, yang meneruskan nilai integer dari SeekBar dikalikan 1000 (parameter dalam milidetik, Anda menginginkan agar pengguna menyetel batas waktu dalam detik)

 

 

 

 

 

 

  1. Modifikasi boolean constraintSetuntuk menyertakan nilai seekBarSet sebagai kemungkinan batasan

 

2.5 Mengimplementasikan batasan Periodik

  1. Dalam activity_main.xml, tambahkan tampilan Switch di antara dua LinearLayout horizontal. Gunakan atribut-atribut berikut:
Atribut Nilai
android:layout_width “wrap_content”
android:layout_height “wrap_content”
android:text “Periodic”
android:id “@+id/periodicSwitch”
android:layout_margin “4dp”

 

 

 

 

 

 

 

 

 

  1. Buat variabel anggota untuk switch dan inisialisasikan di onCreate()

 

 

 

 

 

 

 

 

 

 

 

Buat kode untuk menggunakan Periodic Switch

  1. Panggil setOnCheckedChangeListener()pada switch periodik, yang meneruskan OnCheckedChangeListener baru.
  2. Jika dicentang, setel label ke “Periodic Interval: “, jika tidak, ke “Override Deadline: “:

 

Yang tersisa sekarang adalah mengimplementasikan logika dalam metode scheduleJob() untuk menyetel batasan pada objek JobInfo dengan benar.

Jika opsi periodiknya adalah on:

  • Jika SeekBar memiliki nilai non-zero, setel batasan dengan memanggil setPeriodic()pada objek JobInfo.Builder.
  • Jika SeekBar memiliki nilai 0, tampilkan pesan Toast yang meminta pengguna untuk menyetel interval periodik dengan SeekBar.

Jika opsi periodiknya adalah off:

  • Jika SeekBar memiliki nilai selain nol, pengguna telah menyetel batas waktu pengganti. Aplikasikan batas waktu pengganti menggunakan opsi setOverrideDeadline().
  • Jika SeekBar memiliki nilai 0, pengguna belum menentukan batas waktu pengganti atau tugas periodik, jadi jangan tambahkan apa pun ke objek JobInfo.Builder.
  • Ganti kode yang menyetel batas waktu pengganti ke JobInfo.Builder dalam scheduleJob()dengan kode berikut untuk mengimplementasikan logika ini

 

 

 

 

Tampilan Ketika Aplikasi Dijalankan :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Source Code:

AndroidManifest.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.example.android.notificationscheduler”>

<application
android:allowBackup=”true”
android:icon=”@mipmap/ic_launcher”
android:label=”@string/app_name”
android:supportsRtl=”true”
android:theme=”@style/AppTheme”>
<activity android:name=”.MainActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<service
android:name=”.NotificationJobService”
android:permission=”android.permission.BIND_JOB_SERVICE”/>
</application>

</manifest>

 

MainActivity.java

package com.example.android.notificationscheduler;

import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private static final int JOB_ID = 0;

private JobScheduler mScheduler;

private Switch mDeviceIdleSwitch;
private Switch mDeviceChargingSwitch;
private Switch mPeriodicSwitch;

private SeekBar mSeekBar;

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

mDeviceIdleSwitch = (Switch) findViewById(R.id.idleSwitch);
mDeviceChargingSwitch = (Switch) findViewById(R.id.chargingSwitch);
mPeriodicSwitch = (Switch) findViewById(R.id.periodicSwitch);

mSeekBar = (SeekBar) findViewById(R.id.seekBar);

Button scheduleJobButton = (Button) findViewById(R.id.scheduleJobButton);
Button cancelJobButton = (Button) findViewById(R.id.cancelJobsButton);

final TextView label = (TextView) findViewById(R.id.seekBarLabel);
final TextView seekBarProgress = (TextView) findViewById(R.id.seekBarProgress);

mPeriodicSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked){
label.setText(R.string.periodic_interval);
} else {
label.setText(R.string.override_deadline);
}
}
});

mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean userSet) {
if (progress > 0){
String progressLabel = getString(R.string.seekbar_label, progress);
seekBarProgress.setText(progressLabel);
} else {
seekBarProgress.setText(R.string.not_set);
}
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

scheduleJobButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scheduleJob();
}
});

cancelJobButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
cancelJobs();
}
});
}

private void scheduleJob() {
mScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);

RadioGroup networkOptions = (RadioGroup) findViewById(R.id.networkOptions);

int selectedNetworkID = networkOptions.getCheckedRadioButtonId();

int selectedNetworkOption = JobInfo.NETWORK_TYPE_NONE;
switch(selectedNetworkID){
case R.id.noNetwork:
selectedNetworkOption = JobInfo.NETWORK_TYPE_NONE;
break;
case R.id.anyNetwork:
selectedNetworkOption = JobInfo.NETWORK_TYPE_ANY;
break;
case R.id.wifiNetwork:
selectedNetworkOption = JobInfo.NETWORK_TYPE_UNMETERED;
break;
}

ComponentName serviceName = new ComponentName(getPackageName(),
NotificationJobService.class.getName());
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceName)
.setRequiredNetworkType(selectedNetworkOption)
.setRequiresDeviceIdle(mDeviceIdleSwitch.isChecked())
.setRequiresCharging(mDeviceChargingSwitch.isChecked());

int seekBarInteger = mSeekBar.getProgress();
boolean seekBarSet = seekBarInteger > 0;
if (mPeriodicSwitch.isChecked()){
if (seekBarSet){
builder.setPeriodic(seekBarInteger * 1000);
} else {
Toast.makeText(MainActivity.this, R.string.no_interval_toast,
Toast.LENGTH_SHORT).show();
}
} else {
if (seekBarSet) {
builder.setOverrideDeadline(seekBarInteger * 1000);
}
}

boolean constraintSet = selectedNetworkOption != JobInfo.NETWORK_TYPE_NONE
|| mDeviceChargingSwitch.isChecked() || mDeviceIdleSwitch.isChecked()
|| seekBarSet;

if(constraintSet) {
JobInfo myJobInfo = builder.build();
mScheduler.schedule(myJobInfo);
Toast.makeText(this, R.string.job_scheduled, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.no_constraint_toast, Toast.LENGTH_SHORT).show();
}
}

/**
* onClick method for cancelling all existing jobs
*/
private void cancelJobs() {
if (mScheduler != null){
mScheduler.cancelAll();
mScheduler = null;
Toast.makeText(this, R.string.jobs_canceled, Toast.LENGTH_SHORT).show();
}
}
}

 

NotificationJobService.java

package com.example.android.notificationscheduler;

import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private static final int JOB_ID = 0;

private JobScheduler mScheduler;

private Switch mDeviceIdleSwitch;
private Switch mDeviceChargingSwitch;
private Switch mPeriodicSwitch;

private SeekBar mSeekBar;

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

mDeviceIdleSwitch = (Switch) findViewById(R.id.idleSwitch);
mDeviceChargingSwitch = (Switch) findViewById(R.id.chargingSwitch);
mPeriodicSwitch = (Switch) findViewById(R.id.periodicSwitch);

mSeekBar = (SeekBar) findViewById(R.id.seekBar);

Button scheduleJobButton = (Button) findViewById(R.id.scheduleJobButton);
Button cancelJobButton = (Button) findViewById(R.id.cancelJobsButton);

final TextView label = (TextView) findViewById(R.id.seekBarLabel);
final TextView seekBarProgress = (TextView) findViewById(R.id.seekBarProgress);

mPeriodicSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked){
label.setText(R.string.periodic_interval);
} else {
label.setText(R.string.override_deadline);
}
}
});

mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean userSet) {
if (progress > 0){
String progressLabel = getString(R.string.seekbar_label, progress);
seekBarProgress.setText(progressLabel);
} else {
seekBarProgress.setText(R.string.not_set);
}
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

scheduleJobButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scheduleJob();
}
});

cancelJobButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
cancelJobs();
}
});
}


private void scheduleJob() {
mScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);

RadioGroup networkOptions = (RadioGroup) findViewById(R.id.networkOptions);

int selectedNetworkID = networkOptions.getCheckedRadioButtonId();

int selectedNetworkOption = JobInfo.NETWORK_TYPE_NONE;
switch(selectedNetworkID){
case R.id.noNetwork:
selectedNetworkOption = JobInfo.NETWORK_TYPE_NONE;
break;
case R.id.anyNetwork:
selectedNetworkOption = JobInfo.NETWORK_TYPE_ANY;
break;
case R.id.wifiNetwork:
selectedNetworkOption = JobInfo.NETWORK_TYPE_UNMETERED;
break;
}

ComponentName serviceName = new ComponentName(getPackageName(),
NotificationJobService.class.getName());
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceName)
.setRequiredNetworkType(selectedNetworkOption)
.setRequiresDeviceIdle(mDeviceIdleSwitch.isChecked())
.setRequiresCharging(mDeviceChargingSwitch.isChecked());

int seekBarInteger = mSeekBar.getProgress();
boolean seekBarSet = seekBarInteger > 0;

if (mPeriodicSwitch.isChecked()){
if (seekBarSet){
builder.setPeriodic(seekBarInteger * 1000);
} else {
Toast.makeText(MainActivity.this, R.string.no_interval_toast,
Toast.LENGTH_SHORT).show();
}
} else {
if (seekBarSet) {
builder.setOverrideDeadline(seekBarInteger * 1000);
}
}

boolean constraintSet = selectedNetworkOption != JobInfo.NETWORK_TYPE_NONE
|| mDeviceChargingSwitch.isChecked() || mDeviceIdleSwitch.isChecked()
|| seekBarSet;

if(constraintSet) {
JobInfo myJobInfo = builder.build();
mScheduler.schedule(myJobInfo);
Toast.makeText(this, R.string.job_scheduled, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.no_constraint_toast, Toast.LENGTH_SHORT).show();
}
}

private void cancelJobs() {
if (mScheduler != null){
mScheduler.cancelAll();
mScheduler = null;
Toast.makeText(this, R.string.jobs_canceled, Toast.LENGTH_SHORT).show();
}
}
}

 

AndroidManifest.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:layout_width=”match_parent”
android:layout_height=”match_parent”
android:paddingBottom=”@dimen/activity_vertical_margin”
android:paddingLeft=”@dimen/activity_horizontal_margin”
android:paddingRight=”@dimen/activity_horizontal_margin”
android:paddingTop=”@dimen/activity_vertical_margin”
android:orientation=”vertical”
tools:context=”com.example.android.notificationscheduler.MainActivity”>

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/required_network_type”
android:textAppearance=”@style/TextAppearance.AppCompat.Subhead”
android:layout_margin=”4dp”/>

<RadioGroup
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:orientation=”horizontal”
android:id=”@+id/networkOptions”
android:layout_margin=”4dp”>
<RadioButton
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/no_network”
android:checked=”true”
android:id=”@+id/noNetwork”/>
<RadioButton
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/any_network”
android:id=”@+id/anyNetwork”/>
<RadioButton
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/wifi_network”
android:id=”@+id/wifiNetwork”/>
</RadioGroup>

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/requires”
android:textAppearance=”@style/TextAppearance.AppCompat.Subhead”
android:layout_margin=”4dp”/>

<LinearLayout
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:orientation=”horizontal”
android:layout_margin=”4dp”>
<Switch
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/device_idle”
android:id=”@+id/idleSwitch”/>
<Switch
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/device_charging”
android:id=”@+id/chargingSwitch”/>
</LinearLayout>

<Switch
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/periodic”
android:id=”@+id/periodicSwitch”
android:layout_margin=”4dp”/>

<LinearLayout
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:orientation=”horizontal”
android:layout_margin=”4dp”>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/override_deadline”
android:id=”@+id/seekBarLabel”
android:textAppearance=”@style/TextAppearance.AppCompat.Subhead”/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/not_set”
android:id=”@+id/seekBarProgress”
android:textAppearance=”@style/TextAppearance.AppCompat.Subhead”/>

</LinearLayout>

<SeekBar
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:id=”@+id/seekBar”
android:layout_margin=”4dp”/>

<Button
android:id=”@+id/scheduleJobButton”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_margin=”4dp”
android:text=”@string/schedule_job”
android:layout_gravity=”center_horizontal”/>

<Button
android:id=”@+id/cancelJobsButton”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_margin=”4dp”
android:text=”@string/cancel_jobs”
android:layout_gravity=”center_horizontal”/>
</LinearLayout>

 

 

 

M.Zahid Syafnel

I've a dream to be a busineman and a technopreneur

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *