Membuat Komunikasi antara Service dan Activity

Seringkali suatu service akan mengeksekusi di thread-nya sendiri, terbebas dan tidak tergantung pada 'activity' yang memanggilnya. Ini tidak akan menjadi masalah bila kita ingin service yang kita buat melakukan tugasnya secara periodik dan 'activity' tidak memerlukan notifikasi tentang status service tersebut. Misalnya, kita mungkin membuat service yang secara periodik membuat log lokasi perangkat ke database. Dalam hal ini, service yang kita buat tidak perlu berinteraksi dengan 'activity' apapun, karena tujuan utamanya adalah menyimpan koordinat ke database. Tetapi, andaikan kita ingin memonitor lokasi tertentu, dan ketika service mencatat log alamat yang dekat dengan lokasi yang kita monitor, service seperti ini mungkin perlu menyampaikan informasi ke 'activity'. Dengan demikian, kita perlu merancang suatu cara supaya service berinteraksi dengan 'activity'.

Berikut adalah latihan bagaimana service akan berinteraksi dengan 'activity' dengan menggunakan 'BroadcastReceiver'.

1. Kita masih menggunakan project dari latihan sebelumnya, kemudian modifikasi dan tambahkan dalam file "MyIntentService.java" seperti berikut ini:
package com.example.services;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

import java.net.MalformedURLException;
import java.net.URL;

public class MyIntentService extends IntentService {

public MyIntentService() {
super("MyIntentServiceName");
}

protected void onHandleIntent(Intent intent) {
try {
int result = DownloadFile(new URL("https://diansano.blogspot.com/somefile.pdf"));
Log.d("IntentService", "Downloaded " + result + " bytes");
/*mengirim broadcasr untuk memberi info activity bahwa file sudah di-download*/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("FILE_DOWNLOADED_ACTION");
getBaseContext().sendBroadcast(broadcastIntent);

} catch (MalformedURLException e) {
e.printStackTrace();
}
}

private int DownloadFile(URL url) {
try {
/*mensimulasikan beberapa saat untuk download file*/
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 100;
}
}
2. Modifikasi dan tambahkan kode berikut pada file "MainActivity.java" seperti berikut:
package com.example.services;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

IntentFilter intentFilter;

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

@Override
public void onResume() {
super.onResume();

/*intent untuk memfilter file yang di-download intent*/
intentFilter = new IntentFilter();
intentFilter.addAction("FILE_DOWNLOADED_ACTION");

/*me-register penerima*/
registerReceiver(intentReceiver, intentFilter);
}


public void onPause() {
super.onPause();
/*unregister penerima*/
unregisterReceiver(intentReceiver);
}


public void startService(View view) {
/*startService(new Intent(getBaseContext(), MyIntentService.class));
* atau
* startService(new Intent("com.example.MyIntentService"));*/
startService(new Intent(getBaseContext(), MyIntentService.class));
}

public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}

private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getBaseContext(), "File downloaded!", Toast.LENGTH_LONG).show();
}
};

}
Kemudian jalankan di emulator Android Studio, klik tombol 'Start Service'. Setelah lima detik, class 'Toast' akan menampilkan pesan yang menunjukkan bahwa file sudah di download.




Penjelasan:

Untuk memberi notifikasi pada 'activity' bila service sudah selesai eksekusinya, kita men-broadcast intent dengan menggunakan method 'sendBroadcast()':
@Override
protected void onHandleIntent(Intent intent) {
try {
int result = DownloadFile(new URL("https://diansano.blogspot.com/somefile.pdf"));
Log.d("IntentService", "Downloaded " + result + " bytes");
/*mengirim broadcasr untuk memberi info activity bahwa file sudah di-download*/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("FILE_DOWNLOADED_ACTION");
getBaseContext().sendBroadcast(broadcastIntent);

} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Action dari intent yang melakukan broadcasting tersebut kita set "FILE_DOWNLOADED_ACTION", yang artinya 'activity' apapun yang mendengar/menerima dari intent tersebut akan dipanggil. Karena itu, di dalam file "MainActivity.java" kita siapkan untuk mendengar/menerima intent ini dengan menggunakan method 'registerReceiver()' dari class "IntentFilter":
@Override
public void onResume() {
super.onResume();

/*intent untuk memfilter file yang di-download intent*/
intentFilter = new IntentFilter();
intentFilter.addAction("FILE_DOWNLOADED_ACTION");

/*me-register penerima*/
registerReceiver(intentReceiver, intentFilter);
}

Bila intent diterima, dia akan memanggil instans dari class 'BroadcastReceiver' yang sudah kita buat:
private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getBaseContext(), "File downloaded!", Toast.LENGTH_LONG).show();
}
};
Catatan:
Pada topik tentang SMS kita sudah mempelajari tentang class 'BroadcastReceiver' lebih detil.

Dalam hal ini, kita menampilkan pesan "File downloaded!", dan bila kita perlu melewatkan suatu data dari service ke 'activity', kita bisa menggunakan object 'Intent'. Latihan berikutnya akan mempelajari hal ini.

No comments: