How to parse data from pubnub history callback resonse? - android

History callback is shown below,I need to parse Object response (message) which response is given below for reference.Object message - params which produce nested array without any keyword and nested object with keyword as message.
pubnub.history(request_id, true, 100, new Callback() {
#Override
public void successCallback(String channel, Object message) {
super.successCallback(channel, message);
Log.e(TAG, "successCallback: History Messages" + message);
}
#Override
public void errorCallback(String channel, PubnubError error) {
super.errorCallback(channel, error);
Log.e(TAG, "successCallback: History Messages error" + error);
}
});
Here is my Object response message.
Response:-
[ //array 1
[ // array 2
{ //obj 1
"message":{
"message":"Hai",
"timestamp":1507105493379,
"type":"SENT",
"userId":137
},
"timetoken":15071054937865507
},
{ //object 2
"message":{
"message":"How are you ?",
"timestamp":1507105503320,
"type":"SENT",
"userId":137
},
"timetoken":15071055037143632
},
{ //object 3
"message":{
"message":"Fyn",
"timestamp":1507105505628,
"type":"SENT",
"userId":137
},
"timetoken":15071055060355900
}
], //array 1 end
15071054937865507,
15071055060355900
]
//array 2 end
How to parse this response.

You can parse your JSON using below code
Call parseJson() inside your successCallback method and pass message.toString() to parse method like this:
public void successCallback(String channel, Object message) {
super.successCallback(channel, message);
Log.e(TAG, "successCallback: History Messages" + message);
parseJson(message.toString());
}
JsonParse method:
private void parseJson(String jsonStr) {
try{
JSONArray jsonArray = new JSONArray(jsonStr);
JSONArray innerJsonArray = jsonArray.getJSONArray(0);
for(int i = 0; i < innerJsonArray.length(); i++) {
JSONObject jsonObject = innerJsonArray.getJSONObject(i);
JSONObject jsonObjectMessage = jsonObject.getJSONObject("message");
String msg = jsonObjectMessage.getString("message");
//TODO you can get all other fields
}
}catch (JSONException e){
e.printStackTrace();
}
}

first of all this is not a valid JSON, maybe this is way you are having trouble parsing it.
when you'll get a valid json (and you can check if it is a valid json in here https://jsonlint.com/) , you will need to first cast it from a string as a json object and then get every child and every child of a child ans so on until u get the whole object.
you should use some json parser like this one:http://json.parser.online.fr/ to help you understand what object is a child of what
good luck

Related

for not running in onPostExecute

