Problems with JSONObject vs JSONArray in Android - java

I have a pretty specific problem I guess. I'm using Volley library to get a String response from URL, the response is following:
{"email":"imribar#gmail.com","phone":"7(707)111-11-11","family_name":"Жилин","name":"Иван","role":0}
I get this response by converting my SQL query array to JSON in PHP
$output=$db->query("SELECT email, phone, family_name, name, role FROM users WHERE email=?", "$email")->fetchArray();
$json=json_encode($output, JSON_UNESCAPED_UNICODE);
echo"$json";
What I need to do next is go throught this JSON and insert records to local database in my Android APP. In order to do that, I do following:
if(response.contains("email")) {
testResponse.setText("Response is2: " + response);
try {
JSONArray jsonArr = new JSONArray(response);
for(int i=0; i < jsonArr.length();i++){
JSONObject jsonObj = jsonArr.getJSONObject(i);
Log.i("User",jsonObj.toString());
User user = new User();
user.email= jsonObj.getString("email");
user.phone=jsonObj.getString("phone");
user.firstName=jsonObj.getString("name");
user.lastName=jsonObj.getString("family_name");
user.role=jsonObj.getInt("role");
user.token="123123123fsadf";
insertUser inewuser = new insertUser();
inewuser.execute(user);
}
} catch (JSONException e) {
Log.i("JSONerror", e.toString());
}
}
I keep getting the following error:
13:24:59.518 22389-22389/com.local.school I/JSONerror: org.json.JSONException: Value {"email":"imribar#gmail.com","phone":"7(707)111-11-11","family_name":"Жилин","name":"Иван","role":0} of type org.json.JSONObject cannot be converted to JSONArray
Any idea what I can do on PHP side to change the JSONString (add [], or add a name to an array), or what do I need to do in Android?

Your response does not have a json array, only an object. 
Array is something like this. 
[{
"email": "imribar1#gmail.com",
"phone": "7(707)990-77-72",
"family_name": "Жилин2",
"name": "Иван2",
"role": 2
},
{
"email": "imribar#gmail.com",
"phone": "7(707)990-77-71",
"family_name": "Жилин",
"name": "Иван",
"role": 0
}
]
So remove the  loop and try. 
if(response.contains("email")) {
testResponse.setText("Response is2: " + response);
try {
JSONObject jsonObj = jsonArr.getJSONObject(i);
Log.i("User",jsonObj.toString());
User user = new User();
user.email= jsonObj.getString("email");
user.phone=jsonObj.getString("phone");
user.firstName=jsonObj.getString("name");
user.lastName=jsonObj.getString("family_name");
user.role=jsonObj.getInt("role");
user.token="123123123fsadf";
insertUser inewuser = new insertUser();
inewuser.execute(user);
} catch (JSONException e) {
Log.i("JSONerror", e.toString());
}
}

I suggest you use a JsonObjectRequest instead of StringRequest when you call Volley in your app. It is almost the same as StringRequest but it gets a JSONObject as an answer.
String url = "http://my-json-feed";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// your cose goes here:
JSONObject jsonObject = new JSONObject(response.toString());
User user = new User();
user.email= jsonObject.getString("email");
user.phone=jsonObject.getString("phone");
user.firstName=jsonObject.getString("name");
user.lastName=jsonObject.getString("family_name");
user.role=jsonObject.getInt("role");
user.token="123123123fsadf";
insertUser inewuser = new insertUser();
inewuser.execute(user);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
jsonObjectRequest

Your json string has a json object as root object, while in code you are using JSONArray jsonArr = new JSONArray(response); to parse it as if it were an array. Assuming your used json library, you would have to start parsing the json using:
JSONObject jsonObj = new JSONObject(response);
The alternative would be to actually generate a json array ([...]) rather than a json object ({...}) so that your parsing code will recognise it. The choice you want to make will depend on whether you always send a single json object or whether you want to be able to send multiple json objects (in a json array).

Related

HttpRequest in java with GSON and multiple elements

