Retrieve current time using Json in Android Studio

Objective:
To retrieve current time using Json

Function:
When the button is pressed, small pop up will be displayed to inform the status of network connectivity. Once network is established, Json data will be retrieved and display it on TextView. Time is based on GMT.

IDE:
Android Studio 1.0.2

Source Code:
The project can be downloaded from here.

Result:





Explanation:

1. As usual, we need to add permission to AndroidManifest.xml





2. Then we need to commit the Fragment in MainActivity.java.

/*way of adding fragment with java*/
        //FragmentOne is the class which inflate the fragment_one.xml and return the view
        FragmentOne myFragment = new FragmentOne();
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        //'container' is android id in activity_main.xml
        //add android:id="@+id/container" in activity_main.xml
        transaction.add(R.id.container, myFragment, "main_layout_container");
        transaction.commit();

3. In FragmentOne.java, we first setup button to display
//create Button 'button' and link with button id from fragment_one.xml
        Button button = (Button) view.findViewById(R.id.button);

4. In FragmentOne.java, we implement setOnClickListener to detect the pressing of the button.Also take note that Object of JsonHelperClass is created with Context which will be used in HttpURLConnection.

/*define OnClickListener for button here*/
        button.setOnClickListener(new View.OnClickListener() {
            JsonHelperClass jsonHelperClass = new JsonHelperClass(context);

            public void onClick(View v) {
                //get String result and display it on TextView
                textViewCurrentTime.setText(jsonHelperClass.getResult());
            }
        });

5. In JsonHelperClass.java, more interesting stuff are happening here. The context passed from FragmentOne.java is first used in constructor.
//JsonHelperClass Constructor
    public JsonHelperClass(Context context) {
       // context is passed from FragmentOne.java; to be used in JsonHelperClass
        this.context = context;
    }

6. In JsonHelperClass.java, we first check the network connectivity. If the network is connected, then we will proceed with json parsing.
private boolean isConnectedToNetwork() {
        boolean connection;
        //ConnectivityManager required context
        //context is passed from FragmentOne.java
        ConnectivityManager connMgr = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            // small popup to show the status of network connection
            Toast.makeText(context, "Internet is connected",
                    Toast.LENGTH_SHORT).show();
            connection = true;
        } else {
            Toast.makeText(context, "Internet is not connected",
                    Toast.LENGTH_SHORT).show();
            connection = false;
        }
        return connection;
    }
7. In JsonHelperClass.java, before we parse Json data, we need to establish http connection to retrieve data from api provided by respective website. Take note that there is no running thread in background. Therefore, it might be some delay processing the connection. This is just for the simplicity. More should be done with Async Task. Once http connection is estiblished, we need to get stream data to pass to Json parsing function.
private void fetchMeJson() {

        //Ref website
        // http://stackoverflow.com/questions/8706464/defaulthttpclient-to-androidhttpclient
        //this is just for the simplicity
        //it is always recommended to move network operation off the UI thread, for example, using AsyncTask.
        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        try {

            //Ref from http://www.tutorialspoint.com/android/android_json_parser.htm
            URL url = new URL("http://date.jsontest.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000 ); // in milliseconds
            conn.setConnectTimeout(15000); // in milliseconds
            //below two line are default themselves; no need to set for getting data
            //but need to set explicitly if we want to post data
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            InputStream stream = conn.getInputStream();

            String data = convertStreamToString(stream);

            readAndParseJSON(data);
            stream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
8. In JsonHelperClass.java, we will parse the data stream and get appropriate data. The resultant data will be pass it back to String of 'result' in class.
 private void readAndParseJSON(String in) {
        try {
            JSONObject reader = new JSONObject(in);
            //time is expressed using the GMT time zone.
            result = reader.getString("time");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
9. In JsonHelperClass.java, finally overall picture of getting result can be seen on this following function.
    public String getResult() {
        //only fetch json if there is network connection
        if (isConnectedToNetwork()) {
            fetchMeJson();
        }
        return result;
    }


Complete Code:


Content of MainActivity.java
package com.example.osdevlab.simpletutorial;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;


public class MainActivity extends ActionBarActivity {

    public static Context context;


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

        /*way of adding fragment with java*/
        //FragmentOne is the class which inflate the fragment_one.xml and return the view
        FragmentOne myFragment = new FragmentOne();
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        //'container' is android id in activity_main.xml
        //add android:id="@+id/container" in activity_main.xml
        transaction.add(R.id.container, myFragment, "main_layout_container");
        transaction.commit();
    }


}

Content of FragmentOne.java
package com.example.osdevlab.simpletutorial;

import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

/**
 * Created by osdevlab on 12/29/14.
 */
public class FragmentOne extends Fragment {

    Context context;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // Inflate the layout with fragment_one.xml
        View view = inflater.inflate(R.layout.fragment_one, container, false);

        //create TextView 'textViewCurrentTime' and link with texView id from fragment_one.xml
        final TextView textViewCurrentTime = (TextView) view.findViewById(R.id.textView);

        //create Button 'button' and link with button id from fragment_one.xml
        Button button = (Button) view.findViewById(R.id.button);

        //returns the Activity the Fragment is currently associated with
        //In Fragment, this step requires to pass context to other class.
        context = getActivity();

        /*define OnClickListener for button here*/
        button.setOnClickListener(new View.OnClickListener() {
            JsonHelperClass jsonHelperClass = new JsonHelperClass(context);

            public void onClick(View v) {
                //get String result and display it on TextView
                textViewCurrentTime.setText(jsonHelperClass.getResult());
            }
        });
        return view;
    }
}


Content of JasonHelperClass.java
package com.example.osdevlab.simpletutorial;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.StrictMode;
import android.widget.Toast;
import org.json.JSONObject;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by osdevlab on 12/30/14.
 */


public class JsonHelperClass {
    Context context;
    private String result = "default result";

    //JsonHelperClass Constructor
    public JsonHelperClass(Context context) {
        // context is passed from FragmentOne.java; to be used in JsonHelperClass
        this.context = context;
    }

    static String convertStreamToString(java.io.InputStream is) {
        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }

    public String getResult() {
        //only fetch json if there is network connection
        if (isConnectedToNetwork()) {
            fetchMeJson();
        }
        return result;
    }

    private boolean isConnectedToNetwork() {
        boolean connection;
        //ConnectivityManager required context
        //context is passed from FragmentOne.java
        ConnectivityManager connMgr = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            // small popup to show the status of network connection
            Toast.makeText(context, "Internet is connected",
                    Toast.LENGTH_SHORT).show();
            connection = true;
        } else {
            Toast.makeText(context, "Internet is not connected",
                    Toast.LENGTH_SHORT).show();
            connection = false;
        }
        return connection;
    }

    private void fetchMeJson() {

        //Ref website
        // http://stackoverflow.com/questions/8706464/defaulthttpclient-to-androidhttpclient
        //this is just for the simplicity
        //it is always recommended to move network operation off the UI thread, for example, using AsyncTask.
        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        try {

            //Ref from http://www.tutorialspoint.com/android/android_json_parser.htm
            URL url = new URL("http://date.jsontest.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000 ); // in milliseconds
            conn.setConnectTimeout(15000); // in milliseconds
            //below two line are default themselves; no need to set for getting data
            //but need to set explicitly if we want to post data
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            InputStream stream = conn.getInputStream();

            String data = convertStreamToString(stream);

            readAndParseJSON(data);
            stream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void readAndParseJSON(String in) {
        try {
            JSONObject reader = new JSONObject(in);
            //time is expressed using the GMT time zone.
            result = reader.getString("time");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

No comments:

Post a Comment