I am getting some info from the server and the for used in onPostExecute was supposed to store the data into 2 different arrays. The server's response it's alright, it gets to the app, it is recognized as a JSON object, but when it comes to transforming it to a JSONArray to get the elements it just gets over that part of the code, as it wouldn't be written. So, after the JSONArray departamenteArray = obj.getJSONArray("departamente"); line, it just goes over the rest of it without making any changes.
.java code:
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//hiding the progressbar after completion
try {
//converting response to json object
JSONObject obj = new JSONObject(s);
//if no error in response
if (!obj.getBoolean("error")) {
JSONArray departamenteArray = obj.getJSONArray("departamente");
for (int i = 0; i < departamenteArray.length(); i++) {
JSONObject dep = departamenteArray.getJSONObject(i);
// Verificare daca s-au primit probleme trimise de server
if (!dep.isNull("Departament")) {
String departament = SchimbareDiactritice(dep.getString("Departament")).replace("&","");
String id_departament= dep.getString("id_departament");
id_departamente.add(id_departament);
departamente.add(departament);
}
}
} else {
Toast.makeText(getApplicationContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
layout_validare.setVisibility(GONE);
linearLayout_obs_redirectionare.setVisibility(View.VISIBLE);
}
JSON response from the server :
{
"error": false,
"message": "Alerte reimprospatate",
"departamente": [{
"Departament": "Parcări",
"id_departament": 2
}, {
"Departament": "Trafic rutier și iluminat public",
"id_departament": 3
}, {
"Departament": "Salubritate și vandalism",
"id_departament": 4
}, {
"Departament": "Altele",
"id_departament": 5
}]
}
.php code on the server side:
if($stmt->num_rows > 0){
$stmt->bind_result($departament, $id_departament);
while($stmt->fetch()) {
$departamente[] = array (
"Departament"=>$departament,
"id_departament"=>$id_departament
);
$response['error'] = false;
$response['message'] = 'Alerte reimprospatate';
$response['departamente']= $departamente;
It seems that after a restart of the Android Studio it works. It must have been only a bug. The code shown above it's working properly.

Android - How to Represent JSON Information from URL through GSON

I have been attempting to retrieve information from an online JSON Source using a URL. I initially got the information parsed to a TextView in Android, however I got ALL Information from the JSON. Below is a screenshot of what I am referring to.
Text View Showing All Data In Json
Essentially, What I want is to just show the Location, so in the above example, Oslo, in Norway in one Textview, then in another show the Current Moon Phase for that location, so - using the above example again, Waxing Crescent.
This is the JSON I am using.
{
"version": 2,
"locations": [{
"id": "187",
"geo": {
"name": "Oslo",
"country": {
"id": "no",
"name": "Norway"
},
"latitude": 59.913,
"longitude": 10.740
},
"astronomy": {
"objects": [{
"name": "moon",
"days": [{
"date": "2018-09-13",
"events": [],
"moonphase": "waxingcrescent"
}]
}]
}
}]
}
To parse the JSON to the Textview showing all the data I used the following.
JSONObject jo = new JSONObject(data);
JSONArray locations = jo.getJSONArray("locations");
for (int i = 0; i < locations.length(); ++i) {
JSONObject loc = locations.getJSONObject(0);
JSONObject geo = loc.getJSONObject("geo");
JSONObject country = geo.getJSONObject("country");
JSONObject astronomy = loc.getJSONObject("astronomy");
JSONObject objects = astronomy.getJSONArray("objects").getJSONObject(0);
JSONObject day = objects.getJSONArray("days").getJSONObject(0);
StringBuilder result = new StringBuilder();
String singleParsed = "Moon: "+ astronomy.getString("moonphase");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
MainActivity.fetcheddata.setText(this.data);
}
NOTE: A String is created in the For Loop, Called "Single Parsed", This is what I want to put on the screen, however - once I call that variable, nothing shows on the screen. It only shows when using:
MainActivity.fetcheddata.setText(this.data);
But Not with the following, I do actually receive an error saying "Cannot Resolve Symbol, singleParsed as well.
MainActivity.fetcheddata.setText(this.singleParsed);
After some research and previous questions on Stack, I believe GSON is the way to go to do what I wish, however I have no idea where to start, or how to do the task using GSON.
All help is appreciated.
JSON Information from URL through GSON
Simple answer - Look at using Retrofit, and find a tutorial on it, as well as Gson
However
You don't need Gson to fix your problem, and I suggest fixing the problem at hand rather than going down an unnecessary path.
First, singleParsed is a local variable within a loop. Therefore, this.singleParsed doesn't exist. Or if it does, you never set it.
Secondly, let's assume you only have one location, so you don't need a loop. Similar to how you accessed the other JSON arrays, just get the first array item.
Finally, you'll need to understand how AsyncTask works, but my general recommended solution is at How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
But, for this purpose, here is a simple example with AsyncTask<String, Void, String>
// protected String doInBackground(String... url) { // I assume you have this ??
// String data = parseJsonFrom(url[0]);
String singleParsed = "(none)";
try {
JSONObject jo = new JSONObject(data);
JSONObject firstLocationAstronomy = jo
.getJSONArray("locations").getJSONObject(0)
.getJSONObject("astronomy");
JSONObject firstDay = firstLocationAstronomy
.getJSONArray("objects").getJSONObject(0)
.getJSONArray("days").getJSONObject(0);
singleParsed = firstDay.getString("moonphase");
} catch (Exception e) { // TODO: catch a JSONParseException
}
return singleParsed; // This is returned to onPostExecute, don't store a variable elsewhere
}
Then in the MainActivity, wherever you make this task, and set the text
new MoonPhaseTask() {
#Override
protected void onPostExecute(String moonPhase) {
MainActivity.this.textView.setText("Phase: " + moonPhase);
}
}.execute("some url");
What I want is to just show the Location, so in the above example, Oslo, in Norway in one Textview, then in another show the Current Moon Phase for that location
You can change the AsyncTask to return you the entire JSONObject to the onPostExecute, and parse the JSON there if you really wanted. Just the networking pieces need to be off the UI thread... parsing is not computationally expensive.

Access variable set by Volley's onResponse

I have two global variables currentTemp and currentHum that are set when Volley's onResponse method is called. My code looks like this:
// Request a string response from the provided URL.
private JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, WEATHER_URL, null, new Response.Listener<JSONObject>() {
public void onResponse(JSONObject response) {
try {
JSONObject main = new JSONObject(response.getString("main"));
currentTemp = main.getString("temp");
currentHum = main.getString("humidity");
Log.i("RES", "Temp: " + main.getString("temp") + " Hum: " + main.getString("humidity"));
} catch (JSONException e) {
e.printStackTrace();
}
}}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(appContext, "An error occurred while retrieving weather info", Toast.LENGTH_LONG).show();
Log.e("ERR", "ERROR RET WEATHER DATA");
}
});
// Call the OpenWeatherMap API and get data such as temperature and humidity
private String getWeatherInfo(String key) {
// Add the request to the RequestQueue to invoke the API
queue.add(jsonObjectRequest);
// Access variables set by Volley's onResponse here.
switch (key) {
case "temp":
return String.valueOf(Float.parseFloat(currentTemp) - 273.15);
case "hum":
return currentHum;
default:
return " ";
}
}
I want to be able to access the values of the global variables set by the onResponse method in the getWeatherInfo method that invoked it. Then pass the values to a switch statement for processing. How do I do it without getting empty values for currentTemp and currentHum?
This work is meant to be done with use of an interface. If you don't know about an interface callbacks then please go through this answer. Which will help you understand interface, and plus point that this will guide you for handling volley response.
Also this is not recommended to take global variables to set any response, rather you can pass your whole JsonObject from volley class. and parse it where you make a call. You can use Gson for parsing the response to your Model or ArrayList.

