问题
This is my first attempt to create a login system in Android Studio and already got myself into trouble with my code.
My PHP script always returns something as JSON and I'm trying to parse that JSON in my LoginActivity, inside the login -method, but I'm getting the following error after creditentials were forwarded to the server and the login button was clicked:
I/qtaguid﹕ Failed write_ctrl(u 43) res=-1 errno=22
I/qtaguid﹕ Untagging socket 43 failed errno=-22
W/NetworkManagementSocketTagger﹕ untagSocket(43) failed with errno -22
It did work earlier, when I was doing a stringRequest instead of jsonRequest, so everything should be fine on the server side. Since I'm very new to Android development, I'm unable to figure this one out by myself and need desperately your help.
Here's my LoginActivity without the imports:
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
// Define Views
private EditText editTextEmail, editTextPassword;
private Button buttonLogin;
private ProgressBar progress;
private UserLocalStore userLocalStore;
private boolean loggedIn = false;
private final String TAG = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide(); // Hides the Action Bar for Login Activity
setContentView(R.layout.activity_login); // Sets the Content View
// Initializing Views
// EditText fields
editTextEmail = (EditText) findViewById(R.id.editTextEmail);
editTextPassword = (EditText) findViewById(R.id.editTextPassword);
// Buttons
buttonLogin = (Button) findViewById(R.id.buttonLogin);
// Other
progress = (ProgressBar) findViewById(R.id.progressBar);
// This method will set watcher for the EditTextFields
// The method will watch the value set to the EditTextFields.
// If there is nothing inputted in the EditTextField, "Login" button is disabled.
// Correspondingly, if there are text in the field, "Login" button is enabled.
watcher(editTextEmail, editTextPassword, buttonLogin);
// On-Click listeners
buttonLogin.setOnClickListener(this);
}
// Watcher method to check the value of EditText field
public void watcher(final EditText editText, final EditText editPassword, final Button button)
{
editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (editText.length() == 0 && editPassword.length() == 0) // If length of the text field is equal to 0
button.setEnabled(false); // Disable the "Send" button
else
button.setEnabled(true); // Otherwise enable
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
if(editText.length() == 0 && editPassword.length() == 0)
button.setEnabled(false); //disable at app start
}
@Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences = getSharedPreferences(Config.SHARED_PREF_NAME, Context.MODE_PRIVATE);
loggedIn = sharedPreferences.getBoolean(Config.LOGGEDIN_SHARED_PREF, false);
// If the value of loggedIn variable is true
if(!loggedIn) {
// We will start the Courses activity
Intent intent = new Intent(LoginActivity.this, CourseActivity.class);
startActivity(intent);
}
}
private void login() {
// Get the values from the edit texts
final String email = editTextEmail.getText().toString().trim();
final String password = editTextPassword.getText().toString().trim();
// Creating a JSON Object request
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, Config.LOGIN_URL, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
// This line will not print out
System.out.println(response);
try {
String json_status = response.getString("status");
String message = response.getString("message");
if(json_status.equalsIgnoreCase(Config.LOGIN_SUCCESS)) {
System.out.println(message);
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// You can handle the error here if you want
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
// Adding parameters to request
params.put(Config.KEY_EMAIL, email);
params.put(Config.KEY_PASSWORD, password);
// Return parameters
return params;
}
};
// Adding the string request to the queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonObjectRequest);
}
@Override
public void onClick(View v) {
switch(v.getId()) {
// If button Login was clicked
case R.id.buttonLogin:
login(); // Start login method after "Login" button is clicked
// startActivity(new Intent(this, MainActivity.class));
break;
}
}
}
And here's my PHP:
<?php
require_once("dbconnect.php");
// POST Variables
$post_email = $_POST['email'];
$post_password = $_POST['password'];
// Prepare the SQL query
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(array(
':email' => $post_email,
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0 && password_verify($post_password, $row['password']) && $row['role'] != 'staff') {
$user = array(); // Create an array for the user information
$user['id'] = $row['id'];
$user['name'] = $row['name'];
$user['email'] = $row['email'];
$user['password'] = $row['password'];
$user['role'] = $row['role'];
// echo json_encode(["message" => "success"]);
echo json_encode(["status" => "success", "message" => "Successfully logged in"]); // Format the array to JSON
} else {
echo json_encode(["status" => "error", "message" => "Incorrect creditentials"]);
}
回答1:
You might not be passing the params, I usually use this syntax:
// Get the values from the edit texts
final String email = editTextEmail.getText().toString().trim();
final String password = editTextPassword.getText().toString().trim();
Map<String, Object> params = new ArrayMap<>(2);
// Adding parameters to request
params.put(Config.KEY_EMAIL, email);
params.put(Config.KEY_PASSWORD, password);
// Creating a JSON Object request
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, new JSONObject(params),
new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response)
{
Log.d(TAG, response.toString());
// other stuff ...
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
// You can handle the error here if you want
}
});
// Adding the string request to the queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonObjectRequest);
Also, you might want to handle all the volley requests in a Singleton class, have a look at this SO question.
Hope this helps in any way :)
来源:https://stackoverflow.com/questions/33933160/android-studio-using-volley-to-get-json-data-from-the-server