Build Your Android App

Berhubung lagi booming akhir akhir ini, ayo kita utak atik buat aplikasi Android. cuman butuh skill di java aja koq :)

Create Your Own Game Using Unity

Kata siapa membuat game itu susah, asal ada kemauan untuk belajar membuat game itu gampang kok. Apalagi ada engine seperti unity ini

Belajar JSON yuk

Apa itu JSON? penasaran dengan fungsi dan cara menggunakannya? mari kita pelajari disini

Mushroom Farmer

Yuk belajar manajamen bisnis sambil bermain sebagai petani jamur. Tertarik? Cek Disini

HIMIT PENS

Menjadi bagian dari himpunan di kampus cukup menyenangkan. Banyak pengalaman yang bisa didapat dari kegiatan tersebut dan juga bisa menjadi sarana pengembangan diri.

Minggu, Maret 03, 2013

Loading Gambar Dari Internet Dengan Android

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvUdeFBB9pjMk9uCzJQFijTrs-kOOopJCRE0H3cr89LEys3OMx2hdIsG_CN7pFtZjFVlb4cK-Iwnoh0aHDeW71E5A-NIz1hv9zX-TTYx24G2L7BHqu_Ww40_WPJ6m3I3j-vgLEpNLL_c8/s1600/Logo_Android.jpg

yak, kembali lagi nih ke utak atik programming Android. Seperti yang sudah saya beritahukan pada postingan sebelumnya. Kini kita akan mencoba meload gambar dari internet. Sepertinya sih terdengar biasa saja ya. Memang sih kebanyakan dari kita menggunakan fungsi berikut untuk meload image dari internet.

HttpURLConnection connection= (HttpURLConnection)imageURL.openConnection();

connection.setDoInput(true);

connection.connect();

InputStream inputStream = connection.getInputStream();

bitmap = BitmapFactory.decodeStream(inputStream);//Convert to bitmap

image_view.setImageBitmap(bitmap);

Nah yang ingin saya bagikan pada tutorial kali ini adalah bagaimana meload gambar dari internet kemudian disimpan dalam memori. Wah pasti timbul pertanyaan, bukannya kalau disimpan di memori bakal ngebuat penuh ya? tapi tenang saja memori yang digunakan memori cache kok. Jadi hanya bersifat temporary, kalo cachenya di clear maka juga ikut ikutan hilang Open-mouthed smile. Keuntungan dari menyimpan image di cache adalah ketika kita membuat app yang butuh melakukan penyimpanan gambar atau app yang meload gambar berulang ulang akan menjadi lebih efisien. Image yang sudah di load tidak perlu didownload kembali, itung itung hemat kuota Smile.

Nah langsung aja ini nih caranya, pertama tama buat project baru di android dengan nama AndroidLoadImageFromWeb. untuk nama terserah sih, ga harus pakai punya saya. Setelah project selesai buat koding sesuai class yang diperlukan.

AndroidLoadImageFromWebActivity.java

package com.eepis.android;

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

public class AndroidLoadImageFromWebActivity extends Activity implements OnClickListener {
    Button load;
    ImageView image;
    ImageLoader imgLoader;
    int loader = R.drawable.loader;
    String image_url = "http://rapidpurple.com/purpleblog/wp-content/uploads/2011/11/php_mysql_logo.png";
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        load=(Button)findViewById(R.id.btnLoad);
        load.setOnClickListener(this);
        image = (ImageView) findViewById(R.id.image);       
    }
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        imgLoader = new ImageLoader(getApplicationContext());
        imgLoader.DisplayImage(image_url, loader, image);
    }
}

FileCache.java

package com.eepis.android;

import java.io.File;
import android.content.Context;
 
public class FileCache {
 
    private File cacheDir;
 
    public FileCache(Context context){
        //Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"TempImages");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }
 
    public File getFile(String url){
        String filename=String.valueOf(url.hashCode());
        File f = new File(cacheDir, filename);
        return f;
 
    }
 
    public void clear(){
        File[] files=cacheDir.listFiles();
        if(files==null)
            return;
        for(File f:files)
            f.delete();
    }
 
}

ImageLoader.java

package com.eepis.android;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
 
public class ImageLoader {
 
    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
 
