1

I am making an android app in which i want to load json data. My specification is that, if there is internet available, then load the data from a url which i provide.

If There is no internet, then load the local json.txt file.

My app is able to load the data from the url if there is internet connection and it can load the local json data if there is absolute no internet connection.

However in meta state such as this, my app crashes.enter image description here

The log is

07-14 09:56:21.258  22499-28349/scientist.jobless.foodmana E/log_tag﹕ Error in http connection java.net.UnknownHostException: Unable to resolve host "lit-hamlet-6856.herokuapp.com": No address associated with hostname
07-14 09:56:21.258  22499-28349/scientist.jobless.foodmana E/log_tag﹕ Error converting result java.lang.NullPointerException
07-14 09:56:21.258  22499-28349/scientist.jobless.foodmana E/log_tag﹕ Error parsing data org.json.JSONException: End of input at character 0 of
07-14 09:56:21.266  22499-28349/scientist.jobless.foodmana E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.NullPointerException
            at scientist.jobless.foodmana.JsonLoadSubFirstFirst$DownloadJSON.doInBackground(JsonLoadSubFirstFirst.java:239)
            at scientist.jobless.foodmana.JsonLoadSubFirstFirst$DownloadJSON.doInBackground(JsonLoadSubFirstFirst.java:215)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
07-14 09:56:21.878  22499-22499/scientist.jobless.foodmana E/WindowManager﹕ Activity scientist.jobless.foodmana.JsonLoadSubFirstFirst has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@5374c12c that was originally added here
    android.view.WindowLeaked: Activity scientist.jobless.foodmana.JsonLoadSubFirstFirst has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@5374c12c that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:374)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
            at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
            at android.view.Window$LocalWindowManager.addView(Window.java:547)
            at android.app.Dialog.show(Dialog.java:277)
            at scientist.jobless.foodmana.MyCustomProgressDialog.show(MyCustomProgressDialog.java:43)
            at scientist.jobless.foodmana.JsonLoadSubFirstFirst$DownloadJSON.onPreExecute(JsonLoadSubFirstFirst.java:227)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
            at android.os.AsyncTask.execute(AsyncTask.java:534)
            at scientist.jobless.foodmana.JsonLoadSubFirstFirst.onCreate(JsonLoadSubFirstFirst.java:74)
            at android.app.Activity.performCreate(Activity.java:5008)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
            at android.app.ActivityThread.access$600(ActivityThread.java:130)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

Below is my java code where i am checking for connection type.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Get the view from listview_main.xml
    setContentView(R.layout.listview_main);
    // Execute DownloadJSON AsyncTask

    ConnectivityManager connec = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connec != null && (
            (connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) ||
                    (connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED))) {
        new DownloadJSON(this).execute();
        //You are connected, do something online.

    } else if (connec != null && (
            (connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.DISCONNECTED) ||
                    (connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.DISCONNECTED ))) {

        //Not connected.
        Toast.makeText(getApplicationContext(), "You must be connected to the internet", Toast.LENGTH_LONG).show();
        new LocalDownloadJSON().execute();
    }

    else if (connec != null && (
            (connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.UNKNOWN) ||
                    (connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.UNKNOWN ))) {

        //i want to load local json data here
    }

}

My question is that how to handle that meta state of connection as i have shown in the emulator's picture.

i have tried this answer but i get error on isNetworkAvailable(context) as cannot resolve method isNetworkAvailable.

Is there anyway by this code ??

(connec != null && (
             (connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.UNKNOWN) ||
                        (connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.UNKNOWN )))

LocalJsonDownload.java

