Lokasi (Bagian 2B: Google Location API: Mengambil secara rutin & penanganan Error)

Update Oktober 2015: Jangan gunakan tutorial ini, sebaiknya gunakan versi tutorial yang lebih baru versi yang lebih baru

Lanjutan dari bagian 2A

Mengambil Lokasi Secara Rutin
Selanjutnya kita akan membuat project yang menangkap lokasi secara reguler. Buat project baru, tambahkan tiga label sebagai berikut, dengan id tvStatus, tvLat dan tvLang.

loc_2_8

Untuk mengambil koordinat secara rutin, diperlukan tiga parameter:

  1. Update interval, menyatakan selang interval yang diinginkan, satuannya milidetik. Jika diset 5000 (5 detik), maka app akan diberi update lokasi device setiap 5 detik sekali. Tapi jika ada beberapa app yang menggunakan google location service, maka interval sesungguhnya dapat lebih pendek lagi, karena untuk efisiensi, jika app lain mendapat update lokasi, app kita akan mendapatkannya juga. Ini dapat membuat app terlalu banyak mendapatkan update (overflow).
  2. Untuk mencegah terjadinya overflow, dapat diset fastest interval untuk menyatakan interval tercepat yang dimungkinkan. Misalnya jika diset 1000 (1 detik), maka paling cepat app akan diupdate setiap 1 detik.
  3. Prioritas. Terdapat beberapa pilihan. Mulai dari yang prioritas paling tinggi yang paling banyak menghabiskan energi yaitu PRIORITY_HIGH_ACCURACY sampai dengan PRIORITY_NO_POWER yang paling hemat energi. Untuk PRIORITY_NO_POWER, app tidak akan mendapatkan lokasi kecuali jika ada app lain yang meminta lokasi.

Parameter tersebut kemudian dimasukkan pada objek LocationRequest yang kemudian dipassing ke method LocationClient.requestLocationUpdates. Setelah method tersebut dipanggil, maka setiap kali update maka method onLocationChanged akan dipanggil (callback).

Selain harus mengimplementasikan ConnectionCallbacks, OnConnectionFailedListener, Activity juga harus mengimplementasikan LocationListener (tapi dari com.google.android.gms.location bukan android.location). Berikut kode lengkapnya:

package edu.upi.cs.yudiwbs.cobagooglelocation;

import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.format.Time;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationRequest;


//implements ConnectionCallBacks dan OnConnectionFailedListener
//tambah LocationListener
//LocationListener sengaja dituliskan lengkap karena 
//bisa tertukar dengan android.location.LocationListener

