lundi 2 mars 2015

org.json.JSONException: No value for id - IMPOSSIBLE TO SOLVE



http://ift.tt/1wIxj9s


Hi,


This is a tutorial about building a group chat app using socket programming. This app allows us to chat between multiple devices like android mobiles and web.


I want to send more than one "String" at a time to the server. I'm having trouble figuring that out.


The link to the tutorial where I downloaded the code is pasted above. I've already made the dynamic web page and I have it hosted on eapps.com At the very bottom of the this email is the edited code for the app. If you click the link above, you can see how I changed it.


The way it works is..



A web socket is created using WebSocketClient class and it has all the callback methods like onConnect, onMessage and onDisconnect. In onMessage method parseMessage() is called to parse the JSON received from the socket server. In parseMessage() method, the purpose of JSON is identified by reading the flag value. When a new message is received, the message is added to list view data source and adapter.notifyDataSetChanged() is called to update the chat list. sendMessageToServer() method is used to send the message from android device to socket server. playBeep() method is called to play device’s default notification sound whenever a new message is received.​



When you click the btnSend. it uses this method from the UtilsXd class. I've changed it a little in an attempt to pass an extra value.



public String getSendMessageJSONXD(String message, String whichPicIndex) {
String json = null;

try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_MESSAGE);
jObj.put("sessionId", getSessionId());
jObj.put("message", message);
jObj.put("id", id);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}

return json;
}


First of all, what I still don't understand is, where did the values for



String sessionId = jObj.getString("sessionId");


and



String onlineCount = jObj.getString("onlineCount");​


from this method



private void parseMessage(final String msg, String idINDEX) {


come from.


They were't added in the JSON object created in the UtilsXD class so how are they created?


That's not the problem I'm having. This is.


superString is the value I want to pass to dictate which picture to show.



superString = (sharedPrefs.getString("prefSyncAvatar", "1"));​


You can change your picture in from the settings.


When a message is received, a switch/case statement changes the picture of/ for the message received according to the value passed by superString.


I should be able to sit there and just receive messages, and whatever number the user passes, the profilePicture should be set according to that number.


Here's where the problem begins.


This constructer builds a message based of the message that's just been parsed.



// Message m = new Message(fromName, message, isSelf);
Message m = new Message(fromName, message, isSelf, id, name,
image, status, profilePic, timeStamp, url);


In this method.



private void parseMessage(final String msg, String idINDEX) {


I can pass an value to the string "id" excluding the JSON I need it to.



String id = idINDEX;​


this works,



String id = "0";


this works,



String id = utils.getPictureId();


this works,



String id = jObj.getString("id");


This doesn't work.


This is the error I'm getting.


org.json.JSONException: No value for id (this is the issue)


I've added the key/value pair



jObj.put("id", id);


in



public String getSendMessageJSONXD(String message, String whichPicIndex) {​


but it's not coming though to the message.


Here's where I think the problem is.


The method onMessage, isn't can't take an extra parameter because it's from a library project. And I can't find that method to make a new constructor.



@Override
public void onMessage(String message) {
Log.d(TAG, String.format("Got string message! %s", message));

parseMessage(message, superString);


}

@Override
public void onMessage(byte[] data) {
Log.d(TAG, String.format("Got binary message! %s",
bytesToHex(data)));
String hello = "99";

parseMessage(bytesToHex(data), superString);


}


/////// Here's the final code below ////////



// JSON flags to identify the kind of JSON response
private static final String TAG_SELF = "self", TAG_NEW = "new",
TAG_MESSAGE = "message", TAG_ID = "id", TAG_EXIT = "exit";



@SuppressWarnings("deprecation")
@SuppressLint({ "NewApi", "CutPasteId" })
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_chat);

showUserSettings();
getActionBar().setTitle("City Chat - Beta 1.3");

superString = (sharedPrefs.getString("prefSyncAvatar", "1"));

listView = (ListView) findViewById(R.id.list_view_messages);

feedItems = new ArrayList<FeedItem>();

// We first check for cached request

vollewStuff();
//
//
// THis is where this fun begins

btnSend = (Button) findViewById(R.id.btnSend);
inputMsg = (EditText) findViewById(R.id.inputMsg);
listViewMessages = (ListView) findViewById(R.id.list_view_messages);

utils = new UtilsXD(getApplicationContext());

// Getting the person name from previous screen
Intent i = getIntent();
name = i.getStringExtra("name");



Integer.parseInt((sharedPrefs.getString("prefSyncAvatar", "1")));

btnSend.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// Sending message to web socket server
sendMessageToServer(utils.getSendMessageJSONXD(inputMsg
.getText().toString(), superString), superString);

utils.storePictureId((sharedPrefs.getString("prefSyncAvatar",

"1")));

// Clearing the input filed once message was sent
inputMsg.setText("");
}
});

listMessages = new ArrayList<Message>();

adapter = new MessagesListAdapter(this, listMessages, feedItems);
listViewMessages.setAdapter(adapter);