private class LocalDownloadJSON extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd = new ProgressDialog(JsonLoadSubFirstFirst.this);

            pd.setMessage("Loading...");
            pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);

            pd.setIndeterminate(true);
            pd.setCancelable(false);
            pd.show();
        }



        @Override
        protected Void doInBackground(Void... params) {
            // Create an array
            localarraylist = new ArrayList<HashMap<String, String>>();
            // Retrieve JSON Objects from the given URL address

            StringBuffer sb = new StringBuffer();
            BufferedReader br = null;

            try {
                br = new BufferedReader(new InputStreamReader(getAssets().open("localfood.txt")));
                String temp;
                while ((temp = br.readLine()) != null)
                    sb.append(temp);
            }
            catch (IOException e)
            {

                e.printStackTrace();
            }
            finally
            {
                try
                {
                    br.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }

            myjsonstring = sb.toString();

            try{
                JSONObject jsonObj = new JSONObject(myjsonstring);
                JSONArray Attendance = jsonObj.getJSONArray("events");

                for (int i = 0; i < Attendance.length(); i++)

                {

                    JSONObject a = Attendance.getJSONObject(i);

                    String Name = a.getString("Name");
                    String time = a.getString("Time");
                    String ingredients = a.getString("ingredients");
                    String Serves = a.getString("Serves");
                    String descr = a.getString("Description");


                    HashMap<String, String> contact = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    contact.put("Name", Name);
                    contact.put("Time", time);
                    contact.put("ingredients", ingredients);
                    contact.put("Serves", Serves);
                    contact.put("Description", descr);
                    // adding contact to contact list
                    localarraylist.add(contact);

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

            return null;
        }


        @Override
        protected void onPostExecute(Void args) {
            Toast.makeText(getApplicationContext(),"Loading local data dishes, please connect o internet to load new dishes",Toast.LENGTH_LONG).show();
            // Locate the listview in listview_main.xml
            //setContentView(R.layout.listview_main);
            listview = (ListView) findViewById(R.id.listview);
            // Pass the results into ListViewAdapter.java
            adapter = new ListViewAdapter(JsonLoadSubFirstFirst.this, localarraylist);
            // Set the adapter to the ListView
            listview.setAdapter(adapter);
            // Close the progressdialog
            //  mProgressDialog.dismiss();

            //   textView.setVisibility(View.VISIBLE);
            pd.dismiss();

            super.onPostExecute(args);

        }
    }
Community
  • 1
  • 1
penta
  • 2,160
  • 2
  • 18
  • 40
  • 1
    Hi, you made things more difficult my friend.. instead of doing that, the approach that I can see is even if you dont check the connection, declare this json.. in try block: do the getting of json from the internet. if there is no connection or if it fails to get the data.. It would automatically go to the catch block with general Exception parameter: where you will do the reading of local json. – Sheychan Jul 14 '15 at 10:16
  • Want me to create sample? :) – Sheychan Jul 14 '15 at 10:17
  • i tried try catch block, even that resulted in app crash :-), the logs even then were pretty much same – penta Jul 14 '15 at 10:17
  • Hmmmmmmm lemme see what youve tried – Sheychan Jul 14 '15 at 10:18

4 Answers4

1

you can do one thing while loading json data when internet is available you can save it to your sqite and while loading next time check if network is available or not if network is not available then you can fetch json data from sqlite and parse it simple. and you can use GreenDao for this it will make very fast and reliable

Ram Mandal
  • 1,750
  • 1
  • 17
  • 33
  • het thanks for an answer, but i dont want to make my project more time consuming, can you plz suggest a solution by the above code – penta Jul 14 '15 at 11:11
0

Seems that json file is not properly downloaded because of internet connection. So when you read incomplete downloaded file it throws "JSONException: End of input at character 0 of"

You should check for downloaded file size with original file size before you read downloaded file. Original file size can be found in HTTP Header.

Or you have invalid json file on server.

Hope you will find it helpful.

