Anda di halaman 1dari 20

Studi Kasus MENU RESTORAN DIGITAL

dengan MySQL Server - ANDROID


POKOK BAHASAN

1. Teknologi Client-Server
2. AsyncTask
3. Web Server dengan Parsing JSON.
4. Menampilkan dengan Custom ListView

Skenario dan Rancangan Antarmuka

Restoran / Rumah Makan yang biasanya menyajikan daftar Menu Konvensional


diganti dengan daftar Menu Digital dan dapat di akses dengan Tablet atau HP
dengan sangat mudah & praktis.

Ada tiga tahapan / langkah kerja yang harus dilakukan, sbb:

1. Membangun Server Local Basisdata.


2. Membangun Web Service untuk menghubungkan Aplikasi PHP-MySQL
dengan Aplikasi ANDROID dengan JSON.
3. Membangun Aplikasi Client untuk mengakses Server dengan ANDROID.

Membangun Server Local Basisdata.

Langkah-1: Buat database & tabelnya

Create database MenuDigital


Use MenuDigital

Create table tb_kategori (idkategori int(2) not null


AUTO_INCREMENT primary key,kategori varchar(15) not null)

create table tb_menu (idmenu int(2) not null AUTO_INCREMENT


primary key,nama_menu varchar(35) not null,harga_menu
varchar(16) not null,
diskripsi_menu text not null,pic_menu text not null,idkategori
int(2) not null)

Langkah-2: Membangun Web Service dengan JSON.

2.1 FILE: config.php


