0

First of all i am newbie in android. I have read almost every similar topic but i couldn't find specific answers. The problem is at json parsing of my Login activity. What can i do to find where NullPointException come from; Im stucked for over one week... Thanks in advance

I have to mention that my app worked like a charm. The problems began after trying to connect to my localhost fare away from my wifi. Isnt that very strange;

Login.java

package com.example.tranfer;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Login extends Activity implements OnClickListener{

private EditText user, pass;
private Button mSubmit, mRegister;

 // Progress Dialog
private ProgressDialog pDialog;

// JSON parser class
JSONParser jsonParser = new JSONParser();

//php login script location:

//localhost :
//testing on your device
//put your local ip instead,  on windows, run CMD > ipconfig
//or in mac's terminal type ifconfig and look for the ip under en0 or en1
// private static final String LOGIN_URL = "http://192.168.1.4:80/etruck1/login1.php";

//testing on Emulator:
 private static final String LOGIN_URL = "http://.............................";

//testing from a real server:
//private static final String LOGIN_URL = "http://www.yourdomain.com/webservice/login.php";

//JSON element ids from repsonse of php script:
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login);

    //setup input fields
    user = (EditText)findViewById(R.id.edtusername);
    pass = (EditText)findViewById(R.id.edtpassword);


    //setup buttons
    mSubmit = (Button)findViewById(R.id.signin);
    mRegister = (Button)findViewById(R.id.register);

    //register listeners
    mSubmit.setOnClickListener(this);
    mRegister.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
    case R.id.signin:
            new AttemptLogin().execute();
        break;
    case R.id.register:
            Intent i = new Intent(this, RegistrationForm.class);
            startActivity(i);
        break;

    default:
        break;
    }
}

class AttemptLogin extends AsyncTask<String, String, String> {

     /**
     * Before starting background thread Show Progress Dialog
     * */
    boolean failure = false;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(Login.this);
        pDialog.setMessage("Attempting login...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
         // Check for success tag
        int success;
        String username = user.getText().toString();
        String password = pass.getText().toString();
        Log.d(username, username);
        try {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("username", username));
            params.add(new BasicNameValuePair("password", password));

            Log.d("request!", "starting");
            // getting product details by making HTTP request
            JSONObject json = jsonParser.makeHttpRequest(
                   LOGIN_URL, "POST", params);

            // check your log for json response
            Log.d("Login attempt", json.toString());

            // json success tag
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                Log.d("Login Successful!", json.toString());
                Intent i = new Intent(Login.this, MainActivity1.class);
                finish();
                startActivity(i);
                return json.getString(TAG_MESSAGE);
            }else{
                Log.d("Login Failure!", json.getString(TAG_MESSAGE));
                return json.getString(TAG_MESSAGE);

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

        return null;

    }
    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once product deleted
        pDialog.dismiss();
        if (file_url != null){
            Toast.makeText(Login.this, file_url, Toast.LENGTH_LONG).show();
        }

    }

}
@Override
// Το παρακάτω το πρόσθεσα εγω
protected void onDestroy() {
    if (pDialog != null) {
        if (pDialog.isShowing()) {
            pDialog.dismiss();
            pDialog = null;
        }
    }
    super.onDestroy();
}
}

Login.php

?php
//load and connect to MySQL database stuff
require("config.inc.php");
$query_params=null;

if (!empty($_POST)) {
//gets user's info based off of a username.
$query = " 
        SELECT 
            id, 
            username, 
            password
        FROM registration 
        WHERE 
            username = :username  ";

$query_params = array(
    ':username' => $_POST['username']
);

try {
    $stmt   = $db->prepare($query);
    $result = $stmt->execute(); 
   $stmt->execute($query_params); 
}
catch (PDOException $ex) {
    // For testing, you could use a die and message. 
    //die("Failed to run query: " . $ex->getMessage());

    //or just use this use this one to product JSON data:
    $response["success"] = 0;
    $response["message"] = "Database Error1. Please Try Again!";
    die(json_encode($response));

}

    //we initialize it as false.
$validated_info = false;

//fetching all the rows from the query
$row = $stmt->fetch();
$login_ok = false;
if ($row) {
    //if we encrypted the password, we would unencrypt it here, but in our case we just
    //compare the two passwords
    if ($_POST['password'] === $row['password']) {
        $login_ok = true;
    }
}

// If the user logged in successfully, then we send them to the private members-only page 
// Otherwise, we display a login failed message and show the login form again 
if ($login_ok) {
    $response["success"] = 1;
    $response["message"] = "Συνδεθήκατε επιτυχώς!";
    die(json_encode($response));
} else {
    $response["success"] = 0;
    $response["message"] = "Λανθασμένα στοιχεία!";
    die(json_encode($response));
 }
} else {
?>
    <h1>Login</h1> 
    <form action="login.php" method="post"> 
        Username:<br /> 
        <input type="text" name="username" placeholder="username" /> 
        <br /><br /> 
        Password:<br /> 
        <input type="password" name="password" placeholder="password" value=""  /> 
        <br /><br /> 
        <input type="submit" value="Login" /> 
    </form> 
    <a href="register.php">Register</a>
<?php
}