chandil03
  • 14,047
  • 5
  • 43
  • 64
  • Hey Sachin thanks for reply, this error comes only when i am in the meta state of internet connection, this error does not happen when i am connected or absolutely not connected, actually this error is comming when my class is trying to download the json data when there is no aparent connection (i.e. meta connection) – penta Jul 14 '15 at 10:39
  • Yes i understood. Because of no apparent connection, file in not completely downloaded that is why this exception is being thrown. You should check for size of downloaded file or catch exception in doInBackgournd method. – chandil03 Jul 14 '15 at 10:44
  • i have tried try catch statements, even they result in the same as i mentioned it in question – penta Jul 14 '15 at 10:44
  • Have you checked downloaded file size with original one at remote location? – chandil03 Jul 14 '15 at 10:46
  • This exception comes only when you have invalid json file. So you have invalid json file or it is not properly being downloaded, check again. Or post your AsyncTask code so i can check it. – chandil03 Jul 14 '15 at 10:54
  • That code is reading file from assets folder not from internet. Is that code giving exception? – chandil03 Jul 14 '15 at 11:05
  • Problem is in you downloading code. while downloading is in progress and internet is down. it end up downloading incomplete file. Print content of downloaded file to check its content. – chandil03 Jul 14 '15 at 11:29
  • Read my answer, it should help – Yerzhan Tanatov Jul 14 '15 at 11:29
  • Yerzhan Tanatov he has done that. thats why there is NullPointerException instead of IOException. Because of exception, next part of catch statement is getting null, that was actually being initialized in try block. – chandil03 Jul 14 '15 at 11:36
0

You can't handle this state of connection. Only way is to catch IOException. Better way in the method doInBackground of DownloadJSON catch IOException and JSONException then execute LocalDownloadJSON

try{
    // your code for downloading from internet
 } catch (IOException e) {
            e.printStackTrace();
 } catch (JSONException e) {
            e.printStackTrace();
}

Edited: Better parse Json in onPostExecute

 private class DownloadJSON extends AsyncTask<String, Integer, String> {

        protected void onPreExecute() {         
        }

        protected String doInBackground(String... urls) {
            String result = null;
            try {
                result = tryGetJSON();
            } catch (IOException e) {
                  e.printStackTrace();
            }
            return result;
        }

        protected void onPostExecute(String result) {
            if (result != null) {
              //parse json              
            }
            else{
              //execute LocalDownloadJSON
           }
}
  • Unable to resolve host "lit-hamlet-..."(my link) i have put new LocalDownloadjson().execute in the try catch statement – penta Jul 14 '15 at 11:33
  • penta, execute LocalDownloadJSON in onPostExecute. So it means you first notify onPostExecute of DownloadJSON somehow to execute it. Return null for example and check it and execute immediately – Yerzhan Tanatov Jul 14 '15 at 12:01
  • there was mistake, the async class name actually should be DownloadJSON – Yerzhan Tanatov Jul 14 '15 at 12:25
0

had you work with sqlite before ? I hope yes . for this task work with volley library that will make you more fast and easiest. If you want me to do with volley then let me know i will help u using volley. But according to your code do like this. I was not able to post these code to comment so I m re-posting my answer for you hope it help

package com.view9.datamodel;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;

import com.view9.cmap.R;

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

/**
 * Created by Ram Mandal on 7/14/15.
 */
public class test extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_layout);
        if (isNetworkOnline(test.this)) {
            new BackgroundThread().execute();
        } else {
            Toast.makeText(test.this, "No network", Toast.LENGTH_SHORT).show();
            //get json data from sqlite and send it to this method
            parseDataHere("your jsonData from sqlite");
        }

    }

    private void parseDataHere(String s) {
        //load your data here s is the jsonString
    }

    class BackgroundThread extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            String jsonString = "";
            //do task here and load your jsonStrng to jsonString variable and return it
            return jsonString;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            //test if the string is jsonObject or jsonArray here
            if (isValidJSONObject(s)) {
                //do whateever you want to do with your jsondata
                //for further use when nointernet connection is detected you can save it to sqlite
                parseDataHere(s);
            }
        }


        public boolean isValidJSONObject(String value) {

            try {
                new JSONObject(value);
            } catch (JSONException e) {
                return false;
            }
            return true;
        }
    }

    public static boolean isNetworkOnline(Context context) {
        ConnectivityManager cm =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        return netInfo != null && netInfo.isConnectedOrConnecting();

    }

}
Ram Mandal
  • 1,750
  • 1
  • 17
  • 33