<?php
$host="localhost";
$username="root";
$password="";
$db="menudigital";
mysql_connect($host,$username,$password) or die ("Tidak
Berhasil");
mysql_select_db($db) or die ("Basis Data Tidak Ditemukan");
?>

2.2.FILE:menu_service.php
<?php
require_once "config.php";
$json = array();
$kategori=$_POST('kategori');
$sql ="select * from tb_menu where idkategori=$kategori";
$hasil= mysql_query($sql);
while($row=mysql_fetch_assoc($hasil)){
$menu[]=$row;
}
if(is_array($menu)){
$json['datamenu']=$menu;
echo json_encode($json);
}
?>

Langkah-3: Membangun Aplikasi ANDROID


AplicationName : MenuDigital
ProjectName : MenuDigital
PackageName : com.menu.digital
=========================================
Activity Name : MainActivity (.JAVA)
Layout Name : main (.XML)
3.1. FILE: strings.xml (res-> values)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MenuDigital</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
</resources>

3.2. FILE: activity_main.xml (res-> layout)


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >

<Button
android:id="@+id/bMakanan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:drawableLeft="@drawable/foodsmall"
android:text="Makanan" />
<Button
android:id="@+id/bMinuman"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:drawableLeft="@drawable/drinksmall"
android:text="Minuman" />

</LinearLayout>

3.3. FILE: activity_main_listview.xml (res-> layout)


<?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:orientation="vertical" >

<ListView
android:id="@+id/listMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_custom_listview" >
</ListView>

</LinearLayout>

3.4. FILE: dialog_custom.xml (res-> layout)


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >

<ImageView
android:id="@+id/picDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />

<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:text="Nama menu"

android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
android:id="@+id/idNamaMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:text="not available"

android:textAppearance="?android:attr/textAppearanceMedium" />

</TableRow>

<TableRow
android:id="@+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:text="Harga menu"

android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
android:id="@+id/idHarga"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:text="not available"

android:textAppearance="?android:attr/textAppearanceMedium" />

</TableRow>

<TableRow
android:id="@+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/TextView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:text="Deskripsi"

android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
android:id="@+id/idDeskripsi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:text="not available"

android:textAppearance="?android:attr/textAppearanceMedium" />

</TableRow>

</TableLayout>
<Button
android:id="@+id/idOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK" />

</LinearLayout>

3.5. FILE: item_custom_listview.xml (res-> layout)


<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:context=".MainActivity" >

<ImageView
android:id="@+id/img_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/nama"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"

android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
android:id="@+id/harga"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />

</LinearLayout>

</LinearLayout>

Langkah-4: Membuat Class JAVA


4.1 FILE:AmbilData.java (src->com.menu.digital)
package com.menu.digital;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

public class AmbilData extends AsyncTask<Object, Object, Object> {


private JSONParser jsonparser;
ArrayList<String> d;
JsonObjectResult jobres;
Context context;
ProgressDialog pd;

public void init(Context c, JsonObjectResult jres, String


kategori,
String url) {
this.context = c;
this.jobres = jres;

AmbilData ad = this;
ad.execute(url, kategori, "");
}

@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd = ProgressDialog.show(context, "Retrieve Data",
"aaa");
pd.setMessage("Please wait...");
pd.show();
}

@Override
protected Object doInBackground(Object... parameter) {
// TODO Auto-generated method stub
JSONObject jsobj = null;
String url = (String) parameter[0];
String kat = (String) parameter[1];
Log.i("url", url);
Log.i("kat", kat);
jsonparser = new JSONParser();
List<NameValuePair> datajson = new
ArrayList<NameValuePair>();
datajson.add(new BasicNameValuePair("kategori", kat));
try {
jsobj = jsonparser.getObject(url, "GET", datajson);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsobj;
}

@Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (pd.isShowing()) {
pd.dismiss();
}

if (result != null) {
JSONObject js = (JSONObject) result;
jobres.gotJsonObject(js);
}
}

public static abstract class JsonObjectResult {


public abstract void gotJsonObject(JSONObject jobject);
}

4.2 FILE:JSONParser.java (src->com.menu.digital)


package com.menu.digital;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

public class JSONParser {

InputStream is;
String json;

JSONObject object;

public JSONObject getObject(String url, String method,


List<NameValuePair> value) throws IOException {

if(method == "POST"){
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
try {
post.setEntity(new
UrlEncodedFormEntity(value));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}else if(method == "GET"){


DefaultHttpClient client = new DefaultHttpClient();
String param = URLEncodedUtils.format(value, "utf-
8");
url += "?" + param;
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
is = response.getEntity().getContent();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
try {
BufferedReader reader = new BufferedReader(new
InputStreamReader(is,"iso-8859-1"));
StringBuilder sb = new StringBuilder();
String line;
while((line = reader.readLine())!=null){
sb.append(line+"\n");
}
is.close();
json = sb.toString();
object = null;
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
object = new JSONObject(json);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return object;
}

4.3 FILE:EntitasMakanan.java (src->com.menu.digital)


package com.menu.digital;

public class EntitasMakanan {


int idmenu;
String namamenu = "";
String hargamenu = "";
String deskripsimenu = "";
String picmenu = "";

public void setIDmenu(int id) {


this.idmenu = id;
}
public int getIDmenu() {
return idmenu;
}

public void setNamaMenu(String n) {


this.namamenu = n;
}

public String getNamaMenu() {


return namamenu;
}

public void setHargaMenu(String h) {


this.hargamenu = h;
}

public String getHargaMenu() {


return hargamenu;
}

public void setDeskripsiMenu(String d) {


this.deskripsimenu = d;
}

public String getDeskripsiMenu() {


return deskripsimenu;
}

public void setPicMenu(String p) {


this.picmenu = p;
}

public String getPicMenu() {


return picmenu;
}
}

4.4 FILE:MainActivity.java (src->com.menu.digital)


package com.menu.digital;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity;
import android.content.Intent;

public class MainActivity extends Activity implements


OnClickListener {
Button bFood, bDrink;

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

bFood = (Button) findViewById(R.id.bMakanan);


bDrink = (Button) findViewById(R.id.bMinuman);

bFood.setOnClickListener(this);
bDrink.setOnClickListener(this);

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bMakanan:
Bundle b = new Bundle();
Intent intent = new Intent(MainActivity.this,
MenuActivity.class);
b.putString("kategori", "1");
intent.putExtras(b);
startActivity(intent);

break;

case R.id.bMinuman:

Bundle bu = new Bundle();


Intent in = new Intent(MainActivity.this,
MenuActivity.class);
bu.putString("kategori", "2");
in.putExtras(bu);
startActivity(in);

break;
}
}

4.5 FILE:MenuActivity.java (src->com.menu.digital)


package com.menu.digital;

import java.io.InputStream;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.menu.digital.AmbilData.JsonObjectResult;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class MenuActivity extends Activity {


EntitasMakanan entitasmakanan;
ArrayList<EntitasMakanan> menu = new
ArrayList<EntitasMakanan>();
ListView lv;
String url =
"http://10.0.2.2/menudigital/menu_services.php";
String urlpic = "http://10.0.2.2/menurestoran/";

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

lv = (ListView) findViewById(R.id.listMenu);

Bundle b = this.getIntent().getExtras();
if (b.containsKey("kategori")) {

String kat = b.getString("kategori");


Log.d("kat", kat);
AmbilData ambildata = new AmbilData();
ambildata.init(MenuActivity.this, jsresult,
kat, url);
}

public JsonObjectResult jsresult = new JsonObjectResult()


{

@Override
public void gotJsonObject(JSONObject jobject) {
// TODO Auto-generated method stub
try {
JSONArray arraytempat =
jobject.getJSONArray("datamenu");

for (int i = 0; i < arraytempat.length();


i++) {
entitasmakanan = new
EntitasMakanan();

entitasmakanan.setIDmenu(arraytempat.getJSONObject(i)
.getInt("idmenu"));

entitasmakanan.setNamaMenu(arraytempat.getJSONObject(i)
.getString("nama_menu"));

entitasmakanan.setHargaMenu(arraytempat.getJSONObject(i)
.getString("harga_menu"));

entitasmakanan.setDeskripsiMenu(arraytempat

.getJSONObject(i).getString("diskripsi_menu"));

entitasmakanan.setPicMenu(arraytempat.getJSONObject(i)
.getString("pic_menu"));

menu.add(entitasmakanan);

}
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

MenuBaseAdapter datatempat = new


MenuBaseAdapter(MenuActivity.this,
menu);
lv.setAdapter(datatempat);
lv.setOnItemClickListener(new
OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?>
arg0, View arg1, int p,
long arg3) {
// TODO Auto-generated method stub
String des =
menu.get(p).getDeskripsiMenu();
String nm =
menu.get(p).getNamaMenu();
String hrg =
menu.get(p).getHargaMenu();
String pic =
menu.get(p).getPicMenu();
tampilkandetail(nm, des, hrg, pic);

}
});
}

};

public void tampilkandetail(String nama, String desk,


String harga,
String pic) {

final Dialog d = new Dialog(this);


d.setTitle("detail");
d.setContentView(R.layout.dialog_custom);

WindowManager.LayoutParams lp = new
WindowManager.LayoutParams();
lp.copyFrom(d.getWindow().getAttributes());
lp.width = LayoutParams.MATCH_PARENT;
lp.height = LayoutParams.WRAP_CONTENT;

d.getWindow().setAttributes(lp);

ImageView gb = (ImageView)
d.findViewById(R.id.picDialog);
TextView n = (TextView)
d.findViewById(R.id.idNamaMenu);
TextView h = (TextView)
d.findViewById(R.id.idHarga);
TextView desc = (TextView)
d.findViewById(R.id.idDeskripsi);
Button bOk = (Button) d.findViewById(R.id.idOK);

n.setText(nama);
h.setText(harga);
desc.setText(desk);
new DownloadImageTask(gb).execute(urlpic + pic);
bOk.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
d.dismiss();
}
});
d.show();
}

public class DownloadImageTask extends AsyncTask<String,


Void, Bitmap> {
ImageView bmImage;

public DownloadImageTask(ImageView bmImage) {


this.bmImage = bmImage;
}

@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}

protected Bitmap doInBackground(String... urls) {


String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new
java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}

protected void onPostExecute(Bitmap result) {


if (result != null) {
Bitmap bmp2 =
Bitmap.createScaledBitmap(result, 72, 72, true);
bmImage.setImageBitmap(bmp2);
}

}
}
}