public class CobaGoogleLocation extends FragmentActivity implements   
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, 
com.google.android.gms.location.LocationListener {
	
//client untuk mendapatkan lokasi
LocationClient mLocationClient;

//lokasi terakhir
Location mCurrentLocation;
	
//untuk output
    TextView tvLat;
    TextView tvLng; 
    TextView tvStatus;
    
    //parameter update lokasi
    
    //interval update dalam Milidetik yang diinginkan
    //jika tidak ada app lain yg mengakses, interval akan sesuai ini
    //tapi jika ada app lain yg mengakses, interval bisa lebih pendek
    private static final long UPDATE_INTERVAL = 1000 * 5; //5 detik 
    
    //interval tercepat yang dapat dihandle oleh app
    //karena interval bisa lebih pendek daripada nilai UPDATE_INTERVAL
    //sehingga dapat terjadi overflow, yaitu data update lebih cepat
    //daripada yang app bisa handle 
    //untuk mengatasi itu dapat diset fasteset_interval sebagai batas
    //tercepat
    //jika diset 1 detik, maka *paling cepat* app akan diupdate lokasinya
    //tiap 1 detik
    private static final long FASTEST_INTERVAL =1000 * 1; //1 detik
    
    // objek berisi parameter2 update lokasi
    LocationRequest mLocationRequest;
    
    private Time waktu;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_coba_google_location);
		mLocationClient = new LocationClient(this, this, this);
		
		//init user interface
		tvStatus = (TextView) findViewById(R.id.tvStatus);
		tvLat =  (TextView) findViewById(R.id.tvLat);
		tvLng =  (TextView) findViewById(R.id.tvLng);

		waktu = new Time();
	    
		//siapkan paramter request
		mLocationRequest = LocationRequest.create();
        	// akurasi tertinggi
        	mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        	// Set the update interval dan fastetst update interval
        	mLocationRequest.setInterval(UPDATE_INTERVAL);
        	mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
	}
	

    //Dipanggil saat Activity  visible.
    @Override
    protected void onStart() {
        super.onStart();
        // Connect ke client
        mLocationClient.connect();
    }
    
    /*
     * dipanggil saat activity tidak terlihat
     */
    @Override
    protected void onStop() {
        // disconnect dengan client
        mLocationClient.disconnect();
        super.onStop();
    }


	@Override
	public void onConnected(Bundle arg0) {
		//method ini dipanggil saat sudah terhubung dgn client
		
		tvStatus.setText("Terhubung.. mulai mengupdate");
		
		//mulai update request dengan parameter
		//yang ada pada mLocationRequest
		//selanjutnya jika ada update lokasi maka 
		//method onLocationChanged akan dipanggil
		mLocationClient.requestLocationUpdates(mLocationRequest, this);
	}
	
	@Override
	public void onLocationChanged(Location loc) {
		//dipanggil setiap ada perubahan lokasi
		//freq pemangilan sesuai parameter 
		//interval dan fastestinterval
		
		//catat waktu update
		waktu.setToNow();
		String strWaktu =  "Direfresh:"+
		       waktu.hour+":"+waktu.minute+":"+waktu.second;
		tvStatus.setText(strWaktu);
		
		//tulis latitude dan longitude
		tvLng.setText(Double.toString(loc.getLongitude()));
		tvLat.setText(Double.toString(loc.getLatitude()));   
	}

	@Override
	public void onDisconnected() {
		// dipanggil saat sudah tidak terhubung
		Toast.makeText(this, "Disconnected", Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onConnectionFailed(ConnectionResult arg0) {
		// sekarang tampilkan pesan dulu
		// nanti ada mekanisme resolve
		Toast.makeText(this, "Koneksi gagal.",
               Toast.LENGTH_SHORT).show();
	}
}


Penanganan Error
Pada dua contoh sebelumnya, belum ditangani jika terjadi kesalahan saat koneksi dengan Google Play Service. Beberapa kemungkinan error yang dapat terjadi misalnya user belum melakukan sign-in, google play belum diupdate, tanggal yang salah dan sebagainya (ingat kelemahan Google Location API adalah API ini bergantung pada Google Play Service). Beberapa kesalahan dapat diselesaikan dengan memanggil intent.

Kita akan memodifikasi code pada bagian sebelumnya untuk menangani kesalahan saat app mencoba terhubung dengan service.

Tambahkan konstanta berikut:

//kode result setelah intent dipanggil, akan digunakan di
//onActvityResult
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; 

Kemudian ubah isi method onConnectionFailed yang akan dipanggil jika terjadi gagal koneksi. Jika ada kemungkinan untuk solusi (misalnya harus login ulang dengan account Google), maka akan dipanggil intent melalui startResolutionForResult. Setelah selesai pemanggilan intent, onActivityResult akan dipanggil.

@Override
	public void onConnectionFailed(ConnectionResult cr) {
		tvStatus.setText("Koneksi gagal, coba resolusi");
		if (cr.hasResolution()) {
            		try {
                	//memungkinkan resolusi (misal install google 
            		//play versi terbaru, login dll). 
            		//Jalankan intent 
            		//nanti hasilnya ditangkap di onActivityResult
                	cr.startResolutionForResult(
                        	this,
                        	CONNECTION_FAILURE_RESOLUTION_REQUEST);

            	} catch (IntentSender.SendIntentException e) {
                   e.printStackTrace();
            	}
        	} else {
            	   //tidak ada resolusi, tampilkan error code
                   Toast.makeText(this, "Tidak bisa melakukan koneksi, kode:"+
                                  cr.getErrorCode(), Toast.LENGTH_SHORT).show();
                }
	}

onActivityResult akan dipanggil saat intent selesai, dicek melalui requestCode dan jika resultCode berisi RESULT_OK maka artinya resolusi berhasil dan berhasil terhubung dengan Google Play Service.

	 @Override
	 protected void onActivityResult(
			int requestCode, int resultCode, Intent data) {
	        switch (requestCode) {
	            //hasil kiriman dari startResolutionForResult
	        	case CONNECTION_FAILURE_RESOLUTION_REQUEST :
	                if (resultCode==Activity.RESULT_OK) {
	                   //resolusi sukses
	                   tvStatus.setText("Resolusi sukses, terhubung");	
	                } else {
		               tvStatus.setText("Gagal terhubung");		
	                }	
	                break;
	        }
	 }

Leave a Reply

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

Time limit is exhausted. Please reload CAPTCHA.