I'm trying to get the "symbol" of a JSON HttpRequest in Java. I want to use GSON of google but, I can't reach any value ... I'm always with a null value in my object... I know that the error are "stock.symbol" I certainly need to put some "node" before ... I'm lost ... so ...
here the code :
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://yahoo-finance-low-latency.p.rapidapi.com/v6/finance/quote?symbols=AAPL&lang=en&region=CA"))
.header("x-rapidapi-key", "---")
.header("x-rapidapi-host", "***")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
try {
HttpResponse<String> reponse = null;
reponse = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.print(reponse.body());
Gson gson = new Gson();
Stock stock = gson.fromJson(reponse.body(), Stock.class);
System.out.println("******************************************************");
System.out.println(stock.symbol + stock.displayName + stock.quoteType);
System.out.println("******************************************************");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
here my output, you will be eable to see the answer from the api in JSON format :
{"quoteResponse":{"result":[{"language":"en-US","region":"CA","quoteType":"EQUITY","quoteSourceName":"Nasdaq Real Time Price","triggerable":true,"currency":"USD","firstTradeDateMilliseconds":345479400000,"priceHint":2,"postMarketChangePercent":-0.0956731,"postMarketTime":1621641596,"postMarketPrice":125.31,"postMarketChange":-0.120003,"regularMarketChange":-1.8799973,"regularMarketChangePercent":-1.4767083,"regularMarketTime":1621627203,"averageAnalystRating":"2.0 - Buy","tradeable":false,"esgPopulated":false,"marketState":"POSTPOST","regularMarketPrice":125.43,"regularMarketDayHigh":128.0,"regularMarketDayRange":"125.21 - 128.0","regularMarketDayLow":125.21,"regularMarketVolume":79152773,"regularMarketPreviousClose":127.31,"bid":125.37,"ask":125.37,"bidSize":12,"askSize":10,"fullExchangeName":"NasdaqGS","financialCurrency":"USD","regularMarketOpen":127.82,"averageDailyVolume3Month":103188411,"averageDailyVolume10Day":86685085,"fiftyTwoWeekLowChange":47.1575,"fiftyTwoWeekLowChangePercent":0.60247856,"fiftyTwoWeekRange":"78.2725 - 145.09","fiftyTwoWeekHighChange":-19.659996,"fiftyTwoWeekHighChangePercent":-0.13550209,"fiftyTwoWeekLow":78.2725,"fiftyTwoWeekHigh":145.09,"dividendDate":1620864000,"earningsTimestamp":1619627400,"earningsTimestampStart":1627469940,"earningsTimestampEnd":1627905600,"trailingAnnualDividendRate":0.82,"trailingPE":28.192854,"trailingAnnualDividendYield":0.006440971,"epsTrailingTwelveMonths":4.449,"epsForward":5.36,"epsCurrentYear":5.2,"priceEpsCurrentYear":24.121155,"sharesOutstanding":16687599616,"bookValue":4.146,"fiftyDayAverage":130.1347,"fiftyDayAverageChange":-4.7047043,"fiftyDayAverageChangePercent":-0.03615257,"twoHundredDayAverage":127.04788,"twoHundredDayAverageChange":-1.6178818,"twoHundredDayAverageChangePercent":-0.012734425,"marketCap":2093125599232,"forwardPE":23.40112,"priceToBook":30.253258,"sourceInterval":15,"exchangeDataDelayedBy":0,"exchange":"NMS","shortName":"Apple Inc.","longName":"Apple Inc.","messageBoardId":"finmb_24937","exchangeTimezoneName":"America/New_York","exchangeTimezoneShortName":"EDT","gmtOffSetMilliseconds":-14400000,"market":"us_market","displayName":"Apple","symbol":"AAPL"}],"error":null}}******************************************************
nullnullnull`
Process finished with exit code 0
public class Stock {
public String symbol, displayName, quoteType;}
We need to get to the JSON inside the result array:
Gson gson = new Gson();
JsonObject json = gson.fromJson(jsonStr, JsonObject.class)
.get("quoteResponse")
.getAsJsonObject()
.get("result")
.getAsJsonArray()
.get(0) // only one object in the array
.getAsJsonObject();
String symbol = json.get("symbol").getAsString();
String displayName = json.get("displayName").getAsString();
String quoteType = json.get("quoteType").getAsString();
Stock stock = new Stock(symbol, displayName, quoteType);

How do i call API with multiple parameters in android studio

I have created this app that pulls data from an API and shows it in a list. the problem I am having is that I can't pull the JSON data from an API with a nested JSON array.
In this image it is simple since all the info is in one array / table.
https://imgur.com/a/v9gsbop
but in this image, it is more difficult for me. for example, how do i call the paragraph value: line in body?
https://imgur.com/Qj5CRn8
This is the code that i am currently using to pull data from API.
private void parseJSON () {
String url = "https://blah,com";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,url,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray =response.getJSONArray("items");
for (int i = 0; i< jsonArray.length(); i++){
JSONObject article = jsonArray.getJSONObject(i);
String authorName = article.getString("article_author");
String imageUrl = article.getString("src");
String published = article.getString("first_published_at");
String description = article.getString("value");
String headline = article.getString("title");
Try this way to work with nested json array,
Try this to get the result,
Your question is not quiet clear, but what from what I understand I do think you need this solutions:
Solution: Sending Parameters along with the Request
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
textView.setText("Response: " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("parameter1 name","parameter1 Value");
params.put("parameter2 name","parameter2 Value");
return params;
};
As in the above example I have shown a get request; So suppose the URL is: "https://www.youtube.com/channel/UCXEIUll8VvOqRN-OSZ5_aOg" and parameter is "view_as" and parameter value is "subscriber" then params.put("view_as","subscriber");
Solution: If you want to pass multiple parameters to your request then,
Map<String, String> params = new HashMap();
params.put("first_param", 1);
params.put("second_param", 2);
JSONObject parameters = new JSONObject(params);
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, url, parameters, new Response.Listener<JSONObject>() { ... }
Solution: If you want to pull the items array and get its subsequent object contents, try using an iterator instead of a for loop,
JSONArray jsonArray = (JSONArray) apiResult[0].get("body");
Iterator jsonArrayIterator = jsonArray.iterator();
while(jsonArrayIterator.hasNext()) {
JSONObject jsonObject = (JSONObject) jsonArrayIterator.next();
JSONObject jsonValue = (JSONObject) jsonObject.get("value");
JSONObject jsonOriginal = (JSONObject) jsonValue.get("original");
JSONObject jsonWidth = (JSONObject) jsonOriginal.get("width");
}

I have to parse hindi text from API using volley

I want to parse a JSON response using volley, JSON response contain Hindi data also, so how can I get that Hindi data in my test view
I had just parse JSON array using JSONObject and JSONArray and just fetch data by using getString() method.
final String URL = "http://[DomainName]/getSubCategory";
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
dialog.cancel();
Log.d("1234","responce array "+response.toString());
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("sub_cat_list");
Log.d("1324","responce array "+array.toString());
for (int i = 0; i < array.length(); i++) {
JSONObject main_recipes = array.getJSONObject(i);
SubCatPojo pojo = new SubCatPojo();
pojo.setCatId(main_recipes.getString("id"));
pojo.setCatName(main_recipes.getString("name"));
pojo.setCatImage(main_recipes.getString("image"));
arrayList.add(pojo);
}
adapter.notifyDataSetChanged();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.cancel();
Toast.makeText(Listing.this, "error in network", Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> map = new HashMap<>();
map.put("p_id", catId);
return map;
}
};
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
But in logcat, I got this response
{ "sub_cat_list":[{"id":6,"name":"\u0936\u094d\u0930\u0940 \u0917\u0923\u0947\u0936 \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/shree-ganesh-ji.png"},{"id":7,"name":"\u0913\u092e \u091c\u092f \u091c\u0917\u0926\u0940\u0936 \u0939\u0930\u0947 \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/vishnu-ji.png"},{"id":8,"name":"\u0926\u0941\u0930\u094d\u0917\u093e \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/durga_ma.png"},{"id":9,"name":"\u0906\u0930\u0924\u0940 \u0936\u094d\u0930\u0940 \u0932\u0915\u094d\u0937\u094d\u092e\u0940 \u092e\u093e\u0924\u093e ","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/laxmi_ma.png"},{"id":10,"name":"\u0936\u093f\u0935 \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/shiv.png"},{"id":11,"name":"\u0936\u094d\u0930\u0940 \u0939\u0928\u0941\u092e\u093e\u0928 \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/hanuman_ji.png"},{"id":12,"name":"\u0936\u094d\u0930\u0940 \u0938\u0930\u0938\u094d\u0935\u0924\u0940 \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/banner_img\/sarswati_maa.png"},{"id":13,"name":"\u0915\u0941\u0902\u091c \u092c\u093f\u0939\u093e\u0930\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/\/banner_img\/Kunj_Bihari.png"},{"id":14,"name":"\u0936\u094d\u0930\u0940 \u0936\u0928\u093f \u0926\u0947\u0935 \u0915\u0940 \u0906\u0930\u0924\u0940","img_url":"http:\/\/poojavidhi.webepower.biz\/banner_img\/shani_dev.png"}]}
Use HTML.fromHtml() :
import android.text.Html;
String base = "\u0936\u094d\u0930\u0940 \u0917\u0923\u0947\u0936 \u0906\u0930\u0924\u0940";
String decoded = Html.fromHtml(base,Html.FROM_HTML_MODE_COMPACT).toString();
Decoded: श्री गणेश आरती
Now, I didn't really dig further with the flags you can use but this one seems to work. If you stumble upon issues, you should definitely try other flags.
Using core java, Only you have to convert the unicode characters to UTF-8.
First, get the value for key 'name' while iterating over the object and then try to apply below code, and the again set the value corresponding to the key 'name'.
I'm just showing the way to convert, a part of your sample string.
String string ="\u0913\u092e \u091c\u092f \u091c\u0917\u0926\u0940\u0936 \u0939\u0930\u0947 \u0906\u0930\u0924\u0940";
byte[] utf8 = string.getBytes("UTF-8");
string = new String(utf8, "UTF-8");
System.out.println(string);
It will give you output like : 'ओम जय जगदीश हरे आरती' |

Is there any way to handle "Array response" return from API call

I'm testing a API where it return response as a Array,I am finding it difficult in storing in list or Array?
I am using JsonPath to fetch the records
API response looks like this
[
"String1",
"String2",
"String3",
"String4",
"String5"
]
I am Using below code
Response response;
JsonPath jsonPathEvaluator = response.jsonPath();
jsonPathEvaluator.getString("[0]");
You can try following to get list of strings:
List<String> = jsonPathEvaluator.get();
or
List<String> = jsonPathEvaluator.getList("");
You could use JSONArrayRequest() method which works similar to JSONObjectRequest().
If it's for a GET request method, here is how the sample code will look like:
JsonArrayRequest requestData = JSONArrayRequest(Request.Method.GET, 'https://your-api/endpoint', null, new Response.Listener<JSONArray>(){
#Override
public void onResponse(JSONArray response){
//do whatever you want with the response data from here
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error){
//whenever there is an error in response...
// ...the code works, data is usually retrieved, just that it's not the
//... intended type
}
});
// add the request to the queue
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(requestData);
Don't forget to import the required classes.
It is better if you have tags for you element lists if they are of one type:-
{
"Strings":[
"String1",
"String2",
"String3",
"String4",
"String5"
]
}
JsonArray arrObj = empObj.getJsonArray("Strings");
This will return you a JsonArray that you can convert to any type based on your requirement
If you cannot change the input json , maybe this could help :-
String [] json = new String[10];
obj = parser.parse(response);
String jsoString = obj.toString();
List<String> items = Arrays.asList(jsoString.split("\\s*,\\s*"));

how to correctly use search query of Facebook graph API (android)?

I'm trying to run a query to search for locations using search query facebok graf api for android.
If I try to run this query in the Graph API Explorer, I get this result.
But programmatically it is impossible. I try to make so:
new GraphRequest(AccessToken.getCurrentAccessToken(),"/search?q=coffee&type=place&center=37.76,-122.427",null,HttpMethod.GET,new GraphRequest.Callback()
{
public void onCompleted(GraphResponse response)
{
Log.v("HelloFacebook", response.toString());
}
}).executeAsync();
}
i get nothing (param distance must be number)
if I try without distance i get too nothing, but another message (An access token is required to request this resourse and too)
What could be the problem?
Right syntax for search in Facebook graph API:
GraphRequest request = GraphRequest.newGraphPathRequest(
accessToken,
"/search",
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
// Insert your code here
}
});
Bundle parameters = new Bundle();
parameters.putString("type", "place");
parameters.putString("center", "53,27");
parameters.putString("distance", "30000");
request.setParameters(parameters);
request.executeAsync();
The syntax that Vadim Korzun provided did unfortunately not directly work for me. But it gave me some ideas. I wanted to search for people by names. Here the code I impelemted according to the newPlacesSearchRequest(...)-method of the official GraphRequest-class:
AccessToken accessToken = AccessToken.getCurrentAccessToken();
Bundle parameters = new Bundle(2);
parameters.putString("type", "user");
parameters.putString("q", "Albert Einstein");
GraphRequest.Callback wrapper = new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
try {
JSONObject jso = response.getJSONObject();
JSONArray arr = jso.getJSONArray( "data" );
for (int i = 0; i < (arr.length()); i++) {
JSONObject json_obj = arr.getJSONObject(i);
// START: Your code goes here
String id = json_obj.getString("id");
String name = json_obj.getString("name");
// ...
// END: Your code goes here
}
} catch (JSONException e) {
Log.e("name: ", e.getMessage());
}
}
};
GraphRequest gr = new GraphRequest(accessToken, "search", parameters, HttpMethod.GET, wrapper);
gr.executeAsync();
hope this helps...

Categories