Membuat Aplikasi Android Menggunakan WebView dan HTML5

Beberapa hari yang lalu, saya disibukkan oleh sebuah proyek aplikasi Android yang berbasiskan mobile web (HTML5, JQuery, PHP dan kawan-kawannya). Karena ingin dibuat lintas platform, sehingga dibuatlah aplikasi tersebut berupa mobile web. Awalnya saya kira porting ke Android menggunakan WebView-nya mudah dan tidak membutuhkan usaha banyak. Namun ternyata setelah dicoba, banyak sekali blunder dan tantangan yang harus dihadapi ketika kita menggunakan WebView di Android…

Apa itu WebView

WebView adalah sebuah class pada Android yang berfungsi sebagai semacam sandbox untuk menampilkan dan menjalan aplikasi mobile yang berbasiskan web, entah itu HTML5, JQuery Mobile, dan sebagainya. Cara gampangnya WebView itu seperti Android browser, tetapi tidak mempunyai address bar tempat memasukkan alamat URL. Karena URL yang mau kita buka sudah didefinisikan di aplikasi dan tidak bisa kita ganti.

Web Client

Dalam implementasinya, WebView mempunyai dua buah klien yang bisa kita gunakan untuk me-render halaman web, dan tiap-tiap klien tersebut mempunyai fungsionalitas yang berbeda-beda. Kedua klien tersebut adalah WebViewClient dan WebChromeClient.

WebViewClient adalah sebuah browser klien yang menyediakan fungsi-fungsi dasar dalam menampilkan halaman web. Sedangkan, WebChromeClient adalah browser klien yang menyediakan fitur-fitur advanced dalam rendering halaman web, kebanyakan berhubungan dengan interaksi antara browser dengan javascript, menampilkan objek seperti video, dan fitur-fitur advanced lainnya. Kalian bisa menggunakan kedua klien tersebut, namun apabila kalian hanya ingin me-render halaman web yang tidak membutuhkan banyak fitur (misal berisi HTML saja, tanpa javascript) maka kalian cukup menggunakan WebViewClient.

Pada dasarnya inisialisasi sebuah aplikasi WebView di Android adalah seperti berikut :

webView= (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());

//mengaktifkan dukungan untuk javascript
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("https://www.twoh.co");

Adapun untuk aplikasi yang lebih advanced, contoh kodenya seperti berikut :

                webView = (WebView) findViewById(R.id.wv_twoh);
		webSettings = (WebSettings) webView.getSettings();

		String url = "http://twoh.co";
                // memberitahukan browser untuk mengaktifkan Wide ViewPort
		webSettings.setUseWideViewPort(true);

                // otomatis website akan diload dengan zoom out
		webSettings.setLoadWithOverviewMode(true);

                // otomatis menampilkan javascript window
		webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

                // mengaktifkan fungsi-fungsi storage HTML5
		webSettings.setDatabaseEnabled(true);
		webSettings.setDomStorageEnabled(true);
		String databasePath = this.getApplicationContext()
		.getDir("databases", Context.MODE_PRIVATE).getPath();
		webSettings.setDatabasePath(databasePath);
		webSettings.setJavaScriptEnabled(true);

                // mengaktifkan fitur geolocation (deteksi lokasi)
		webSettings.setGeolocationEnabled(true);
		webSettings.setGeolocationDatabasePath(databasePath);

                // menonaktifkan hw acceleration yang kadang bermasalah
                // dengan mengaktifkan software layer
		webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
		webView.loadUrl(url);

Bisa dilihat, banyak sekali settingan yang saya nyalakan pada kode di atas. Untuk geolocation, ketika diaktifkan maka browser akan menampilkan alert, apakah aplikasi boleh mengakses lokasi pengguna atau tidak. Namun fungsionalitas ini bisa di bypass sehingga aplikasi secara otomatis akan mendapatkan lokasi pengguna. 😀 Setelah itu saya akan memberikan contoh pembuatan custom WebViewClient dan WebChromeClient