?> 

and Log.cat

06-07 14:24:08.245: E/JSON Parser(28772): Error parsing data org.json.JSONException: Value Failed of type java.lang.String cannot be converted to JSONObject
06-07 14:24:08.315: W/dalvikvm(28772): threadid=12: thread exiting with uncaught exception (group=0x411342a0)
06-07 14:24:09.036: E/AndroidRuntime(28772): FATAL EXCEPTION: AsyncTask #1
06-07 14:24:09.036: E/AndroidRuntime(28772): java.lang.RuntimeException: An error occured while executing doInBackground()
06-07 14:24:09.036: E/AndroidRuntime(28772):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.lang.Thread.run(Thread.java:856)
06-07 14:24:09.036: E/AndroidRuntime(28772): Caused by: java.lang.NullPointerException
06-07 14:24:09.036: E/AndroidRuntime(28772):    at com.example.tranfer.Login$AttemptLogin.doInBackground(Login.java:127)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at com.example.tranfer.Login$AttemptLogin.doInBackground(Login.java:1)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-07 14:24:09.036: E/AndroidRuntime(28772):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
06-07 14:24:09.036: E/AndroidRuntime(28772):    ... 5 more
akhilesh0707
  • 6,709
  • 5
  • 44
  • 51

4 Answers4

0

in php ...

json_encode(array("data" => $yourarray));

then you can parse it using a JSONObject since it's by default formatted as an JSONArray.

If you want to force it as an JSONObject you will need to set the flag JSON_FORCE_OBJECT.

example:

json_encode($data, JSON_FORCE_OBJECT);

Check my answer on

How to decode JSON values in my Android Aplication?

which solves your problem.

In your case

In Java

String jsonData = jsonParser.makeHttpRequest(LOGIN_URL, "POST", params); 
JSONObject obj = (JSONObject) new JSONTokener(jsonData ).nextValue(); 
String yourdata= obj.getString("message");

Oh, and by the way.. You shouldnt send your password as parameter between the client and server since this is readable by everyone in the same network aslong it's not transfered via ssl or crypted.

Community
  • 1
  • 1
Emanuel
  • 8,027
  • 2
  • 37
  • 56
  • Thanks emanuel for response. What exactly should I replace? btw..i think i have json objects not json arrays – user3649152 Jun 07 '14 at 12:00
  • force it to be a json object in your PHP app. json_encode(..., JSON_FORCE_OBJECT); – Emanuel Jun 07 '14 at 12:28
  • String jsonData = jsonParser.makeHttpRequest(LOGIN_URL, "POST", params); JSONObject obj = (JSONObject) new JSONTokener(jsonData ).nextValue(); String yourdata= obj.getString("message"); check my updated answer – Emanuel Jun 07 '14 at 12:38
0

Take a look at the LogCat. It says NullPointerException on Login.java:127 which means line 127. Which should be success = json.getInt(TAG_SUCCESS);

As TAG_SUCCESS is initialized and final it must have to do with your json Object, which is initialized here JSONObject json = jsonParser.makeHttpRequest(LOGIN_URL, "POST", params); This probably fails ;)

Torhan Bartel
  • 550
  • 6
  • 33
  • Erm, no. Value Failed of type java.lang.String cannot be converted to JSONObject Means that the string can't be interpreted or parsed because its not a valid JSONObject. Check my Solution since it's (in PHP) converted as an JSONArray(). Anyway, you can use the flag JSON_FORCE_OBJECT but better do json_encode(array("data", $yourarray)); and parse a JSONArray() – Emanuel Jun 07 '14 at 11:43
  • I know to read logcat, i know what fails. I need to read answers – user3649152 Jun 07 '14 at 12:15
0

change your asynctask class defintion to this:

class AttemptLogin extends AsyncTask<Void, Void, String> 

and your doInBackground to this:

protected String doInBackground(Void... params)
Milan Maharjan
  • 4,156
  • 1
  • 21
  • 28
0

did you add all the permissions on the manifiest?

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET"/>