Jay Fitz
Jay Fitz

Reputation: 53

Issue converting string data to JSON format

I am trying to set up a registration process for an android device. The user should open the app, enter in details and be stored in the database.

As it stands, the user will enter the database fine but the logcat is throwing an issue with converting string data to JSON.

Where is this coming from can anyone tell me?

Register.java

public class RegisterTask extends AsyncTask<String, Void, Integer> {

    private ProgressDialog progressDialog;
    private RegisterActivity activity;
    private int id = -1;
    private JSONParser jsonParser;
    private static String loginURL = "http://***.***.**.**/androidUsers/";
    private static String registerURL = "http://***.***.**.**/androidUsers/";
    private static String KEY_SUCCESS = "success";
    private static String KEY_ERROR = "error";
    private static String KEY_ERROR_MSG = "error_msg";
    private static String KEY_UID = "uid";
    private static String KEY_NAME = "name";
    private static String KEY_EMAIL = "email";
    private static String KEY_CREATED_AT = "created_at";
    private int responseCode = 0;

    /*Constructor that takes parameters passed by LoginFragment and stores them as class-
     * wide fields so that all methods can access necessary variables.
     * */
    public RegisterTask(RegisterActivity activity, ProgressDialog progressDialog)
    {
        this.activity = activity;
        this.progressDialog = progressDialog;
    }

    /*A necessary but very simple method that launches a ProgressDialog to show the
     * user that a background task is operating (registration).*/
    @Override
    protected void onPreExecute()
    {
        progressDialog.show();
    }

    /*This method does almost all of the work for the class. It builds a connection to my
     * server, collects the details from the UI of the user's information, and then tries
     * to register the user with the SQL database. All of the actual HTTP connection work
     * is done in a background library class for security - including the hashing of a
     * password into a 64bit encryption. */
    @Override
    protected Integer doInBackground(String... arg0)
    {
        EditText userName = (EditText)activity.findViewById(R.id.registerEmail);
        EditText passwordEdit = (EditText)activity.findViewById(R.id.registerPassword);
        EditText nameEdit = (EditText)activity.findViewById(R.id.registerName);

        String name = nameEdit.getText().toString();
        String email = userName.getText().toString();
        String password = passwordEdit.getText().toString();

        Log.v(email, password);
        UserFunctions userFunction = new UserFunctions();

        JSONObject json = userFunction.registerUser(name, email, password);

        // check for login response
        try
        {
            
            if (json.getString(KEY_SUCCESS) != null)
            {
                //registerErrorMsg.setText("");
                String res = json.getString(KEY_SUCCESS);
                if(Integer.parseInt(res) == 1){
                    // user successfully registred
                    // Store user details in SQLite Database
                    DatabaseHandler db = new DatabaseHandler(activity.getApplicationContext());
                    JSONObject json_user = json.getJSONObject("user");

                    // Clear all previous data in database
                    userFunction.logoutUser(activity.getApplicationContext());
                    db.addUser(json_user.getString(KEY_NAME),
                            json_user.getString(KEY_EMAIL), json.getString(KEY_UID),
                            json_user.getString(KEY_CREATED_AT));
                    //successful registration
                    responseCode = 1;
                }else{
                    // Error in registration
                    responseCode = 0;
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return responseCode;
    }

    /*This final method concludes the background task. Its responseCode variable is sent from
     * doInBackground, and this method acts based on the code it is sent. If the code is 1,
     * registration was successful and the main activity notifies the user of succes - the
     * inverse occurs if there is a failure and 0 was sent.*/
    @Override
    protected void onPostExecute(Integer responseCode)
    {
        EditText userName = (EditText)activity.findViewById(R.id.registerEmail);
        EditText passwordEdit = (EditText)activity.findViewById(R.id.registerPassword);
        String s = userName.getText().toString();

        if (responseCode == 1) {
            progressDialog.dismiss();
            activity.registerReport(responseCode);
            userName.setText("");
            passwordEdit.setText("");
        }
        if (responseCode == 0) {
            progressDialog.dismiss();
            activity.registerReport(responseCode);
        }
    }
}

JSONParser

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {

        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
            Log.e("JSON", json);
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) { //this is where the error results
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }

}

Logcat

20:35:56.346  11989-12390/com.example.jay.demoapp E/JSON﹕ Connected successfully{"tag":"register","success":1,"error":0,"uid":"5519a59d377a95.73943916","user":{"name":"testname","email":"[email protected]","created_at":"2015-03-30 20:35:57","updated_at":null}}
03-30 20:35:56.361  11989-12390/com.example.jay.demoapp E/JSON Parser﹕ Error parsing data org.json.JSONException: Value Connected of type java.lang.String cannot be converted to JSONObject
03-30 20:35:56.361  11989-12390/com.example.jay.demoapp W/dalvikvm﹕ threadid=12: thread exiting with uncaught exception (group=0x412bd2a0)
03-30 20:35:56.396  11989-12390/com.example.jay.demoapp E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.NullPointerException
            at com.example.jay.demoapp.RegisterTask.doInBackground(RegisterTask.java:76)
            at com.example.jay.demoapp.RegisterTask.doInBackground(RegisterTask.java:18)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
03-30 20:36:05.346  11989-11989/com.example.jay.demoapp I/Choreographer﹕ Skipped 527 frames!  The application may be doing too much work on its main thread.
03-30 20:36:05.916  11989-11989/com.example.jay.demoapp E/WindowManager﹕ Activity com.example.jay.demoapp.RegisterActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41d7c868 that was originally added here
    android.view.WindowLeaked: Activity com.example.jay.demoapp.RegisterActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41d7c868 that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:403)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:311)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
            at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
            at android.view.Window$LocalWindowManager.addView(Window.java:554)
            at android.app.Dialog.show(Dialog.java:277)
            at com.example.jay.demoapp.RegisterTask.onPreExecute(RegisterTask.java:49)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
            at android.os.AsyncTask.execute(AsyncTask.java:534)
            at com.example.jay.demoapp.RegisterActivity$1.onClick(RegisterActivity.java:52)
            at android.view.View.performClick(View.java:4232)
            at android.view.View$PerformClick.run(View.java:17298)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4921)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
            at dalvik.system.NativeStart.main(Native Method)

As i've said previously, the data will get to the database no problem and store the user, but I cannot login with that data which I'm assuming is caused by the above error.

update

added the JSONParser class as the error seems to be coming from the last try-catch block

Upvotes: 0

Views: 59

Answers (1)

dhke
dhke

Reputation: 15388

I think you overlooked (I did on first glance) the actual problem because you silence the JSONException that you are getting:

    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) { //this is where the error results
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

The server sends the string Connected successfully before the actual JSON response:

Connected successfully{...}

This shows in your log output. Because of this, your JSON parse fails, which causes getJSONFromUrl() to return null.

The line

        if (json.getString(KEY_SUCCESS) != null)

then fails with NullPointerException as a delayed error from the failed parse, because json is null.

Suggested solution: Check your server side code and remove the Connected successfully that the server is sending to you.

Upvotes: 1

Related Questions