    public ImageLoader(Context context){
        fileCache=new FileCache(context);
        executorService=Executors.newFixedThreadPool(5);
    }
 
    int stub_id = R.drawable.ic_launcher;
    public void DisplayImage(String url, int loader, ImageView imageView)
    {
        stub_id = loader;
        imageViews.put(imageView, url);
        Bitmap bitmap=memoryCache.get(url);
        if(bitmap!=null)
            imageView.setImageBitmap(bitmap);
        else
        {
            queuePhoto(url, imageView);
            imageView.setImageResource(loader);
        }
    }
 
    private void queuePhoto(String url, ImageView imageView)
    {
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }
 
    private Bitmap getBitmap(String url)
    {
        File f=fileCache.getFile(url);
 
        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;
 
        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex){
           ex.printStackTrace();
           return null;
        }
    }
 
    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);
 
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }
 
            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }
 
    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public PhotoToLoad(String u, ImageView i){
            url=u;
            imageView=i;
        }
    }
 
    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;
        PhotosLoader(PhotoToLoad photoToLoad){
            this.photoToLoad=photoToLoad;
        }
 
        @Override
        public void run() {
            if(imageViewReused(photoToLoad))
                return;
            Bitmap bmp=getBitmap(photoToLoad.url);
            memoryCache.put(photoToLoad.url, bmp);
            if(imageViewReused(photoToLoad))
                return;
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
            Activity a=(Activity)photoToLoad.imageView.getContext();
            a.runOnUiThread(bd);
        }
    }
 
    boolean imageViewReused(PhotoToLoad photoToLoad){
        String tag=imageViews.get(photoToLoad.imageView);
        if(tag==null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }
 
    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
        public void run()
        {
            if(imageViewReused(photoToLoad))
                return;
            if(bitmap!=null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }
 
    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
 
}

MemoryCache.java

package com.eepis.android;

import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
 
public class MemoryCache {
    private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());
 
    public Bitmap get(String id){
        if(!cache.containsKey(id))
            return null;
        SoftReference<Bitmap> ref=cache.get(id);
        return ref.get();
    }
 
    public void put(String id, Bitmap bitmap){
        cache.put(id, new SoftReference<Bitmap>(bitmap));
    }
 
    public void clear() {
        cache.clear();
    }
}

Utils.java

package com.eepis.android;

import java.io.InputStream;
import java.io.OutputStream;
 
public class Utils {
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {
            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);
            }
        }
        catch(Exception ex){}
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
   
    <ImageView
        android:id="@+id/image"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_margin="10dip"/>

    <Button
        android:id="@+id/btnLoad"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_margin="10dip"
        android:text="Load Image" />

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.eepis.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".AndroidLoadImageFromWebActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
   
    <!-- Internet Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
   
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
   
    <!-- Permission to write to external storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

</manifest>

Hasil Tampilan Aplikasi

image

Demikianlah tutorial kali ini semoga bisa bermanfaat buat kawan kawan sekalian. Untuk source projectnya bisa di download di alamat berikut

DOWNLOAD

Yah akhirnya selesai juga tutorial kali ini, setelah bisa mendownload gambar tentunya kita juga bisa mengupload dong. Nantikan tutorial selanjutnya ya tentang upload image dengan http-post multipart. So Keep Update ya Open-mouthed smile

jika ada pertanyaan silahkan saja email saya di bagibagi23@gmail.com

Sumber Artikel

http://www.androidhive.info/2012/07/android-loading-image-from-url-http/

http://stackoverflow.com/questions/3085366/android-image-cache-stategy-and-memory-cache-size

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Jumat, Maret 01, 2013

Memahami ASyncTask di Android Programming

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvUdeFBB9pjMk9uCzJQFijTrs-kOOopJCRE0H3cr89LEys3OMx2hdIsG_CN7pFtZjFVlb4cK-Iwnoh0aHDeW71E5A-NIz1hv9zX-TTYx24G2L7BHqu_Ww40_WPJ6m3I3j-vgLEpNLL_c8/s1600/Logo_Android.jpg