/**
* Creating web socket client. This will have callback methods
* */
client = new WebSocketClient(URI.create(WsConfig.URL_WEBSOCKET
+ URLEncoder.encode(name)), new WebSocketClient.Listener() {
@Override
public void onConnect() {

}

/**
* On receiving the message from web socket server
* */
@Override
public void onMessage(String message) {
Log.d(TAG, String.format("Got string message! %s", message));

parseMessage(message, superString);

// parseMessage(message,
// (sharedPrefs.getString("prefSyncAvatar", "1")));

}

@Override
public void onMessage(byte[] data) {
Log.d(TAG, String.format("Got binary message! %s",
bytesToHex(data)));
String hello = "99";

parseMessage(bytesToHex(data), superString);

// Message will be in JSON format
// parseMessage(bytesToHex(data),
// (sharedPrefs.getString("prefSyncAvatar", "1")));
}

/**
* Called when the connection is terminated
* */
@Override
public void onDisconnect(int code, String reason) {

String message = String.format(Locale.US,
"Disconnected! Code: %d Reason: %s", code, reason);

showToast(message);
//
// clear the session id from shared preferences
utils.storeSessionId(null);
}

@Override
public void onError(Exception error) {
Log.e(TAG, "Error! : " + error);

// showToast("Error! : " + error);

showToast("Are you sure you want to leave?");
}

}, null);

client.connect();
}


/**
* Method to send message to web socket server
* */

private void sendMessageToServer(String message, String id) {
if (client != null && client.isConnected()) {
client.send(message);
client.send(id);
}
}

/**
* Parsing the JSON message received from server The intent of message will
* be identified by JSON node 'flag'. flag = self, message belongs to the
* person. flag = new, a new person joined the conversation. flag = message,
* a new message received from server. flag = exit, somebody left the
* conversation.
* */

private void parseMessage(final String msg, String idINDEX) {

try {
jObj = new JSONObject(msg);

// JSON node 'flag'
String flag = jObj.getString("flag");

String id = idINDEX;

// if flag is 'self', this JSON contains session id
if (flag.equalsIgnoreCase(TAG_SELF)) {

String sessionId = jObj.getString("sessionId");

// Save the session id in shared preferences
utils.storeSessionId(sessionId);

Log.e(TAG, "Your session id: " + utils.getSessionId());

} else if (flag.equalsIgnoreCase(TAG_NEW)) {
// If the flag is 'new', new person joined the room
String name = jObj.getString("name");
String message = jObj.getString("message");

// number of people online
String onlineCount = jObj.getString("onlineCount");

showToast(name + message + ". Currently " + onlineCount
+ " people online!");

} else if (flag.equalsIgnoreCase(TAG_MESSAGE)) {
// if the flag is 'message', new message received
String fromName = name;
String message = jObj.getString("message");
String sessionId = jObj.getString("sessionId");

// switch (Integer.parseInt((sharedPrefs.getString(
// "prefSyncAvatar", "1"))))

boolean isSelf = true;

switch (Integer.parseInt(utils.getPictureId())) {

case 1:

profilePic = "http://ift.tt/1B2l2QA";

break;
case 2:

profilePic = "http://ift.tt/1APWf3z";

break;
case 3:

profilePic = "http://ift.tt/1B2l5vK";

break;
case 4:

profilePic = "http://ift.tt/1APWf3B";

break;
case 5:

profilePic = "http://ift.tt/1B2l5vO";

break;

case 10:

profilePic = "http://ift.tt/1B2l5vO";

break;

}

// Checking if the message was sent by you
if (!sessionId.equals(utils.getSessionId())) {
fromName = jObj.getString("name");
// profilePic = jObj.getString("profilePic");

//
//
//
//
jObj.getString("message");
isSelf = false;

profilePic = "http://ift.tt/1APWf3B";
}

// profilePic =
// "http://ift.tt/1B2l2QA";

Integer.parseInt(utils.getPictureId());

String name = "clxxxii";
String image = "http://ift.tt/1tZa5sr";
String status = "status";
String timeStamp = "1403375851930";
String url = "url";

// Message m = new Message(fromName, message, isSelf);
Message m = new Message(fromName, message, isSelf, id, name,
image, status, profilePic, timeStamp, url);

// Appending the message to chat list
appendMessage(m);

} else if (flag.equalsIgnoreCase(TAG_EXIT)) {
// If the flag is 'exit', somebody left the conversation
String name = jObj.getString("name");
String message = jObj.getString("message");

showToast(name + message);
}

} catch (JSONException e) {
e.printStackTrace();
}

}


///////// I've updated the socket server from the first project. /////// I've added the JSON value "id" successfully /// But I how do I change the value without having to type in "5" please see below..


// This is the JSONutilty method I changed. // public String getSendAllMessageJson(String sessionId, String fromName, String message, String photoId) { String json = null;



try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_MESSAGE);
jObj.put("sessionId", sessionId);
jObj.put("name", fromName);
jObj.put("message", message);
jObj.put("id", photoId);

json = jObj.toString();

} catch (JSONException e) {
e.printStackTrace();
}

return json;
}
}


This is the method that is being used by SocketServer. I can successfully send a message from this activity, to the utility method to send over the network.



// Normal chat conversation message
json = jsonUtils //
.getSendAllMessageJson(sessionId, name, message, "5");


How can I retrieve a value sent over the network to place in spot where I have "5" instead of hard coding it?


Thanks!!!




1 commentaire: