Tuesday 27 September 2016

App startup loading screen



activity_main.xml


<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     
xmlns:tools="http://schemas.android.com/tools" 
 android:id="@+id/activity_main" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent"     
tools:context="com.example.pkm1.testapp.MainActivity">

    <TextView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Hello World!" />
</RelativeLayout>



MainActivity.java



import android.app.Dialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Window;

public class MainActivity extends AppCompatActivity {

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

      final Dialog dialog = new Dialog(this);
      dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
      dialog.setContentView(R.layout.spalashscreen);
      dialog.show();

    }
}

splashscreen.xml



<?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     
android:orientation="vertical"  
android:layout_width="match_parent"     
android:layout_height="match_parent" 
 android:background="@drawable/splash"    >

    <LinearLayout 
 android:layout_width="match_parent"         
android:layout_height="wrap_content" 
 android:orientation="vertical" 
 android:layout_alignParentBottom="true" 
 android:layout_marginBottom="100dp">
<ProgressBar 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:indeterminate="true"     
android:layout_gravity="center"/>
 <TextView 
 android:layout_height="wrap_content" 
 android:layout_width="wrap_content" 
 android:text="please wait..." 
 android:layout_gravity="center_horizontal"/>

<TextView         
android:layout_height="wrap_content" 
 android:layout_width="wrap_content" 
 android:text="Checking Server and Network Connectivity"         
android:layout_gravity="center_horizontal"/>
    </LinearLayout>
</RelativeLayout>


Image drawable for screen

splash.jpg







Friday 9 September 2016

Android JSON Parsing - JSONObject, JSONArray




JSON is very light weight, structured, easy to parse and much human readable. JSON is best alternative to XML when your android app needs to interchange data with your server.

 The Sample JSON

Following is the sample JSON that we are going to parse in this tutorial. This is very simple JSON which gives us list of contacts where each node contains contact information like name, email, address, gender and phone numbers.


{
    "contacts": [
        {
                "id": "c200",
                "name": "Ravi Tamada",
                "email": "ravi@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        {
                "id": "c201",
                "name": "Johnny Depp",
                "email": "johnny_depp@gmail.com",
                "address": "xx-xx-xxxx,x - street, x - country",
                "gender" : "male",
                "phone": {
                    "mobile": "+91 0000000000",
                    "home": "00 000000",
                    "office": "00 000000"
                }
        },
        .
        .
        .
        .
  ]
}

 { } represent JSON Object
 [ ]  represent JSON Array