ASyncTask? apa sih itu? kayaknya pernah denger nih haha. ASyncTask adalah salah satu fitur di Android Programming untuk mengeksekusi operasi yang akan dilakukan secara background. Jadi initinya operasi dilakukan di background thread kemudian jika sudah selesai maka akan langsung ditampilkan di UI. Baik berhasil maupun gagal sesuai dengan yang sudah di set sebelumnya. Trus kenapa ini penting banget? bukannya kalo HW sekarang udah canggih ya dan cepet banget. Emang sih buat device Android jaman sekarang wuss wuss lah specnya tapi tetep aja masih ada sedikit lag apalagi jika data yang di proses cukup banyak.

Tapi ada yang hal yang cukup penting juga looo ini bisa mengatasi force close pada aplikasi yang di run di ICS. Berdasar pengalaman penulis ketika mendevelop aplikasi di GB(Android 2.3.3) atau lebih tepatnya menggunakan SDK GB kemudian menjalankan aplikasinya pada device Android dengan level ICS(android 4.0 keatas) ternyata force close berulang kali. Padahal ketika dijalan kan di GB lancar jaya loo tapi anehnya ketika di run di ICS eh malah force close. Terutama kita melakukan access network, ga tahu ada error apa eh tiba force close padahal koneksi lancar lancar aja.

Nah oleh karena itu kali ini penulis akan memberikan sebuah tutorial mengenai ASyncTask di Android. jadi ikuti dengan tenang ya, karena ini cukup mudah kok Open-mouthed smile.

Buat project baru bernama ASyncTask

Kemudian ketik koding berikut pada AsyncTaskActivity.java

package com.eepis.android;


import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;


public class ASyncTaskActivity extends Activity {

    Button btn_start;
    ProgressBar progressBar;
    TextView txt_percentage;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        btn_start    =    (Button) findViewById(R.id.btn_start);
        progressBar =     (ProgressBar) findViewById(R.id.progress);
        txt_percentage= (TextView) findViewById(R.id.txt_percentage);
       
        btn_start.setOnClickListener(new View.OnClickListener() {
           
            @Override
            public void onClick(View v) {
               
                btn_start.setEnabled(false);
                new ShowDialogAsyncTask().execute();
            }
        });
    }

   
    private class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{

        int progress_status;
       
        @Override
        protected void onPreExecute() {
            // update the UI immediately after the task is executed
            super.onPreExecute();
           
             Toast.makeText(ASyncTaskActivity.this,
                     "Invoke onPreExecute()", Toast.LENGTH_SHORT).show();

             progress_status    =    0;
             txt_percentage.setText("downloading 0%");
           
        }
       
        @Override
        protected Void doInBackground(Void... params) {
           
            while(progress_status<100){
               
                progress_status += 2;
               
                publishProgress(progress_status);
                SystemClock.sleep(300);
               
            }
            return null;
        }
   
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
           
            progressBar.setProgress(values[0]);
            txt_percentage.setText("downloading " +values[0]+"%");
           
        }
       
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
           
             Toast.makeText(ASyncTaskActivity.this,
                     "Invoke onPostExecute()", Toast.LENGTH_SHORT).show();
            
             txt_percentage.setText("download complete");
             btn_start.setEnabled(true);
        }
       
    }
}

Ketik kode berikut pada main.xml

<RelativeLayout 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" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:padding="20dp"
        android:text="ASyncTask"
        tools:context=".AsyncTaskActivity" />

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="34dp" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/progress"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp"
        android:minWidth="120dp"
        android:text="Start" />

    <TextView
        android:id="@+id/txt_percentage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/progress"
        android:text="downloading  0%"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

Hasil tampilan ketika aplikasi dijalankan

image

Penjelasan singkat:

class ini memungkinkan kita melakukan proses secara background. 4 fungsi yang ada di dalamnya masing masing berfungsi

1. onPreExecute()—> pada fungsi ini kita menyiapkan setingan inisialisasi operasi yang akan dijalankan

2. doInBackground()—> disini adalah bagian dimana operasi dilakukan secara background

3. onProgressUpdate()—> ketika proses.operasi berjalan setiap perubahan akan ditampilkan

4. onPostExecute()—> setalah proses/operasi selesai fungsi ini dijalankan

hal hal lain yang berkaitan dengan ASyncTask bisa dilihat pada link berikut ini

http://developer.android.com/reference/android/os/AsyncTask.html

