Newbie Question: loadJSONObject in a Thread not working on Processing for Android (retrieving a JSON object HTTP)

Hello,

Many thanks in advance for looking at this.

I’ve used the simple example code below from the Processing “thread()” reference:

String time = "";

void setup() {
  size(100, 100);
}

void draw() {
  background(0);
  // Every 30 frames request new data
  if (frameCount % 30 == 0) {
    thread("requestData");
  }
  text(time, 10, 50);
}

// This happens as a separate thread and can take as long as it wants
void requestData() {
  JSONObject json = loadJSONObject("http://time.jsontest.com/");
  time = json.getString("time");

This works ok when running the sketch in Processing (Java), but when I switch to Android (running on a Samsung Galaxy S8) the app builds and loads ok but no time is displayed and its throwing these errors (repeatedly) to the processing console.

at java.io.BufferedReader.read(BufferedReader.java:193)
at processing.core.PApplet.createReader(PApplet.java:4715)
at processing.core.PApplet.createReader(PApplet.java:4666)
at processing.core.PApplet.loadJSONObject(PApplet.java:4133)
at processing.test.sketch_200421a.sketch_200421a.requestData(sketch_200421a.java:37)
at java.lang.reflect.Method.invoke(Native Method)
at processing.core.PApplet.method(PApplet.java:2862)
at processing.core.PApplet$4.run(PApplet.java:2892)
java.lang.RuntimeException: java.io.IOException: Stream closed
at processing.data.JSONTokener.next(JSONTokener.java:157)
at processing.data.JSONTokener.nextClean(JSONTokener.java:231)
at processing.data.JSONObject.(JSONObject.java:241)
at processing.data.JSONObject.(JSONObject.java:226)
at processing.core.PApplet.loadJSONObject(PApplet.java:4134)
at processing.test.sketch_200421a.sketch_200421a.requestData(sketch_200421a.java:37)
at java.lang.reflect.Method.invoke(Native Method)
at processing.core.PApplet.method(PApplet.java:2862)
at processing.core.PApplet$4.run(PApplet.java:2892)
Caused by: java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:161)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:347)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:172)
at java.io.BufferedReader.read(BufferedReader.java:193)
at processing.data.JSONTokener.next(JSONTokener.java:155)
… 8 more
(HTTPLog)-Static: isSBSettingEnabled false
java.io.IOException: Cleartext HTTP traffic to time.jsontest.com not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:467)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at processing.core.PApplet.createInputRaw(PApplet.java:4855)
at processing.core.PApplet.createInput(PApplet.java:4809)
at processing.core.PApplet.createReader(PApplet.java:4661)
at processing.core.PApplet.loadJSONObject(PApplet.java:4133)
at processing.test.sketch_200421a.sketch_200421a.requestData(sketch_200421a.java:37)
at java.lang.reflect.Method.invoke(Native Method)
at processing.core.PApplet.method(PApplet.java:2862)
at processing.core.PApplet$4.run(PApplet.java:2892)
java.io.IOException: Stream closed

I have enabled all permissions on the Sketch itself and for the App when its running on Android, also I commented out the Thread call and the app just sat there no errors - so I’m pretty sure it’s something to do with that.

I suspect I am missing something like a library or there needs to be a different way to access HTTP thru’ android etc?

Processing Version 3.5.4
Win 10 64 Bit
SDK Android 9.0 (Pie) API 28
Samsung Galaxy S8 (device in which I run the sketch)

Any suggestions most appreciated.

Thanks,

Bob.

1 Like

@BobFishcake ===
the problem you get is from your url, which is http but not https; try your code with MM and you can see that it works; but android changes the security rules with OS 8+; so, as it is only an example, find another url https and try…

2 Likes

Many thanks for your quick and accurate response - I’ve now tried some different HTTPS endpoints and they all work as expected.

I have 2 remaining questions (thanks in advance for any help with these):

  1. When the app is running on my Galaxy S8, a “stream” of these warnings now appear in the Processing console:

(HTTPLog)-Static: isSBSettingEnabled false
(HTTPLog)-Static: isSBSettingEnabled false
(HTTPLog)-Static: isSBSettingEnabled false

Googling around, it seems to be something to do with Samsung devices?

  1. What are the minimum permissions I should give set for this app to keep it working but as secure as possible? At the moment it has all permissions.

Thanks again,

Bob.

@BobFishcake ===

  • as you are using android 9 default rule is false: that means that you cannot use http; not sure but perhaps you can try to add ```
    android:usesCleartextTraffic=“true”> to your Manifest and see what happens. Anyway these are only warnings fired each time you try to connect to the url and it does not matter.

  • Internet is the only permission you have to set (also WriteExternalStorage if you want to keep your JSON file)

2 Likes

Many thanks again -

android:usesCleartextTraffic=“true” didn’t seem to work, but as you say nothing to worry about, so I’ll ignore it.

I’ve set just the Internet access permission - all works no problems.