Search code examples
androidhttpandroid-4.0-ice-cream-sandwichhttpconnection

Error in HTTP connection on Android 4 or higher?


I'm trying to get information from a JSON-file using HTTPCLient. The strange thing is that when I run the application on my own phone (HTC Desire HD with Android 2.3) or on the emulator with Android 2.1 everything works. But when I run my application on the emulator with Android 4.1.2, on a HTC One X (Android 4.1.1) or on a Samsung Galaxy SIII (Android 4.0.4) the application crashes (see stacktrace at the end of the post).

Does anyone know what the problem is? And if not, is there another way to call my JSONfile? Maybe then it will work..

I really hope someone can help me, please tell me if my question isn't clear enough.

RoosterWijzigingen.java (there is some code missing to make it shorter, because it's not relevant for the question):

package pws.sgdbroosterapp;

public class RoosterWijzigingen extends ListActivity {

    JSONArray jArray;
    String result = null;
    InputStream is = null;
    StringBuilder sb = null;
    JSONArray klassen = null;
    JSONArray mededelingen = null;
    JSONArray rooster = null;
    String status = null;
    String type = null;
    String datum = null;
    String versie = null;
    String minutenperlesuur = null;
    String afwezig = null;
    String mededeling = null;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState); 

        JSONObject json = JSONfunctions.getJSONfromURL("http://selenight.nl/Wijzigingen/2.1/wijzigingen.json");

        //new AsyncTask<Void, Void, String>() {

          //@Override
          //protected String doInBackground(Void... params) {
            // Runs on own thread 
            //JSONObject json = JSONfunctions.getJSONfromURL("http://selenight.nl/Wijzigingen/2.1/wijzigingen.json"); 

            //return json.toString(); 
          //} 

          //protected void onPostExecute(String result) { 
            // someMethod(Send json);
            //Log.v("Stackoverflow", result);
          //}

        //}.execute();


            try{
                // Getting Array of Klassen
                klassen = json.getJSONArray("klassen");

                // Status, type, datum, versie, minutenperlesuur, afwezig en medeleningen worden uit JSOn file gehaald en opgeslagen in Strings
                status = json.getString("status");
                                        //"failure";
                type = json.getString("type");
                datum = json.getString("datum");
                versie = json.getString("versie");
                minutenperlesuur = json.getString("minutenperlesuur");
                afwezig = json.getString("afwezig");
                mededelingen = json.getJSONArray("mededelingen");
                mededeling = mededelingen.toString();


            }catch(JSONException e)        {
                 Log.e("log_tag", "Error parsing data "+e.toString());
            }

        setContentView(R.layout.listplaceholder); 

            if(Integer.parseInt(minutenperlesuur) < 50){
            TextView verkortrooster = new TextView(this);
            verkortrooster.setText("---   Het is "+minutenperlesuur+"min-rooster!  --- ");
            }

            TextView statusdatum = new TextView(this);
            statusdatum.setText("Dit is versie "+versie+" van "+datum+". \n");

            TextView afwezigt = new TextView(this);
            afwezigt.setText("Afwezig:");

            TextView afwezigtextt = new TextView(this);
            afwezigtextt.setText(afwezig+"\n");

            TextView mededelingent = new TextView(this);
            mededelingent.setText("Mededelingen:");

            TextView mededelingentextt = new TextView(this);
            mededelingentextt.setText(mededeling+"\n \n");

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(Menu.NONE, 0, 0, "Settings");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       switch (item.getItemId()) {
            case 0:
            startActivity(new Intent(this, Preferences.class));
            return true;
       }
       return false;
    }
 }

JSONfunctions.java:

public class JSONfunctions {
    public static JSONObject getJSONfromURL(String url){
        InputStream is = null;
        String result = "";
        JSONObject jArray = null;

        //http post
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
        } catch(Exception e) { Log.e("log_tag", "Error in http connection" + e.toString()); }


        //convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        } catch(Exception e) { Log.e("log_tag", "Error converting result" + e.toString()); }

        try { jArray = new JSONObject(result); }
        catch(JSONException e) { Log.e("log_tag", "Error parsing data "+e.toString()); }

        return jArray;
    }
 }

Manifest file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="pws.sgdbroosterapp"
        android:versionCode="1"
        android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Roosterwijziging"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".RoosterWijzigingen"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".Preferences"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="portrait" >
        </activity>

        <uses-library
              android:name="android.test.runner"
              android:required="true" />
    </application>
    <uses-permission android:name="android.permission.INTERNET" /> 
 </manifest>

Stacktrace:

01-05 15:12:49.995: E/log_tag(615): Error in http connection android.os.NetworkOnMainThreadException
01-05 15:12:49.995: E/log_tag(615): Error converting result java.lang.NullPointerException
01-05 15:12:49.995: E/log_tag(615): Error parsing data org.json.JSONException: End of input at character 0 of 
01-05 15:12:50.005: D/AndroidRuntime(615): Shutting down VM
01-05 15:12:50.005: W/dalvikvm(615): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
01-05 15:12:50.015: E/AndroidRuntime(615): FATAL EXCEPTION: main
01-05 15:12:50.015: E/AndroidRuntime(615): java.lang.RuntimeException: Unable to start activity ComponentInfo{pws.sgdbroosterapp/pws.sgdbroosterapp.RoosterWijzigingen}: java.lang.NullPointerException
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.os.Looper.loop(Looper.java:137)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.ActivityThread.main(ActivityThread.java:4745)
01-05 15:12:50.015: E/AndroidRuntime(615):  at java.lang.reflect.Method.invokeNative(Native Method)
01-05 15:12:50.015: E/AndroidRuntime(615):  at java.lang.reflect.Method.invoke(Method.java:511)
01-05 15:12:50.015: E/AndroidRuntime(615):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-05 15:12:50.015: E/AndroidRuntime(615):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-05 15:12:50.015: E/AndroidRuntime(615):  at dalvik.system.NativeStart.main(Native Method)
01-05 15:12:50.015: E/AndroidRuntime(615): Caused by: java.lang.NullPointerException
01-05 15:12:50.015: E/AndroidRuntime(615):  at pws.sgdbroosterapp.RoosterWijzigingen.onCreate(RoosterWijzigingen.java:153)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.Activity.performCreate(Activity.java:5008)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
01-05 15:12:50.015: E/AndroidRuntime(615):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)   

Solution

  • You are running HttpClient on Main thread

    android.os.NetworkOnMainThreadException
    

    Wrap your json call

    JSONObject json = JSONfunctions.getJSONfromURL(URL);
    

    with a AsyncTask, somthing like this

    new AsyncTask<Void, Void, Void>() {
    
            @Override
            protected Void doInBackground(Void... params) {
                JSONObject json = JSONfunctions.getJSONfromURL(URL);
                Log.v("Stackoverflow", json.toString());
                return null;
            }
    
        }.execute();
    

    Do not forget to add Internet Access permission

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

    Regards