Parsing extremely simple JSON from a URL in in Android - java

I have tried everything online to try to parse this JSON but nothing seems to work. Here is the JSON:
{"salonphoebe":true,"salonvo":false}
That's it. It is only booleans. It is from an HTTP website if that is important at all.
How do I do parse this extremely simple JSON from http://example.com in Java in Android Studio? I am trying to create Booleans based on these in my app. I know this question is on this website a lot but I have literally tried 10 solutions but nothing will work. Thank you.

Try the following code.
try {
JSONObject json = new JSONObject(your - json - string - here);
boolean b1 = json.optBoolean("salonphoebe");
boolean b2 = json.optBoolean("salonvo");
} catch (JSONException e) {
e.printStackTrace();
}

Okay I have solved my own problem. Here is everything I learned and what I did. I want to help anyone else with this problem if they come across this issue. First I added this to my androidmanifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Then I added this between the tags in the androidmanifest.xml beucase the link I am parsing the JSON from is an HTTP link:
android:usesCleartextTraffic="true"
Really quickly import all of this into your mainactiviy.java:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
Then we get into the hard stuff. There are two parts to parsing JSON data from the internet. First, you must read the JSON (meaning put the JSON from online into a String) from the URL and then you must organize the String of JSON into separate variables. So let's start on the HTTP Request. I created an Async class in my MainActivity.java (under the OnCreate) that I found online that looks like this:
public class HttpGetRequest extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
String url = "http://example.com/example.php";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
System.out.println("Test");
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
String jsonResponse = response.toString();
return jsonResponse;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject json = new JSONObject(result);
boolean myJsonBool = json.optBoolean("samplestringinyourjson");
if(hasPaid){
//do something
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Okay so basically the reason we put this in an Async class is because java won't let you make an HTTP Request in your OnCreate. What the doInBackground is doing is fetching the JSON data and putting it into the string like I said. The OnPostExecute is separating that string into boolean values and doing stuff with it. Lastly, paste this into your OnCreate or it won't work:
new HttpGetRequest().execute();
That's it. If you have questions ask and hopefully I can see it.

Related

asynctask working in emulator with api 24 and not working in real device with api 28

i am using asynctask to fetch data from my hosted web page using the default java httpurlconnection library and apparently the doinbackground method does not execute on my android 9 device but i can receive the json response when tested with emulator api 24. also i declared internet permission in the manifest and i have firebase woking fine, so no internet problem. is there any explanation for this situation? is there any solution while keep using asynctask with httpurlconnection? please help, i have to present my app in two days.
sendDataAsync.class
package com.example.control;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import android.os.AsyncTask;
class sendDataAsync extends AsyncTask<String , Void , String>{
private AsyncResponse delegate = null;
private String serverURL, responsemsg = "Not connected to host",entries;
public sendDataAsync(String name, String prename, String email, String gender, String password, String cfirmpassword) {
entries = "name="+name+"&prename="+prename+"&email="+email+"&gender="+gender+"&password="+password+"&cfirmpassword="+cfirmpassword;
serverURL = "http://iotcontrol.atwebpages.com/Register.php";
}
public sendDataAsync(String email, String password) {
entries = "password="+password+"&email="+email;
serverURL = "http://iotcontrol.atwebpages.com/Login.php";
}
public void setDelegate(AsyncResponse del){
this.delegate = del;
}
#Override
protected String doInBackground(String... params) {
try {
//entries = URLEncoder.encode(entries,"utf-8");
URL url = new URL(serverURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty( "charset", "utf-8");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
writer.write(entries);
writer.flush();
writer.close();
os.close();
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String inputLine;
StringBuilder sb = new StringBuilder();
while ((inputLine = reader.readLine()) != null) {
sb.append(inputLine);
}
reader.close();
is.close();
conn.disconnect();
responsemsg = sb.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return responsemsg;
}
#Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
in my activity i have this
public void insertData() {
sendDataAsync sendPostReqAsyncTask = new sendDataAsync(nameValue, prenameValue, emailValue, genderValue,passwordValue,cfirmpasswordValue);
sendPostReqAsyncTask.setDelegate(this);
sendPostReqAsyncTask.execute();
}
/*
for some reason i cant access logcat so i just have a textview and print the response to it
and while on the emulator api24 i have the text view: {"ok":false,"message":"invalide data"}
but on my android 9 phone i have the text: Not connected to host
*/
public void processFinish(String output) {
TextView txt = (TextView)findViewById(R.id.textView3);
txt.setText(output);
}
Starting with Android 9, cleartext traffic such as http is not permitted by default.
If the server supports it, use https instead.
If the server does not support https, you need to specifically opt in for cleartext traffic. You can do it app-wide with manifest but it's better to enable it only for one host with network security config.
Mostly looks like an issue of Cleartext. Please follow the below shared link
https://medium.com/#son.rommer/fix-cleartext-traffic-error-in-android-9-pie-2f4e9e2235e6
If it's cleartext issue, check your logcat, it will throw an error in logcat.
Plus please note that Async Task has been deprecated from API 30. Since you are using Java you can start looking into RXJAVA for this and retrofit to make API calls.

Extracting Values Not Working JSON file?

I am newbie in java programming. I am trying to get Instagram users full name. and below is my code
package gibs.smith.testapp;
import android.os.AsyncTask;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class fetchData extends AsyncTask<Void,Void,Void> {
private String name = "";
private String link ="";
#Override
protected Void doInBackground(Void... voids) {
try {
URL url= new URL("https://instagram.com/priya.p.varrier/?__a=1");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while (line !=null){
line =bufferedReader.readLine();
JSONObject jo= new JSONObject(line);
JSONObject user=jo.getJSONObject("user");
name=user.getString("full_name");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
MainActivity.data.setText(this.name);
}
}
but it is not working. it dose not extracts the string value "full_name".
It is retrieving the JSON file but not the desired value.
The URL is https://instagram.com/priya.p.varrier/?__a=1
any help would be great.
----Edit-----
adding graphql object causes app crash and below is catlog output
here is the log
https://justpaste.it/1itsa
First the bug. It must be NullPointerException.
while (line !=null)
it will run until line = null. Then this line will give you the exception.
new JSONObject(line);
and you shoud get the graphql first.
so the solution should look like this.
if(line != null) {
JSONObject jo = new JSONObject(line);
JSONObject graphql = jo.getJSONObject("graphql");
JSONObject user = graphql.getJSONObject("user");
name = user.getString("full_name");
}
As per your JSON
your full_name key is inside user JSONObject which is inside graphql JSONObject.
So to get the full_name value you have to first retrieve graphql JSONObject.
JSONObject jo = new JSONObject(line);
JSONObject graphqlObj = jo.getJSONObject("graphql");
JSONObject user = jographqlObj.getJSONObject("user");
name=user.getString("full_name");
You can use http://jsonviewer.stack.hu/ to check JSON structure of your file.

Android HTTPUrlConnection SocketTimeoutException/Indefinite Hang?

I'm working on an Android app for a client, and I'm calling their API to get the info for various parts of my app. There is one call that results on SocketTimeoutException if I set a timeout, or infinitely hangs if I don't; however, it works just fine on the web client(React), so it can't be the server.
Code:
package io.voluntu.voluntu;
import android.os.AsyncTask;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
public class SendApproveHours extends AsyncTask<Bundle, Void, String>{
private StringBuilder sb = new StringBuilder();
private String result;
private ApproveHours approveHours;
public SendApproveHours(ApproveHours approveHours){
this.approveHours = approveHours;
}
protected String doInBackground(Bundle... params){
Bundle b = params[0];
String jwt = b.getString("JWT");
System.out.println(jwt);
boolean approve = b.getBoolean("APPROVE");
int[] id = b.getIntArray("ID");
try {
URL url = new URL("http://voluntu.io/api/hour/update");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(2500 /* milliseconds */); //if i don't do this, it will hang indefinitely
httpURLConnection.setReadTimeout(1500 /* milliseconds */);
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Host", "voluntu.io");
httpURLConnection.setRequestProperty("Origin", "http://voluntu.io");
httpURLConnection.setRequestProperty("Referer", "http://voluntu.io/hours/approve");
httpURLConnection.setRequestProperty("Cookie", "sessionJWT=" + jwt);
httpURLConnection.connect();
JSONObject jsonObject = new JSONObject();
jsonObject.put("approveOrReject", approve);
jsonObject.put("hourIDs", Arrays.toString(id));
System.out.println(jsonObject);
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
wr.writeBytes(jsonObject.toString());
wr.flush();
wr.close();
int HttpResult = httpURLConnection.getResponseCode(); //hangs here
System.out.println("HTTP RESULT: " + HttpResult);
if(HttpResult == HttpURLConnection.HTTP_OK){
BufferedReader in = new BufferedReader(new InputStreamReader(
httpURLConnection.getInputStream(), "utf-8"
));
String line;
while((line = in.readLine()) != null){
sb.append(line);
}
in.close();
}
System.out.println("RESPONSE: " + sb.toString());
httpURLConnection.disconnect();
}
catch (MalformedURLException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
catch (JSONException e){
e.printStackTrace();
}
return sb.toString();
}
protected void onPostExecute(String result){
approveHours.refreshHours();
}
}
It hangs on getting the HTTP response code for some reason. I checked the headers and body and they are identical to what the web version is sending, so I have no idea why it's not working. Also, calling other parts of their API works just fine, and in fact this code is mostly copy pasted from other parts of my app that call the API. Help is appreciated!
I fixed it. Instead of an array, you must use JSONArray, or the array gets wrapped in quotes when it gets put in the JSON object.

Using Java with SleepyMongoose to perform MongoDB inserts

this is my first post here.
In a nutshell, I've set up a MongoDB instance, and installed a REST service to run commands on it. The one I chose was SleepyMongoose.
I've been trying to write a simple Java program to do three things: a find, an insert, and another find. Basically, display the collection, insert something, and display it again to show the update. The finds work correctly, but the insert has been giving me trouble.
The documentation of SleepyMongoose uses curl with a data parameter, but I've been using Java's HttpURLConnection. How can I add that data parameter to the HttpURLConnection? Here's what I've been trying:
private static void POST (String command) {
try {
// The 'command' is just going to be 'insert' for now.
URL restURL = new URL(REST + DATABASE + "/" + COLLECTION + "/_" + command);
HttpURLConnection conn = (HttpURLConnection) restURL.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.connect();
OutputStream out = conn.getOutputStream();
String x = "docs=[{'x':1}]";
out.write(x.getBytes());
out.close();
conn.disconnect();
}
catch (Exception e) {
System.out.println("Uh oh...");
e.printStackTrace();
}
}
Am I even using SleepyMongoose for its correct purpose? Are there better alternatives? I'm not tied down to any REST api, but I'd like to get the inserts down.
Thanks everyone
For some reason, it only works if there's a reader attached to it, too. If I attach the following immediately after the write, it works perfectly:
String line, output = "";
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null)
output += line;
rd.close();
Can someone explain this?
I happen to be writing similar code for an Android project and have had success with the below when doing a POST.
Note that the data you get back will need to be parsed as it comes in as a HttpResponse. I have been converting it to a String then pulling out JSON values (see below).
Sample insert:
String[] link2 = {"http://XXX.XXX.XXX.XXX:27080/foo/bar/_insert", "[{\"x\":2},{\"x\":3}]"};
new HTTPPost().execute(link2);
Code for POST, yours will be different due to not writing for Android specifically. Replace AndroidHttpClient with HttpClient. Note the BasicNameValuePair used to specify "docs" as key.
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
protected HttpResponse doInBackground(String... params) {
String link = params[0];
String value = params[1];
HttpPost post = new HttpPost(link);
AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("docs", value));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
return client.execute(post);
} catch (IOException e) {
return null;
} finally {
client.close();
}
}
To parse to string:
String test = EntityUtils.toString(result.getEntity());
To pull out JSON values:
public String parseJSON(String toParse)
{
try {
JSONObject jObject = new JSONObject(toParse);
String aJsonString = jObject.getString("ok");
JSONArray jArray = jObject.getJSONArray("results");
for (int i = 0; i < jArray.length(); i++) {
try {
JSONObject oneObject = jArray.getJSONObject(i);
// Pulling items from the array
String oneObjectsItem = oneObject.getString("link");
return oneObjectsItem;
} catch (JSONException e) {
// Oops
}
}
} catch (Exception ex) {
}
return "";
}

Source not found error after HttpClient.execute()

I am new to android development. I have the following class for downloading some data in JSON format. I keep getting a Source not found error on the
HttpResponse httpResponse = httpClient.execute(httpPost);
line... I'm sure this must be a simple fix... Here is the class code...
package com.example.tankandroid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
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();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Put this code in onCreate method
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
Use Apache HttpCore and HttpClient libraries. Put these two libraries into your lib folder, its automatically add these into your build path.
One reason for this situation may be missing internet permissions in AndroidManifest.xml file. Adding this line in manifest will fix the issue.
<uses-permission android:name="android.permission.INTERNET" />
You need to provide some more information I think. Where do you get the "Source not found" error? Is it an Eclipse error that prevents you from compiling. Is it during compilation? Is it a runtime error? Could this be a possible duplicate of: Source not found Android? ?
Question: Why are you doing an HTTP POST if you don't intend to add any POST data? A GET seems more appropriate.
And since you also ask "I'm sure this must be a simple fix" then yes, it is. I'd really suggest that you rip out your HTTP code and switch to Android Asynchronous Http Client. It's super easy to work with and very well suited for getting an HTTP response and parsing it. Example:
AsyncHttpClient client = new AsyncHttpClient();
RequestParams rp = new RequestParams();
rp.put("some_param", "some value");
rp.put("another_param", "some other value");
client.post("http://www.simonsayssolutions.co.uk/index.php", rp, new AsyncHttpResponseHandler() {
#Override
public final void onSuccess(String response) {
// handle your response and parse JSON here
}
#Override
public void onFailure(Throwable e, String response) {
// something went wrong
}
});
or GET:
client.get("http://www.simonsayssolutions.co.uk/index.php", rp, new AsyncHttpResponseHandler() {
...
}
And finally if you want to simplify JSON parsing have a look at Jackson or Gson. Especially if you want to parse JSON data to Java objects and vice versa.

Categories

Resources