Demikianlah tutorial kali ini semoga bisa bermanfaat buat kawan kawan sekalian. Untuk source projectnya bisa di download di alamat berikut

DOWNLOAD

Nah setelah kita berhasil mengimplementasikan AsyncTask di Android saatnya mencoba pada praktek yang sesungguhnya. Untuk postingan berikutnya akan saya tunjukkan bagaimana meload gambar dari internet dan menyimpannya pada memori cache di SD Card. So Keep Update ya Open-mouthed smile

jika ada pertanyaan silahkan saja email saya di bagibagi23@gmail.com

Cara Mudah Parsing JSON Array dengan Android

http://rapidpurple.com/purpleblog/wp-content/uploads/2011/11/php_mysql_logo.png

Salam Developer, kali ini kita akan melanjutkan postingan sebelumnya mengenai membuat login form Android dengan PHP MySQL. Untuk kali ini kita akan melakukan parsing data dari JSONArray menjadi data yang tampil dalam bentuk listview di Android. Jika ingin membuka postingan sebelumnya klik link berikut

Untuk persiapan, tool tool yang kita butuhkan adalah

1. Apache Web Server dan mySQL bisa pake XAMPP download disini –> XAMPP

2. Eclipse dan Android SDK –> versi yang saya gunakan disini ada 2.3.3 Ginggerbeard

3. Notepad++ atau Dreamweaver terserah mau pake yang mana untuk edit file PHP

4. Kopi/Susu + roti bakar Open-mouthed smile --> Wajib nih meski cuman singkat tutorialnya Smile

Bagian 1 Buat Project baru pada Android

Seperti sebelumnya copykan file class JSONParser yang ada di postingan sebelumnya ke project ini. Setelah itu pada main class kita akan menghandle fungsi fungsi JSON dan HTTP-POST. (ingat class dan package yang saya gunakan dalam project ini adalah default dari komputer saya. jadi ketika anda melakukan copas cek sesuai dengan konfigurasi milik anda)

JSONArrayActivity

package com.eepis.android;

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.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class JSONArrayActivity extends ListActivity{
    /** Called when the activity is first created. */
    List<String> items,items2;
    private JSONParser jsonParser;
    String ServerURL = "http://10.0.2.2/tes/";    //alamat lokasi file untuk menangkap/mengirim JSON
    String list_tag = "getlistuser";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list);
        items=new ArrayList<String>();
        items2=new ArrayList<String>();
        //Memanggil class JSONParser
        jsonParser = new JSONParser();
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag",list_tag));
        //Mengirim parameter yang akan di tangkap server
        JSONObject json = jsonParser.getJSONFromUrl(ServerURL, params);
        try{
            JSONArray  data = json.getJSONArray("user"); //key ini didapat dari nama array yang kita buat di dalam JSON
            for(int i=0;i < data.length();i++){                       
                JSONObject e = data.getJSONObject(i);
                  items.add(e.getString("name"));
                  items2.add(e.getString("email"));
            }
        }catch(JSONException e){
            e.printStackTrace();
        }
        setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items));
    }
    protected void onListItemClick(ListView l, View v, int position,
            long id) {
        super.onListItemClick(l,v,position, id);
        String text = ""+ items.get(position);
        String textemail = ""+ items2.get(position);
        Toast.makeText(this, "name:"+text+" email:"+textemail, 1).show();                  
    }
}

list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
   
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:drawSelectorOnTop="false"
        android:background="#3b3b3b">
    </ListView>
        <TextView
        android:id="@android:id/empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@android:style/TextAppearance.Large"
        android:gravity="center"
        android:text="Data tidak ditemukan">
    </TextView>

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.eepis.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".JSONArrayActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

Bagian 2 Buat API yang menghandle request dari Android

Pada server side kita membuat API yang menangkap Http-Post yang kita kirim via android dan mengembalikannya ke kita dalam bentuk JSON. Untuk database pada project kali ini kita tetap memakai database pada postingan sebelumnya pada Membuat Login Form di Android dengan PHPMySQL. Jadi disini kita akan mengambil data user yang terdapat dalam database.

untuk file DB_Connect.php dan config.php bisa dilihat pada postingan sebelumnya

index.php

<?php