4.6 FILE:MenuBaseAdapter.java (src->com.menu.digital)


package com.menu.digital;

import java.io.InputStream;
import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MenuBaseAdapter extends BaseAdapter {


private static ArrayList<EntitasMakanan> searchArrayList;

private LayoutInflater mInflater;


String urlpic = "http://10.0.2.2/menurestoran/";

Bitmap bm;

public MenuBaseAdapter(Context context,


ArrayList<EntitasMakanan> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}

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

@Override
public Object getItem(int p) {
return searchArrayList.get(p);
}

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

@Override
public View getView(int p, View v, ViewGroup parent) {
ViewHolder holder;

if (v == null) {
v =
mInflater.inflate(R.layout.item_custom_listview, null);
holder = new ViewHolder();

holder.nama = (TextView)
v.findViewById(R.id.nama);
holder.harga = (TextView)
v.findViewById(R.id.harga);
holder.pic = (ImageView)
v.findViewById(R.id.img_menu);
// holder.deskripsi = (TextView)
v.findViewById(R.id.d);
new
DownloadImageTask(holder.pic).execute(urlpic
+
searchArrayList.get(p).getPicMenu());
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}

holder.nama.setText(searchArrayList.get(p).getNamaMenu())
;

holder.harga.setText(searchArrayList.get(p).getHargaMenu(
));
return v;
}

static class ViewHolder {


TextView nama, harga;
ImageView pic;

public class DownloadImageTask extends AsyncTask<String,


Void, Bitmap> {
ImageView bmImage;

public DownloadImageTask(ImageView bmImage) {


this.bmImage = bmImage;
}

@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}

protected Bitmap doInBackground(String... urls) {


String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new
java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}

protected void onPostExecute(Bitmap result) {


if (result != null) {
Bitmap bmp2 =
Bitmap.createScaledBitmap(result, 72, 72, true);
bmImage.setImageBitmap(bmp2);
}

}
}
}