Custom WebViewClient

Pada aplikasi WebView yang saya buat, tidak ada banyak perubahan untuk kelas WebViewClient. Adapun beberapa hal dasar yang saya implementasikan seperti, menampilkan progress dialog ketika mulai me-load web page, dan meng-override url loading sehingga url yang diklik akan di-load pada WebView tersebut dan tidak membuka aplikasi browser lainnya. Berikut ini contoh kodenya.

public class TwohWebViewClient extends WebViewClient{

	public static final String TAG = TwohWebViewClient.class.getSimpleName();
	private Activity activity;
	private ProgressDialog pgDialog;

	public TwohWebViewClient(Activity act) {
		activity = act;
		// inisialisasi progress dialog
		pgDialog = TwohWebViewUtils.getProgressDialog(activity, ProgressDialog.STYLE_SPINNER, true, "loading", false);
	}

	// Untuk memaksa me-load URL pada browser WebView ini
	@Override
	public boolean shouldOverrideUrlLoading(WebView view, String url) {
		webView.loadUrl(url);
		return true;
	}

	// dipanggil pada saat halaman web mulai di-load, menampilkan progress dialog
	@Override
	public void onPageStarted(WebView view, String url, Bitmap favicon)
	{
		super.onPageStarted(view, url, favicon);
		pgDialog.show();
		Log.v(TAG,"page started "+ url);
	}

	// dipanggil pada saat halaman web selesai di-load, menghilangkan progress dialog
	@Override
	public void onPageFinished(WebView view, String url) {
		super.onPageFinished(view, url);
		pgDialog.dismiss();
		Log.v(TAG,"page finished "+ url);
	}
}

Custom WebChromeClient

Sedangkan untuk custom WebChromeClient, ada lumayan banyak method yang harus diubah. Diantaranya seperti bypass geolocation permission menjadi always allow, kemudian menampilkan output console.log() pada javascript ke logcat Android, dan yang terakhir adalah mengaktifkan fitur HTML5 media capture. Dan bagian terakhir ini yang menjadi blunder terbesar. :v

public class TwohWebChromeClient extends WebChromeClient{

	private Context context;
	private Activity activity;
	public static final String TAG = TwohWebChromeClient .class.getSimpleName();

	public TwohWebChromeClient (Context ctx, Activity act) {
		context = ctx;
		activity = act;
	}

	// display javascript log message pada LogCat
	@Override
	public boolean onConsoleMessage(ConsoleMessage cm) {
		Log.v(TAG,cm.message() + " log from line "+cm.lineNumber()+ " of " + cm.sourceId());
		return true;
	}

	// tidak menampilkan prompt, bypass menjadi always allow get location
	@Override
	public void onGeolocationPermissionsShowPrompt(final String origin,
			final GeolocationPermissions.Callback callback) {
		callback.invoke(origin, true, true);
	}

	// hidden API, akan dijelaskan lebih lanjut :D
	public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType, String capture) {
		Log.v(TAG, "called first");
		openFileChooser(uploadMsg);
	}

	public void openFileChooser(ValueCallback<Uri> uploadMsg,
			String acceptType) {
		Log.v(TAG, "called two");
		openFileChooser(uploadMsg);
	}

	public void openFileChooser(ValueCallback<Uri> uploadMsg) {
		TwohWebActivity.mUploadMessage = uploadMsg;
		Log.v(TAG, "called three");

		Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		File externalDataDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
		File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
		File.separator + "browser-photos");
		cameraDataDir.mkdirs();
		TwohWebActivity.filePath = cameraDataDir.getAbsolutePath() + File.separator +"static_photo.jpg";
		cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(TwohWebActivity.filePath)));
		activity.startActivityForResult(cameraIntent, TwohWebActivity.TAKE_PICTURE);
	}

}

Kelemahan WebView

