Android GCM: Can we get data as a complete JSON structure? - android

I am sending a message (POST) to Google GCM server https://android.googleapis.com/gcm/send for sending a push notification to a registered android device. The POST body looks something like this:
{
"registration_ids" : [android_registration_id],
"data" : {
"message" : "Hello World!",
"update" : "You've got a new update",
"info" : "You've got new information updates too!"
}
}
Suppose that I don't know what all key-value pairs are being sent to me (gcm registered android app) in the "data" field and I want to enumerate and print them, can I extract the fields in "data" as a JSON structure?
For e.g. In the above example, I need the following as a JSON object:
{
"message" : "Hello World!",
"update" : "You've got a new update",
"info" : "You've got new information updates too!"
}

Bundle data = intent.getExtras();
Iterator<String> it = data.keySet().iterator();
String key;
String value;
while(it.hasNext()) {
key = it.next();
value = data.getString(key);
}
Try this. Using key and value you can construct initial json.

JSONArray array = new JSONArray(jsonBodyOfTheResponse);
for (int i = 0; i < array.length(); i++) {
JSONObject row = array.getJSONObject(i);
.
.
. }

Related

Parse Nested JSON Array from Notification Data using Gson in Android

I am getting data in JSON format from FCM notification. It has different format based on notification types as below:
Format 1: accept_request:
{
"alert": "Accept Request By driver",
"title": "Accept Request By driver",
"booking_id": "247",
"notification_type": "accept_request"
}
Format 2: end_request:
{
"alert": "End trip By driver",
"title": "End trip By driver",
"booking_id": "247",
"notification_type": "end_request",
"servicesList": [
{
"service_id": "1",
"service_name": "Services1",
"status": "true",
"sub_category": [
{
"sub_cat_id": "1",
"sub_cat_name": "Doctors on call",
"service_cost": "15.00",
"service_cat_id": "1",
"cost": 0
}
],
"is_multiple_choose": "0",
"total_cost": 15
}
}
I have create CommonNotificationBean.java as POJO class. I have successfully parsed data for accept_request.
Its working because all key has String values and remoteMessage.getData() also returning Map<String, String> type values.
Code:
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("notification_type"));
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(object.toString()));
reader.setLenient(true);
CommonNotificationBean bean = gson.fromJson(reader, CommonNotificationBean.class);
sendNotification(bean);
}
PROBLEM:
Now I am stuck with problem while parsing end_request data because it has Nested JSON Array.
Read it carefully:
What can I do for dynamic data instead of Map<String, String> because it will not convert data into Map<String, String> type as it has some List type values.
Anyone can help?
And finally I got solution by adding some drops of concepts. :)
I got many problems to converting in JSON with proper format like:
Unterminated object at character
MalformedJsonException
and Finally following code get worked for me.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "remoteMessage.getData() : " + remoteMessage.getData());
// Map<String, String> stringStringMap = remoteMessage.getData();
JSONObject object = new JSONObject(remoteMessage.getData());
Log.d(TAG, "new JSONObject(remoteMessage.getData()) : " + object.toString());
String finalJSON = object.toString().replaceAll("\\\\", "").replace("\"[", "[").replace("]\"", "]");
Log.d(TAG, "Replace all back slash and invalid double quotes : " + finalJSON);
CommonNotificationBean bean = new Gson().fromJson(finalJSON, CommonNotificationBean.class);
sendNotification(bean);
}
Logcat:
remoteMessage.getData(): Getting data without double quotes.
remoteMessage.getData() : {content-available=1, notification_type=end_request, booking_id=247, priority=high, base_price=35, totalMinutePrice=1.5, alert=End trip By driver, sound=default, title=End trip By driver, total_amount=397, address_from=A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India, service_cost=360, servicesList=[{"total_cost":15,"sub_category":[{"cost":0,"sub_cat_name":"Doctors on call","sub_cat_id":"1","service_cost":"15.00","service_cat_id":"1"}],"service_name":"Services1","service_id":"1","is_multiple_choose":"0","status":"true"},{"total_cost":95,"sub_category":[{"cost":0,"sub_cat_name":"Hand","sub_cat_id":"3","service_cost":"20.00","service_cat_id":"2"},{"cost":0,"sub_cat_name":"Body","sub_cat_id":"4","service_cost":"75.00","service_cat_id":"2"}],"service_name":"Dressing","service_id":"2","is_multiple_choose":"1","status":"true"},{"total_cost":0,"sub_category":[{"cost":0,"sub_cat_name":"No","sub_cat_id":"7","service_cost":"0.00","service_cat_id":"3"}],"service_name":"Do you need oxygen?","service_id":"3","is_multiple_choose":"0","status":"true"},{"total_cost":30,"sub_category":[{"cost":0,"sub_cat_name":"Level 3","sub_cat_id":"10","service_cost":"30.00","service_cat_id":"4"}],"service_name":"Lift\/Stairs Accessibility","service_id":"4","is_multiple_choose":"0","status":"true"},{"total_cost":220,"sub_category":[{"cost":0,"sub_cat_name":"Ventilator","sub_cat_id":"12","service_cost":"100.00","service_cat_id":"5"},{"cost":0,"sub_cat_name":"Intracenous (IV) drip","sub_cat_id":"13","service_cost":"120.00","service_cat_id":"5"}],"service_name":"Other Medical","service_id":"5","is_multiple_choose":"1","status":"true"},{}], tripdatetime=2019-03-27 10:57:51, address_to=19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India, notification_date_time=28-03-2019 17:24:09}
new JSONObject(remoteMessage.getData()) : Converted to JSONObject but getting unwanted back slash and double quotes
new JSONObject(remoteMessage.getData()) : {"content-available":"1","notification_type":"end_request","booking_id":"247","priority":"high","base_price":"35","totalMinutePrice":"1.5","alert":"End trip By driver","sound":"default","title":"End trip By driver","total_amount":"397","address_from":"A\/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India","service_cost":"360","servicesList":"[{\"total_cost\":15,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Doctors on call\",\"sub_cat_id\":\"1\",\"service_cost\":\"15.00\",\"service_cat_id\":\"1\"}],\"service_name\":\"Services1\",\"service_id\":\"1\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":95,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Hand\",\"sub_cat_id\":\"3\",\"service_cost\":\"20.00\",\"service_cat_id\":\"2\"},{\"cost\":0,\"sub_cat_name\":\"Body\",\"sub_cat_id\":\"4\",\"service_cost\":\"75.00\",\"service_cat_id\":\"2\"}],\"service_name\":\"Dressing\",\"service_id\":\"2\",\"is_multiple_choose\":\"1\",\"status\":\"true\"},{\"total_cost\":0,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"No\",\"sub_cat_id\":\"7\",\"service_cost\":\"0.00\",\"service_cat_id\":\"3\"}],\"service_name\":\"Do you need oxygen?\",\"service_id\":\"3\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":30,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Level 3\",\"sub_cat_id\":\"10\",\"service_cost\":\"30.00\",\"service_cat_id\":\"4\"}],\"service_name\":\"Lift\\\/Stairs Accessibility\",\"service_id\":\"4\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":220,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Ventilator\",\"sub_cat_id\":\"12\",\"service_cost\":\"100.00\",\"service_cat_id\":\"5\"},{\"cost\":0,\"sub_cat_name\":\"Intracenous (IV) drip\",\"sub_cat_id\":\"13\",\"service_cost\":\"120.00\",\"service_cat_id\":\"5\"}],\"service_name\":\"Other Medical\",\"service_id\":\"5\",\"is_multiple_choose\":\"1\",\"status\":\"true\"},{}]","tripdatetime":"2019-03-27 10:57:51","address_to":"19\/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India","notification_date_time":"28-03-2019 17:24:09"}
Final JSON :
Replace all back slash and invalid double quotes : {"content-available":"1","notification_type":"end_request","booking_id":"247","priority":"high","base_price":"35","totalMinutePrice":"1.5","alert":"End trip By driver","sound":"default","title":"End trip By driver","total_amount":"397","address_from":"A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India","service_cost":"360","servicesList":[{"total_cost":15,"sub_category":[{"cost":0,"sub_cat_name":"Doctors on call","sub_cat_id":"1","service_cost":"15.00","service_cat_id":"1"}],"service_name":"Services1","service_id":"1","is_multiple_choose":"0","status":"true"},{"total_cost":95,"sub_category":[{"cost":0,"sub_cat_name":"Hand","sub_cat_id":"3","service_cost":"20.00","service_cat_id":"2"},{"cost":0,"sub_cat_name":"Body","sub_cat_id":"4","service_cost":"75.00","service_cat_id":"2"}],"service_name":"Dressing","service_id":"2","is_multiple_choose":"1","status":"true"},{"total_cost":0,"sub_category":[{"cost":0,"sub_cat_name":"No","sub_cat_id":"7","service_cost":"0.00","service_cat_id":"3"}],"service_name":"Do you need oxygen?","service_id":"3","is_multiple_choose":"0","status":"true"},{"total_cost":30,"sub_category":[{"cost":0,"sub_cat_name":"Level 3","sub_cat_id":"10","service_cost":"30.00","service_cat_id":"4"}],"service_name":"Lift/Stairs Accessibility","service_id":"4","is_multiple_choose":"0","status":"true"},{"total_cost":220,"sub_category":[{"cost":0,"sub_cat_name":"Ventilator","sub_cat_id":"12","service_cost":"100.00","service_cat_id":"5"},{"cost":0,"sub_cat_name":"Intracenous (IV) drip","sub_cat_id":"13","service_cost":"120.00","service_cat_id":"5"}],"service_name":"Other Medical","service_id":"5","is_multiple_choose":"1","status":"true"},{}],"tripdatetime":"2019-03-27 10:57:51","address_to":"19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India","notification_date_time":"28-03-2019 17:24:09"}
Full code : MyFirebaseMessagingService.java
Hope it will be help to others.
It is simple, you should just have an abstract Notification object with the attributes alert, title and notification_type. And then, have specific implementations based on your possible types, so far:
AcceptRequestNotification extends Notification with just an int booking_id (this is the one you already have, the one you called CommonNotificationBean)
EndRequestNotification extends Notification which contains for example, an ArrayList called servicesList, this ArrayList should be of type Service and then, service would have the attributes: service_id, service_name, status, sub_category which is again another ArrayList of a custom type.
And then you just change your code to be:
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("notification_type"));
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(object.toString()));
reader.setLenient(true);
Class typeOf;
switch(remoteMessage.getData().get("notification_type")) {
case "accept_request":
typeOf = AcceptRequestNotification.class;
break;
case "end_request":
typeOf = EndRequestNotification.class;
break;
}
//you can cast this object later on (to the corresponding custom subclass of Notification), based on the notif.getNotificationType() value.
Notification notif = gson.fromJson(reader, typeOf);
sendNotification(notif);
}

