0

Upgraded to Android Api 28. Now im getting an curios JSONException. Actually its not clear how I can solve the problem. I know why this is happen, but I don't know how to fix it at this time.

This part should produce the error "String result = "";" and on line 74 on this part "JSONObject json = new JSONObject(result);" JSON crashed

GetJsonResults

import java.io.InputStreamReader;

public class GetJsonResults extends AsyncTask<String, Void, String> {
    private final static String LOG_TAG = GetJsonResults.class.getSimpleName();

    private static String GET(String url) {
        InputStream inputStream;
        String result = "";
        try {

            // create HttpClient
            HttpClient httpclient = new DefaultHttpClient();

            // make GET request to the given URL
            HttpResponse httpResponse = httpclient.execute(new HttpGet(url));

            // receive response as inputStream
            inputStream = httpResponse.getEntity().getContent();

            // convert inputstream to string
            if (inputStream != null)
                result = convertInputStreamToString(inputStream);
            else
                result = "Did not work!";

        } catch (Exception e) {
            Log.d("InputStream", e.getLocalizedMessage());
        }

        return result;
    }

    private static String convertInputStreamToString(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        String result = "";
        while ((line = bufferedReader.readLine()) != null)
            result += line;

        inputStream.close();
        return result;

    }

    @Override
    protected String doInBackground(String... urls) {

        return GET(urls[0]);
    }

    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
        //Toast.makeText(getBaseContext(), "Daten erfolgreich empfangen!", Toast.LENGTH_LONG).show();
        try {
            JSONObject json = new JSONObject(result);
2019-07-11 16:59:02.919 10072-10072/com.radio.xxxxxxSRAPPID D/SplashActivity: Get JSON Results
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID D/GetJsonResults: There was an JSONException
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID W/System.err: org.json.JSONException: Value http of type java.lang.String cannot be converted to JSONObject
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID W/System.err:     at org.json.JSON.typeMismatch(JSON.java:112)
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID W/System.err:     at org.json.JSONObject.<init>(JSONObject.java:163)
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID W/System.err:     at org.json.JSONObject.<init>(JSONObject.java:176)
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID W/System.err:     at com.radio.xxxxxx.task.GetJsonResults.onPostExecute(GetJsonResults.java:74)
2019-07-11 16:59:04.312 10072-10072/com.radio.xxxxxxSRAPPID W/System.err:     at com.radio.xxxxxx.task.GetJsonResults.onPostExecute(GetJsonResults.java:21)
  • 1
    Post the json string you're trying to parse. – Chrisvin Jem Jul 11 '19 at 15:20
  • This seem related to the clear text http. Since Android 9 (API Level 28), Android block http, use https. see https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted – ישו אוהב אותך Jul 11 '19 at 15:22
  • Its not the JSON String. When I manually insert the JSON String here "String result = "MYFULLSTRING";" it was working. But then the App only used the parts that I manually entered and not the Dynamically parts that the file normally gets from an url. –  Jul 11 '19 at 15:24
  • Big thanks @ישו אוהב אותך. android:usesCleartextTraffic="true" was the solution! –  Jul 11 '19 at 15:27
  • You may also run into this again if you ever hit the condition where you say result = "Did not work!". You should convert that to a json string such as "{error : Did not work!}". – Michael Dougan Jul 11 '19 at 15:47

1 Answers1

0

This is happening because http calls are disabled by default in API 28, you can use the below work around to enable http calls in API 28,

In your AndroidManifest.xml, put

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config">




    </application>
</manifest>

Create network_security_config.xml file in resource directory and paste below source in it,

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

OR use only android:usesCleartextTraffic="true" in app class

This will allow http calls in your app, for more info please check, https://stackoverflow.com/a/51902630/4360419

also documentation here,

https://developer.android.com/about/versions/pie/android-9.0-changes-28

Arsal Imam
  • 2,882
  • 2
  • 24
  • 35
  • Thanks! I added "android:usesCleartextTraffic="true"" to AndroidManifest.xml under application. This was enough and its working now. Its nothing privacy related, but it seems to be an good idea to switch to https. –  Jul 11 '19 at 15:34
  • 1
    While this is an effective work-around, it is not an ideal solution. Chrome dropped HTTP support for a reason (it is inherently insecure). You should really take a look at what part of your system is still relying on the use of HTTP, and see if you can upgrade to HTTPS instead. – Michael Dougan Jul 11 '19 at 15:44