How to send the JSONArray to Receiver app from the sender app for chromecast in android

Unable to send the JSONArray values to the Receiver app from the sender app using MediaInfo.Builder class. I have used the setCustomData(JSONObject obj) where we can send only JSONObject as possible but i need to send JSONArray to receiver app using setCustomData() method if possible, Otherwise if have some other default method or any idea to send the JSONArray values to receiver app for chromecast please tell me.
Thanks in Advance.
I have tried with JSONObject :
MediaMetadata mediaMetadata = new MediaMetadata(
MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
mediaMetadata.putString(MediaMetadata.KEY_ALBUM_ARTIST, ""
+ singers.getText().toString());
mediaMetadata.putString(mediaMetadata.KEY_ALBUM_TITLE, ""
+ songTitle.getText().toString());
MediaInfo mediaInfo = new MediaInfo.Builder(songUrl)
.setContentType("audio/mp3")
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
// here set the customData {"music":"Illayaraja","album_id":"T0000266","duration":"04:57",....}
.setCustomData(customJsonObj)
.setMetadata(mediaMetadata).build();
mRemoteMediaPlayer
.load(mApiClient, mediaInfo, true)
.setResultCallback(
new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(MediaChannelResult result) {
if (result.getStatus().isSuccess()) {
Log.d(Tag, "Media loaded Successfully"
+ result.getStatus());
} else {
Log.d(Tag,
"Media loaded Not Successfully"
+ result.getStatus());
}
}
});
but i need to pass the JSONArray values to receiver app like this
"customData": [
{
"songid": 236854,
"songtitle": "Kadal Anukkal",
"cdimg": "http://cdn.raaga.com/r_img/250/t/t0002491.jpg",
"lyricist": "Vairamuthu",
"lang": "T",
"singers": "Vijay Prakash, Shreya Ghoshal",
"album": "Enthiran",
"album_id": "T0002491",
"music": "AR. Rahman",
"duration": "05:46"
},
]
Here is one idea:
use a JSonObject to wrap your JSonArray.
Here is an example:
try {
JSONObject myJsonObject;
myJsonObject.put("field1", "value1");
JSONArray myJSonArray = new JSONArray();
myJSonArray.put(myJsonObject);
JSONObject jsonArrayWrapper = new JSONObject();
jsonArrayWrapper.put("MyArray", myJSonArray);
} catch (JSONException e) {
Log.d("Tag", e.getMessage());
}

JSON response is changed as no of item changes

my JSON Response from server is changes as user input , suppose on server when user added one item then i got response as JSONObject but when items is more than 1 Then response is in JSONArray form.
Now how to handle these response so that my application is not killed , need to use checkpoint ?
in case of two item ..
"items":{
"item":[
{
"item_id":"49623",
"type":"Products",
"name":"desktop app",
"description":"",
"unit_cost":"162.45",
"quantity":"1.00",
"discount":"0.00",
"discount_type":"Percent",
"tax1_percent":"0.00",
"tax2_percent":"0.00"
},
{
"item_id":"52851",
"type":"Products",
"name":"",
"description":"",
"unit_cost":"5,290.50",
"quantity":"1.00",
"discount":"0.00",
"discount_type":"Percent",
"tax1_name":{
},
"tax1_percent":"0.00",
"tax1_type":{
},
"tax2_name":{
},
"tax2_percent":"0.00",
"tax2_type":{
}
}
]
}
In case of single item
"items":{
"item":{
"item_id":"49623",
"type":"Products",
"name":"desktop app",
"description":"this is the software for your desktop system sequerty",
"unit_cost":"162.45",
"quantity":"1.00",
"discount":"0.00",
"discount_type":"Percent",
"tax1_name":{
},
"tax1_percent":"0.00",
"tax1_type":{
},
"tax2_name":{
},
"tax2_percent":"0.00",
"tax2_type":{
}
}
}
}
I think you could use optJSONArray("") or optJSONObject(""), which doesn't throw any exception, but returns null if the object isn't in the right type.
JSONObject items = myJSON.getJSONObject("items");
Object item;
if (items.optJSONArray("item") != null){
//The result isn't null so it is a JSONArray
item = items.optJSONArray("item");
}
else
{
//The result is null so it isn't a JSONArray
item = items.optJSONObject("item");
}
Then, you'll just have to use your Object as you wish, using "instanceof":
if (item instanceof JSONObject){
// The object is a JSONObject
[... Your code ...]
}
else
{
// The object is a JSONArray
[... Your code ...]
}

Categories

Resources