/**
File ini untuk menghandle API Request
hasilnya di encoda dalam bentuk JSON
  /**
* check for POST request
*/
if (isset($_POST['tag']) && $_POST['tag'] != '') {
    // Tag
    $tag = $_POST['tag'];

    // Database Handler
    require_once 'include/DB_Functions.php';
    $db = new DB_Functions();

    // Response--> data yang akan dikembalikan
    $response = array("tag" => $tag, "success" => 0);
   
    // Cek tipe tag
    if ($tag == 'login') {
        // Tangkap data yang dikirim dari android
        $email = $_POST['email'];
        $password = $_POST['password'];

        // Cek user
        $user = $db->getUserByEmailAndPassword($email, $password);
        if ($user != false) {
            // User ditemukan
            $response["success"] = 1;
            echo json_encode($response);
        } else {
            // User tidak ditemukan
            $response["success"] = 0;
            echo json_encode($response);
        }
    }
    else if ($tag == 'register') {
        // Tangkap data yang dikirim dari android
        $name = $_POST['name'];
        $email = $_POST['email'];
        $password = $_POST['password'];

        // cek user sudah ada atau belum
        if ($db->isUserExisted($email)) {
            // User sudah ada
            $response["success"] = 0;
            $response["error_msg"] = "User sudah ada";
            echo json_encode($response);
        } else {
            // Simpan user baru
            $user = $db->storeUser($name, $email, $password);
            if ($user) {
                // Registrasi Berhasil
                $response["success"] = 1;
                echo json_encode($response);
            } else {
                // Registrasi Gagal
                $response["success"] = 0;
                echo json_encode($response);
            }
        }
    }
   
    else if ($tag == 'getlistuser') {
        //Mengambil data list
        $list=$db->getUserList();
        $response["user"] = $list;
        if($list!=false){
            $response["success"] = 1;
            echo json_encode($response);
        }
        else{
            $response["success"] = 0;
            echo json_encode($response);       
        }
    }
   
    else {
        echo "Invalid Request";
    }
} else {
    echo "Access Denied";
}
?>

DB_Function.php

<?php

class DB_Functions {

    private $db;
    // constructor
    function __construct() {
        require_once 'DB_Connect.php';
        // Koneksi ke database
        $this->db = new DB_Connect();
        $this->db->connect();
    }

    // destructor
    function __destruct() {
       
    }
   