If your JSON node starts with [, then we should use getJSONArray() method. Same as if the node starts with {, then we should use getJSONObject() method.


STEP-1 Creating New Project, Name it - JSONParsing
We’ll build a simple app which fetches the json from url, parses it and displays the contacts in a list view. 

 import java.net libraries (which are natively supported in android) to make the http call and fetch the json from url.
 

STEP-2. As we are fetching the JSON by making HTTP calls, we need to add INTERNET permission in AndroidManifest.xml file. Open AndroidManifest.xml and add the following permission.

<uses-permission android:name="android.permission.INTERNET" />

  STEP-3 Create a class named HttpHandler.java and use the below code.

Here makeServiceCall() makes http call to particular url and

fetches the response. In our case, we use this to get the

raw json from the url.


HttpHandler.java 

import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class HttpHandler {

    private static final String TAG = HttpHandler.class.getSimpleName();

    public HttpHandler() {
    }

    public String makeServiceCall(String reqUrl) {
        String response = null;
        try {
            URL url = new URL(reqUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            // read the response 
 InputStream in = new BufferedInputStream(conn.getInputStream());
            response = convertStreamToString(in);
        } catch (MalformedURLException e) {
            Log.e(TAG, "MalformedURLException: " + e.getMessage());
        } catch (ProtocolException e) {
            Log.e(TAG, "ProtocolException: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
        return response;
    }

    private String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}
 
 
STEP-4 Before making the http call, let’s add a list view first in our view. 
Open the layout file of main activity (activity_main.xml) and add a ListView element. 

activity_main.xml
 
<?xml version="1.0" encoding="utf-8"?> 
<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"    >
 <ListView        android:id="@+id/list" 
 android:layout_width="fill_parent" 
 android:layout_height="wrap_content" />
 </RelativeLayout>
 
STEP-5  Create another layout file named list_item.xml with following content. 
This will be used to render single list item view. 

list_item.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="wrap_content" 
 android:orientation="vertical" 
 android:padding="@dimen/activity_horizontal_margin"
<TextView
        android:id="@+id/name"
         android:layout_width="fill_parent" 
 android:layout_height="wrap_content" 
 android:paddingBottom="2dip"         
android:paddingTop="6dip" 
 android:textColor="@color/colorPrimaryDark"         
android:textSize="16sp"         
android:textStyle="bold" /> 
 <TextView
         
android:id="@+id/email" 
 android:layout_width="fill_parent"         
android:layout_height="wrap_content" 
 android:paddingBottom="2dip"         
android:textColor="@color/colorAccent" /> 
 <TextView
        android:id="@+id/mobile" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:textColor="#5d5d5d" 
 android:textStyle="bold" />
 </LinearLayout>
 
STEP-6  Open MainActivity.java and declare the necessary variables for the list view.
Downloading & Parsing the JSON

 As we are getting the JSON by making HTTP call, I am adding a Async class GetContacts to make http calls on background thread. Add the following method in your main activity class.

In onPreExecute() method progress dialog is shown before making the http call.

In doInBackground() method, makeServiceCall() is called to get the json from url. Once the json is fetched, it is parsed and each contact is added to array list.

In onPostExecute() method the progress dialog is dismissed and the array list data is displayed in list view using an adapter.

Also note that I have used getJSONArray() or getJSONObject() method depending on the type of node.
 
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

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

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {

    private String TAG = MainActivity.class.getSimpleName();

    private ProgressDialog pDialog;
    private ListView lv;

    // URL to get contacts JSON    private static String url = "http://api.androidhive.info/contacts/";

    ArrayList<HashMap<String, String>> contactList;

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

        contactList = new ArrayList<>();

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

        new GetContacts().execute();
    }

    /**     * Async task class to get json by making HTTP call     */    private class GetContacts extends AsyncTask<Void, Void, Void> {

        @Override        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override        protected Void doInBackground(Void... arg0) {
            HttpHandler sh = new HttpHandler();

            // Making a request to url and getting response            String jsonStr = sh.makeServiceCall(url);

            Log.e(TAG, "Response from url: " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);

                    // Getting JSON Array node                    JSONArray contacts = jsonObj.getJSONArray("contacts");

                    // looping through All Contacts                    for (int i = 0; i < contacts.length(); i++) {
                        JSONObject c = contacts.getJSONObject(i);

                        String id = c.getString("id");
                        String name = c.getString("name");
                        String email = c.getString("email");
                        String address = c.getString("address");
                        String gender = c.getString("gender");

                        // Phone node is JSON Object                        JSONObject phone = c.getJSONObject("phone");
                        String mobile = phone.getString("mobile");
                        String home = phone.getString("home");
                        String office = phone.getString("office");

                        // tmp hash map for single contact                        HashMap<String, String> contact = new HashMap<>();

                        // adding each child node to HashMap key => value                        contact.put("id", id);
                        contact.put("name", name);
                        contact.put("email", email);
                        contact.put("mobile", mobile);

                        // adding contact to contact list                        contactList.add(contact);
                    }
                } catch (final JSONException e) {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    "Json parsing error: " + e.getMessage(),
                                    Toast.LENGTH_LONG)
                                    .show();
                        }
                    });

                }
            } else {
                Log.e(TAG, "Couldn't get json from server.");
                runOnUiThread(new Runnable() {
                    @Override                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Couldn't get json from server. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG)
                                .show();
                    }
                });

            }

            return null;
        }

        @Override        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog            if (pDialog.isShowing())
                pDialog.dismiss();
            /**             * Updating parsed JSON data into ListView             * */            ListAdapter adapter = new SimpleAdapter(
                    MainActivity.this, contactList,
                    R.layout.list_item, new String[]{"name", "email",
                    "mobile"}, new int[]{R.id.name,
                    R.id.email, R.id.mobile});

            lv.setAdapter(adapter);
        }

    }
}