Sebenarnya untuk fungsi-fungsi dasar, aplikasi ini berjalan dengan lancar. Hingga kemudian ada satu requirements yaitu capture image dari kamera dan kemudian menguploadnya ke web yang ternyata tidak berjalan dengan mulus. Pada kode HTML-nya menggunakan syntax HTML5 untuk upload file, yaitu <input type="file" media="capture" />. Ketika link tersebut dibuka lewat browser bawaan Android dan Google Chrome for Android, aplikasi akan langsung menjalankan kamera sehingga user bisa ambil gambar dan menguploadnya. Namun ketika membukanya menggunakan WebView, tidak muncul apa-apa. 😀 Setelah saya selidiki, ternyata ada sebuah hidden API yang harus dipanggil supaya aplikasi bisa membuka kamera dan menjalankan HTML5 media capture. Hidden API itu adalah method openFileChooser().

Disebut hidden API karena method tersebut adalah private API, bukan public API, sehingga apabila kalian menulis ulang method tersebut dan menambahkan @Override, Eclipse akan memberikan pesan error walaupun nyatanya memang method tersebut sudah di-override.

Selain merupakan private API, jika kalian cermati pada kode di atas ada tiga buah deklarasi openFileChooser() method. Hal itu karena pada tiap-tiap API level, method openFileChooser() yang dipanggil berbeda-beda, yaitu :
– openFileChooser(ValueCallback uploadMsg), untuk Android versi <= 3.0
– openFileChooser(ValueCallback uploadMsg, String acceptType), untuk Android versi > 3.0
– openFileChooser(ValueCallback uploadMsg, String acceptType, String capture), untuk Android versi Jelly Bean

Lantas, bagaimana dengan KitKat? 😀

Ternyata, pada release Android KitKat, default WebView pada Android diganti menggunakan engine Chrome. Sehingga tidak ada satupun method openFileChooser di atas yang berjalan pada Android KitKat.

Tidak hanya itu, WebView seringkali juga menunjukkan performansi yang tidak konsisten. Seperti kadang berhasil upload gambar, dan kadang tidak berhasil. Padahal menggunakan baris kode yang sama. Walaupun sebenarnya bisa saja hal ini disebabkan oleh script di sisi web-nya, karena kebetulan yang membuat aplikasi web-nya bukan saya, sehingga kurang bebas untuk melakukan modifikasi. Mungkin untuk teknik lebih advanced-nya, aplikasi mobile web yang akan ditampilkan menggunakan WebView harus dicoding dengan Android in mind. Dan kemudian dari sisi Android membuat sebuah javascript interface sendiri yang bisa berinteraksi dengan javascript di sisi website.

Untuk aplikasi web mobile yang sekedar browsing, input form dan sebagainya, WebView masih bagus dan recommended untuk digunakan. Namun untuk aplikasi yang membutuhkan fungsi native, sepertinya harus menggunakan aplikasi native juga. Atau framework yang lebih canggih seperti PhoneGap/Apache Cordova.





Download aplikasi kami di Google Play Store


Tutorial Menarik Lainnya :

20 Comments

  1. Muhammad Zaini January 20, 2015
  2. Devan Aldian Putra January 24, 2015
    • Hafizh Herdi Naufal January 25, 2015
  3. joe bwz March 24, 2015
    • Hafizh Herdi June 1, 2015
      • reza October 25, 2015
  4. Hans May 30, 2015
    • Hafizh Herdi June 1, 2015
  5. Ruslan Munawar July 15, 2015
    • Hafizh Herdi July 15, 2015
  6. Rumah Murah August 18, 2015
    • Duwi Irwanto December 10, 2015
      • Hafizh Herdi December 10, 2015
  7. Duwi Irwanto December 10, 2015
  8. Andi March 19, 2016
  9. Rahman June 21, 2016
  10. Angguy February 5, 2017

Leave a Reply

Do NOT follow this link or you will be banned from the site!