    public function storeUser($name, $email, $password) {
        $uuid = uniqid('', true);
        $hash = $this->hashSSHA($password);
        $encrypted_password = $hash["encrypted"]; // Enkripsi password
        $salt = $hash["salt"]; // salt
        $result = mysql_query("INSERT INTO users(unique_id, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$name', '$email', '$encrypted_password', '$salt', NOW())");
        // Cek registrasi berhasil
        if ($result) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Cek user di database
     */
    public function getUserByEmailAndPassword($email, $password) {
        $result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
        $no_of_rows = mysql_num_rows($result);
        if ($no_of_rows > 0) {
            $result = mysql_fetch_array($result);
            $salt = $result['salt'];
            $encrypted_password = $result['encrypted_password'];
            $hash = $this->checkhashSSHA($salt, $password);
            // Cek kesamaan password
            if ($encrypted_password == $hash) {
                // Identifikasi berhasil
                return true;
            }
        } else {
            // User tidak ditemukan
            return false;
        }
    }

    /**
     * Cek user exist atau tidak
     */
    public function isUserExisted($email) {
        $result = mysql_query("SELECT * from users WHERE email = '$email'");
        $no_of_rows = mysql_num_rows($result);
        if ($no_of_rows > 0) {
            // user exist
            return true;
        } else {
            // user tidak exist
            return false;
        }
    }
        /**
    Enkripsi password
     */
    public function hashSSHA($password) {

        $salt = sha1(rand());
        $salt = substr($salt, 0, 10);
        $encrypted = base64_encode(sha1($password . $salt, true) . $salt);
        $hash = array("salt" => $salt, "encrypted" => $encrypted);
        return $hash;
    }


    public function checkhashSSHA($salt, $password) {

        $hash = base64_encode(sha1($password . $salt, true) . $salt);

        return $hash;
    }
   
    public function getUserList() {

        $result=mysql_query("SELECT name,email from users");       
        $resultNo = mysql_num_rows($result);

        if ($result != null) {
            //Jika hanya satu return valuenya
            if ($resultNo == 1) {

                // Return result
                $resultSet[] = mysql_fetch_assoc($result);
                return $resultSet;

            //Jika lebih dari satu lakukan looping
            } else {

                //tambahkan tiap baris ke array
                while($row = mysql_fetch_assoc($result)) {
                $resultSet[] = $row;
                }
                return $resultSet;
            }
        }
        else{
            return false;
        }
    }
}
?>

Bagian 3 Hasil running aplikasi

File JSON yang dikirim ke android berbentuk

{"tag":"getlistuser","success":1,"user":[{"name":"moresky","email":"moresky@gmail.com"},{"name":"coba","email":"coba@gmail.com"},{"name":"andi","email":"andi@gmail.com"},{"name":"budi","email":"budi@gmail.com"},{"name":"lia","email":"lia@gmail.com"}]}

Hasil tampilan pada aplikasi

image   image


Demikianlah tutorial kali ini semoga bisa bermanfaat buat kawan kawan sekalian. Untuk source projectnya bisa di download di alamat berikut

DOWNLOAD

Mungkin beberapa dari anda menemukan kendala force close ketika mencoba menjalankan project ini di device Android anda. Hal itu dimungkinkan karena device yang anda gunakan menggunakan OS Android ICS. Nah pada ICS networking harus dilakukan di background thread berbeda pada GB(Android 2.3.3). Jadi jika menggunakan SDK 2.3.3 ada baiknya kita menggunakan ASyncTask untuk melakukan networking jika target buildnya pada Android ICS. Tutorial selanjutnya akan membahas tentang ASyncTask di Android. So Keep Update ya Open-mouthed smile

jika ada pertanyaan silahkan saja email saya di bagibagi23@gmail.com

Minggu, Februari 24, 2013

Membuat Login Form di Android dengan PHP MySQL

http://rapidpurple.com/purpleblog/wp-content/uploads/2011/11/php_mysql_logo.png

Salam Developer, kali ini kita akan melanjutkan postingan sebelumnya mengenai koneksi Android dengan PHP MySQL. Untuk lebih jelasnya akan kita implementasikan pada program yang dibuat dibawah ini. Jika ingin membuka postingan sebelumnya klik link berikut

Untuk persiapan, tool tool yang kita butuhkan adalah

1. Apache Web Server dan mySQL bisa pake XAMPP download disini –> XAMPP

2. Eclipse dan Android SDK –> versi yang saya gunakan disini ada 2.3.3 Ginggerbeard

3. Notepad++ atau Dreamweaver terserah mau pake yang mana untuk edit file PHP

4. Kopi/Susu + roti bakar Open-mouthed smile --> Wajib nih meski cuman singkat tutorialnya Smile

Bagian 1 Buat Project baru pada Android

Seperti sebelumnya copykan file class JSONParser yang ada di postingan sebelumnya ke project ini. Setelah itu buat class baru bernama UserFunction.java. Nantinya class ini akan menghandle fungsi fungsi JSON dan HTTP-POST yang akan kita lakukan.(ingat class dan package yang saya gunakan dalam project ini adalah default dari komputer saya. jadi ketika anda melakukan copas cek sesuai dengan konfigurasi milik anda)

UserFunction.java

package com.eepis.android;

import java.util.ArrayList;
import java.util.List;

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

public class UserFunctions {
   
    private JSONParser jsonParser;
   
    private static String loginURL = "http://10.0.2.2/tes/";
   
    private static String login_tag = "login";
    private static String register_tag = "register";
   
    // constructor
    public UserFunctions(){
        jsonParser = new JSONParser();
    }
   
    public JSONObject loginUser(String email, String password){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag", login_tag));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("password", password));
        JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);

        return json;
    }
   
    /**
     * function make Login Request
     * @param name
     * @param email
     * @param password
     * */
    public JSONObject registerUser(String name, String email, String password){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag", register_tag));
        params.add(new BasicNameValuePair("name", name));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("password", password));
       
        // getting JSON Object
        JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);
        // return json
        return json;
    }
}

LoginFormActivity.java

package com.eepis.android;

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

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class LoginFormActivity extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    //Deklarasi variabel view object
    TextView     error;
    Button        login,register;
    EditText    user,pwd;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //Registrasi view id
        error=(TextView)findViewById(R.id.txt1);
        login=(Button)findViewById(R.id.btn1);
        login.setOnClickListener(this);
        register=(Button)findViewById(R.id.btn2);
        register.setOnClickListener(this);
        user=(EditText)findViewById(R.id.edit1);
        pwd=(EditText)findViewById(R.id.edit2);
    }
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.btn1:
            //Memanggil fungsi login di class userfunction
            UserFunctions userFunction = new UserFunctions();
            JSONObject json = userFunction.loginUser(user.getText().toString(), pwd.getText().toString());
            try {
                if (json.getString("success") != null) {
                    error.setText("");
                    String res = json.getString("success");
                    if(Integer.parseInt(res) == 1){
                        Intent login = new Intent(LoginFormActivity.this,MemberActivity.class);
                       startActivity(login);
                       MemberActivity.session=user.getText().toString();
                    }else{
                        error.setText("username/password anda salah");
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            break;
        case R.id.btn2:
            //Memanggil fungsi register di class userfunction
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setTitle("Registrasi");
            alert.setMessage("Masukkan Data Anda");
           
            // Set an EditText view to get user input
            LinearLayout lay=new LinearLayout(this);
            lay.setOrientation(LinearLayout.VERTICAL);
            final EditText name = new EditText(this);
            name.setHint("Nama");
            final EditText email = new EditText(this);
            email.setHint("Email");
            final EditText password = new EditText(this);
            password.setHint("Password");
            lay.addView(name);
            lay.addView(email);
            lay.addView(password);
            alert.setView(lay);
            alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    String nama = name.getText().toString();
                    String mail = email.getText().toString();
                    String pass = password.getText().toString();   
                    UserFunctions userFunction = new UserFunctions();
                    JSONObject json = userFunction.registerUser(nama, mail, pass);
                    try {
                         if (json.getString("success") != null) {
                             String res = json.getString("success");
                             if(Integer.parseInt(res) == 1){
                                 Toast.makeText(LoginFormActivity.this, "Registrasi Berhasll", 1).show();
                             }else{
                                 Toast.makeText(LoginFormActivity.this, "Registrasi Gagal", 1).show();
                             }
                         }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
            alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
           
                }
            });
            alert.show();
            break;
        default:
            break;
        }
    }
}

MemberActivity.java

package com.eepis.android;

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

public class MemberActivity extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    Button        logout;
    static String session="";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.member);
       logout=(Button)findViewById(R.id.btn1);
       logout.setOnClickListener(this);
    }
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        this.session="";
        this.finish();
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.eepis.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".LoginFormActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:label="@string/app_name"
            android:name=".MemberActivity" >
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

Bagian 2 Buat API yang menghandle request dari Android

Pada server side kita membuat API yang menangkap Http-Post yang kita kirim via android dan mengembalikannya ke kita dalam bentuk JSON

SQL file

<form action="index.php" method="post">
   <p>tag: <input type="text" name="tag" /></p>
   <p>name: <input type="text" name="name" /></p>
   <p>email: <input type="text" name="email" /></p>
   <p>password: <input type="text" name="password" /></p>
   <input type="submit" name="submit" value="Submit" />
</form>

index.php

<?php

/**
File ini untuk menghandle API Request
hasilnya di encoda dalam bentuk JSON
  /**
* check for POST request
*/
if (isset($_POST['tag']) && $_POST['tag'] != '') {
    // Tag
    $tag = $_POST['tag'];

    // Database Handler
    require_once 'include/DB_Functions.php';
    $db = new DB_Functions();

    // Response--> data yang akan dikembalikan
    $response = array("tag" => $tag, "success" => 0);
   
    // Cek tipe tag
    if ($tag == 'login') {
        // Tangkap data yang dikirim dari android
        $email = $_POST['email'];
        $password = $_POST['password'];

        // Cek user
        $user = $db->getUserByEmailAndPassword($email, $password);
        if ($user != false) {
            // User ditemukan
            $response["success"] = 1;
            echo json_encode($response);
        } else {
            // User tidak ditemukan
            $response["success"] = 0;
            echo json_encode($response);
        }
    }
    else if ($tag == 'register') {
        // Tangkap data yang dikirim dari android
        $name = $_POST['name'];
        $email = $_POST['email'];
        $password = $_POST['password'];

        // cek user sudah ada atau belum
        if ($db->isUserExisted($email)) {
            // User sudah ada
            $response["success"] = 0;
            $response["error_msg"] = "User sudah ada";
            echo json_encode($response);
        } else {
            // Simpan user baru
            $user = $db->storeUser($name, $email, $password);
            if ($user) {
                // Registrasi Berhasil
                $response["success"] = 1;
                echo json_encode($response);
            } else {
                // Registrasi Gagal
                $response["success"] = 1;
                echo json_encode($response);
            }
        }
    }
   
    else {
        echo "Invalid Request";
    }
} else {
    echo "Access Denied";
}
?>

config.php

<?php

/**
* Database config variables
*/
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "");
define("DB_DATABASE", "tes");
?>

DB_Connect.php

<?php
class DB_Connect {

    // constructor
    function __construct() {
    }

    // destructor
    function __destruct() {
        // $this->close();
    }

    // Connecting to database
    public function connect() {
        require_once 'include/config.php';
        // connecting to mysql
        $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
        // selecting database
        mysql_select_db(DB_DATABASE);

        // return database handler
        return $con;
    }

    // Closing database connection
    public function close() {
        mysql_close();
    }

}

?>

DB_Function.php

<?php

class DB_Functions {

    private $db;
    // constructor
    function __construct() {
        require_once 'DB_Connect.php';
        // Koneksi ke database
        $this->db = new DB_Connect();
        $this->db->connect();
    }

    // destructor
    function __destruct() {
       
    }
   
    public function storeUser($name, $email, $password) {
        $uuid = uniqid('', true);
        $hash = $this->hashSSHA($password);
        $encrypted_password = $hash["encrypted"]; // Enkripsi password
        $salt = $hash["salt"]; // salt
        $result = mysql_query("INSERT INTO users(unique_id, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$name', '$email', '$encrypted_password', '$salt', NOW())");
        // Cek registrasi berhasil
        if ($result) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Cek user di database
     */
    public function getUserByEmailAndPassword($email, $password) {
        $result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
        $no_of_rows = mysql_num_rows($result);
        if ($no_of_rows > 0) {
            $result = mysql_fetch_array($result);
            $salt = $result['salt'];
            $encrypted_password = $result['encrypted_password'];
            $hash = $this->checkhashSSHA($salt, $password);
            // Cek kesamaan password
            if ($encrypted_password == $hash) {
                // Identifikasi berhasil
                return true;
            }
        } else {
            // User tidak ditemukan
            return false;
        }
    }

    /**
     * Cek user exist atau tidak
     */
    public function isUserExisted($email) {
        $result = mysql_query("SELECT * from users WHERE email = '$email'");
        $no_of_rows = mysql_num_rows($result);
        if ($no_of_rows > 0) {
            // user existed
            return true;
        } else {
            // user not existed
            return false;
        }
    }
        /**
    Enkripsi password
     */
    public function hashSSHA($password) {

        $salt = sha1(rand());
        $salt = substr($salt, 0, 10);
        $encrypted = base64_encode(sha1($password . $salt, true) . $salt);
        $hash = array("salt" => $salt, "encrypted" => $encrypted);
        return $hash;
    }


    public function checkhashSSHA($salt, $password) {

        $hash = base64_encode(sha1($password . $salt, true) . $salt);

        return $hash;
    }
}
?>

Bagian 3 Hasil running aplikasi

File JSON yang dikirim ke android berbentuk

// Jika berhasil
{"tag":"login","success":1}
// Jika gagal
{"tag":"login","success":0}
// Jika user exist
{"tag":"register","success":0,"error_msg":"User sudah ada"}

Hasil tampilan pada aplikasi

image  image   image

Demikianlah tutorial kali ini semoga bisa bermanfaat buat kawan kawan sekalian. Untuk source projectnya bisa di download di alamat berikut

DOWNLOAD

Tutorial selanjutnya akan membahas tentang menghandle data array dalam format JSON dengan Android. So Keep Update ya Open-mouthed smile

jika ada pertanyaan silahkan saja email saya di bagibagi23@gmail.com