4.7 FILE:ClientToServer.java (src->com.menu.digital)


package com.menu.digital;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

public class ClientToServer {


public static final int HTTP_TIMEOUT = 30 * 1000;
private static HttpClient client;
private static HttpClient getHttpClient() {
if (client == null) {
client = new DefaultHttpClient();
final HttpParams parameterHttp = client.getParams();
HttpConnectionParams.setConnectionTimeout(parameterHttp,HTTP_T
IMEOUT);
ConnManagerParams.setTimeout(parameterHttp,HTTP_TIMEOUT);
}
return client;
}

public static String eksekusiHttpPost(String url,


ArrayList<NameValuePair> postParameter) throws Exception
{
BufferedReader in = null;
try {
HttpClient klien = getHttpClient();
HttpPost req = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameter);
req.setEntity(formEntity);
HttpResponse jawaban = klien.execute(req);
in = new BufferedReader(new
InputStreamReader(jawaban.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String hasil = sb.toString();
return hasil;
} finally {
if (in != null) {
in.close();
}
}
}

public static String eksekusiHttpGet(String url) throws


Exception {
BufferedReader in = null;
try {
HttpClient hc = getHttpClient();
HttpGet req = new HttpGet();
req.setURI(new URI(url));
HttpResponse resp = hc.execute(req);
in = new BufferedReader(new
InputStreamReader(resp.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String hasil = sb.toString();
return hasil;
} finally {
if (in != null) {
in.close();
}
}
}
}