Search code examples
javaandroidjsonfacebookjsonexception

Please help a newbie having trouble with the following: String cannot be converted to JSON object


I am using the Facebook SDK with Eclipse to send requests to friends, I want to include additional information for the application in the "data" field. I keep getting the error java.lang.String cannot be converted to JSON object, no matter what I try. I've tried retrieving the data in a JSONArray and retrieving the specific values in JSONObjects, to no avail. I'd really appreciate it if you could tell me what I'm doing wrong.

I've included the relevant code below. The badge of awesomeness and social karma values are placeholders, copied from the facebook tutorial here: https://developers.facebook.com/docs/android/send-requests

the request-sending code, straight from the example (apart from the message field):

    private void sendRequestDialog() {
    Bundle params = new Bundle();
    params.putString("title", "Send a Request");
    params.putString("message",
            application.getUserId()+" has invited you to an event!"); 
    String idHolder = ids.get(0);
    for (int i = 1; i < ids.size(); i++) 
    {
        idHolder = idHolder+"," + ids.get(i); // a for-loop to get all selected
                                            // user ids in the recipients
                                            // list (starting at 1 to
                                            // prevent comma placement
                                            // issues)
    }
    params.putString("to", idHolder); // comma seperated list of facebook
                                        // IDs to preset the recipients.
    params.putString("data",
            "{\"badge_of_awesomeness\":\"1\"," +
            "\"social_karma\":\"5\"}");

    WebDialog requestsDialog = ( // initializes a web dialog, sends the
                                    // requests parameters to the stored
                                    // IDs, displays errors in sending
    new WebDialog.RequestsDialogBuilder(this, Session.getActiveSession(),
            params)).setOnCompleteListener(new OnCompleteListener() {

        @Override
        public void onComplete(Bundle values, FacebookException error) {
            if (error != null) {
                if (error instanceof FacebookOperationCanceledException) {
                    Toast.makeText(getApplicationContext(),
                            "Request cancelled", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Network Error", Toast.LENGTH_SHORT).show();
                }
            } else {
                final String requestId = values.getString("request");
                if (requestId != null) {
                    Toast.makeText(getApplicationContext(), "Request sent",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Request cancelled", Toast.LENGTH_SHORT).show();
                }
            }
        }

    }).build();
    requestsDialog.show();
}

Followed by the code on the receiving end (the Toast(badge_of_awesomeness) is there for testing purposes):

    private void getRequestData(final String inRequestId) {
        // Create a new request for an HTTP GET with the
        // request ID as the Graph path.
        Request request = new Request(Session.getActiveSession(), 
                inRequestId, null, HttpMethod.GET, new Request.Callback() {

                    @SuppressLint("NewApi") @Override
                    public void onCompleted(Response response) {
                        // Process the returned response
                        GraphObject graphObject = response.getGraphObject();
                        FacebookRequestError error = response.getError();
                        // Default message
                        String message = "Incoming request";
                        if (graphObject != null) {
                            // Check if there is extra data
                            if (graphObject.getProperty("data") != null) {
                                try {
                                    // Get the data, parse info to get the key/value info

                                    JSONObject dataObject = 
                                            new JSONObject((String)graphObject.getProperty("data"));

       Toast.makeText(getApplicationContext(), dataObject.getString("badge_of_awesomeness"), 500).show();
                                   // new JSONObject((String)graphObject.getProperty("data"));
                                    // Get the value for the key - badge_of_awesomeness
                                    String badge = 
                                        dataObject.getString("badge_of_awesomeness");
                                    // Get the value for the key - social_karma
                                    String karma = 
                                        dataObject.getString("social_karma");
                                    // Get the sender's name
                                    JSONObject fromObject = 
                                        (JSONObject) graphObject.getProperty("from");
                                    String sender = fromObject.getString("name");
                                    String title = sender+" sent you a gift";
                                    // Create the text for the alert based on the sender
                                    // and the data
                                    message = title + "\n\n" + 
                                        "Badge: " + badge + 
                                        " Karma: " + karma;
                                } catch (JSONException e) {
                                    message = "Error getting request infoJSON";
                                    Log.e("!", "!", e);
                                }
                            } else if (error != null) {
                                message = "Error getting request info";
                            }
                        }
                        Toast.makeText(getApplicationContext(),
                                message,
                                Toast.LENGTH_LONG).show();
                    }
            });
        // Execute the request asynchronously.
        Request.executeBatchAsync(request);
    }

The JSON:

    {
      "id": "493703870648580", 
      "application": {
      "name": "Send Requests How To", 
      "id": "403223126407920"
    }, 
      "to": {
      "name": "Chris Abe Colm", 
      "id": "100003086810435"
    }, 
      "from": {
      "name": "Christine Abernathy", 
      "id": "1424840234"
    }, 
      "data": "{\"badge_of_awesomeness\":\"1\",\"social_karma\":\"5\"}", 
      "message": "Learn how to make your Android apps social", 
      "created_time": "2012-10-07T17:29:57+0000"
    }

the logcat:

    06-20 17:33:47.413: E/!(31515): !
    06-20 17:33:47.413: E/!(31515): org.json.JSONException: Value         nullandroid.widget.EditText@4164a490android.widget.EditText@414d9928 of type         java.lang.String cannot be converted to JSONObject
    06-20 17:33:47.413: E/!(31515):     at org.json.JSON.typeMismatch(JSON.java:111)
    06-20 17:33:47.413: E/!(31515):     at org.json.JSONObject.<init>(JSONObject.java:159)
    06-20 17:33:47.413: E/!(31515):     at org.json.JSONObject.<init>(JSONObject.java:172)
    06-20 17:33:47.413: E/!(31515):     at hro.informatica.gameplanner.GamePlannerMain$10.onCompleted(GamePlannerMain.java:482)
    06-20 17:33:47.413: E/!(31515):     at com.facebook.Request$4.run(Request.java:1725)
    06-20 17:33:47.413: E/!(31515):     at android.os.Handler.handleCallback(Handler.java:733)
    06-20 17:33:47.413: E/!(31515):     at android.os.Handler.dispatchMessage(Handler.java:95)
    06-20 17:33:47.413: E/!(31515):     at android.os.Looper.loop(Looper.java:212)
    06-20 17:33:47.413: E/!(31515):     at android.app.ActivityThread.main(ActivityThread.java:5151)
    06-20 17:33:47.413: E/!(31515):     at java.lang.reflect.Method.invokeNative(Native Method)
    06-20 17:33:47.413: E/!(31515):     at java.lang.reflect.Method.invoke(Method.java:515)
    06-20 17:33:47.413: E/!(31515):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
    06-20 17:33:47.413: E/!(31515):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
    06-20 17:33:47.413: E/!(31515):     at dalvik.system.NativeStart.main(Native Method)
    06-20 17:33:47.423: W/ResourceType(31515): CREATING STRING CACHE OF 44 bytes

I really don't get what I'm doing wrong here, I've spent all day (well, all afternoon) pouring over stackoverflow trying different solutions. I'm probably making an obvious mistake somewhere, but I can't find it. I really am stuck, please help me out!


Solution

  • 1.Do you know on which particular line you receive the exception?

    On your receiving-end code, I see you try to get the JSON in 2 different ways:

    JSONObject dataObject = new JSONObject((String)graphObject.getProperty("data"));
    ...
    JSONObject fromObject = (JSONObject) graphObject.getProperty("from");
    

    The first is the correct way to convert String to JSON, the second is not.

    Can you please try:

    JSONObject fromObject = new JSONObject((String)graphObject.getProperty("from"));
    

    Instead of:

    JSONObject fromObject = (JSONObject) graphObject.getProperty("from");
    


    2.Also on your sending-end code: I don't see anywhere where you would call:

    params.putString("from", "{...json stuff...}");
    

    to actually put "from" anywhere. Maybe you forgot to include that?