Android studio: How to receive Json Volley with different objects

According to this json file I want to receive data1 , xyz, abc object and their sub objects and show it in recyclerview.But I am receiving only data1 and their key-value pairs(index1 and name). I am using library Volley.
Can someone help me how to recive xyz and abc ?
{
"Data1":{
"index1":"4",
"name":"dan"
},
"xyz":{
"index1":"2",
"name":"jimi"
}
"abc":{
"index1":"5",
"name":"jordan"
}
}
JSONObject jsonObject = response.getJSONObject("Data1");
getset1.seti(jsonObject.getString("index1"));
getset1.setn(jsonObject.getString("name"));
Try this
JSONObject jsonobject=new JSONobject("");
for (int i=0;i<jsonobject.length();i++){
JSONObject jsonObject1=jsonobject.getJSONObject(i);
);
You have to use loop.As this is not an array so u have to fetch the all keys using iterator and then loop among them try this
Iterator<String> keys = json.keys();
while (keys.hasNext())
{
// Get the key
String key = keys.next();
// Get the value
JSONObject value = json.getJSONObject(key);
// parse inner string from value
}

getting null value while parsing json data in android

i am trying to parse json data in android app i am able to get title of the book and author but i am not able to parse publisher i am getting null value at publisher
"kind":"books#volumes",
"totalItems":997,
"items":[
{
"kind":"books#volume",
"id":"g3hAdK1IBkYC",
"etag":"o+CdTUx3mkQ",
"selfLink":"https://www.googleapis.com/books/v1/volumes/g3hAdK1IBkYC",
"volumeInfo":{
"title":"Professional Android 4 Application Development",
"authors":[
"Reto Meier"
],
"publisher":"John Wiley & Sons",
"publishedDate":"2012-04-05",
}
here is the java code written for Json
JSONObject root = new JSONObject(jsonResponse);
JSONArray itemsArray = root.optJSONArray("items");
for (int i=0;i<itemsArray.length();i++){
JSONObject singleItem = itemsArray.getJSONObject(i);
JSONObject volumeInfo = singleItem.getJSONObject("volumeInfo");
String title = volumeInfo.getString("title");
Log.i("title_book",title);
String author = volumeInfo.getString("authors");
Log.i("author_book",author);
String publisher = singleItem.getString("publisher");
Log.i("publisher_book",publisher);
It seems that the publisher is contained by volumeInfo. Try:
String publisher = volumeInfo.getString("publisher");

Parse.com Receiving push notifications even if not subscribed to channel

i'm receiving push notifications even from channels i'm not subscribed to.
My app gets the user interest from a remote JSON and subscribe him to the channels in Parse.
I'll try to copy all the related code.
MyApplication.java
Parse.enableLocalDatastore(this);
Parse.initialize(this, ParseAppID, ParseClientKey);
ParseInstallation installation=ParseInstallation.getCurrentInstallation();
installation.put("UniqueId", android_id);
installation.saveInBackground();
MainActivity.java (inside an AsyncTask onPostExecute)
JSONObject jObject = new JSONObject(result);
int error = jObject.getInt("Error");
ArrayList<String> channels = new ArrayList<String>();
if(error==0){
JSONArray intereses = jObject.getJSONArray("Interests");
Log.d("ChannelsTrack", "Error: 0");
for(int j=0; j < intereses.length(); j++) {
int interes = intereses.getInt(j);
String channel_name="sdc_channel_" + interes;
channels.add(channel_name);
Log.d("ChannelsTrack", channel_name);
ParsePush.subscribeInBackground( channel_name );
}
List<String> subscribedChannels = ParseInstallation.getCurrentInstallation().getList("channels");
for(int j=0; j < subscribedChannels.size(); j++) {
if(!channels.contains(subscribedChannels.get(j))){
ParsePush.unsubscribeInBackground( subscribedChannels.get(j) );
}
}
}else{
Log.d("ChannelsTrack", "Error: " + error);
}
This is aparently working. I can see my Parse user subscribed to the specified channels y the console
I can't post images but, in Parse Core table it's a single row with ["sdc_channel_6","sdc_channel_5","sdc_channel_2","sdc_channel_3","sdc_channel_4"] in the "channels" column and it changes when i update the user interests so i think everything it's working at this point.
I'm using the REST API to send push notifications using this JSON
{
"data": {
"action": "my.application.UPDATE_STATUS",
"t": "Text",
"d": "Text 2",
"f": "",
"u": "http://example.com"
},
"where": {
"channels": {
"$in": ["sdc_channel_99","sdc_channel_88"]
},
"deviceType": "android"
}
}
And here is the problem. I receive the push notification sent to "sdc_channel_99" and "sdc_channel_88" channels but i'm not subscribed to them (and i've never been subscribed to them).
Obviously i'm missing something, any help? Thanks.
I think the problem is in your compound query :
"where": {
"channels": {
"$in": ["sdc_channel_99","sdc_channel_88"]
},
"$in" means "Contained In" so if the user is subscribed to channel "sdc_channel_9" and channel "sdc_channel_8", the user will be selected.
may be you should try this query :
"where" : {"$or":[{"channels":"sdc_channel_99"},{"channels":"sdc_channel_88"}]}

Get json array length and looping

So I have a json response from web service like this
{
error: false
types: [2]
-0: {
card_type_id: 5
category: "Food & Beverages"
}
-1: {
card_type_id: 8
category: "Entertaiment"
}
}
what I want to do is to get the number inside json array "types" and use it to looping to set the value of arraylist that will be use in listview, but my code seems and cannot get the json array length, this is my code
JSONObject obj = new JSONObject(response);
if(!obj.getBoolean("error")){
JSONArray types = obj.getJSONArray("types");
for(int i=0; i<types.length();i++)
{
JSONObject a = types.getJSONObject(i);
int ct_id = a.getInt("card_type_id");
String category = a.getString("category");
CardType ct = new CardType();
ct.setTypeId(_ct_id);
ct.setTypeCategory(_category);
categoryArray.add(ct);
}
}
Can anyone help me? Thanks before
This is what your JSON response probably should look like (note also that keys and string values should be sorrounded by double-quotes):
{
"error": false,
"types": [
{
"card_type_id": 5,
"category": "Food & Beverages"
},
{
"card_type_id": 8,
"category": "Entertaiment"
}
]
}
The JSONArray "types" in this example has a length (types.length()) of 2. Now you can implement your for-loop and should get the expected results.
actually it's just my fault to see the json from advanced rest client, i use the json menu and the app automatically correct the json and become invalid, after i change to raw menu i can see the actual json and correct the code

Categories

Resources