Android Studio - 使用 Volley 从服务器获取 JSON 数据

Android Studio - Using Volley to get JSON data from the server

这是我第一次尝试在 Android Studio 中创建登录系统,我的代码已经让自己陷入困境。

我的 PHP 脚本总是 returns 类似于 JSON 的东西,我试图在我的 LoginActivity 中解析 JSON,在登录方法中,但是我越来越 将凭据转发到服务器并单击登录按钮后出现以下错误:

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

它确实工作得更早,当我做一个 stringRequest 而不是 jsonRequest 时,所以服务器端的一切都应该没问题。由于我是 Android 开发的新手,我无法自己解决这个问题,迫切需要您的帮助。

这是我没有导入的 LoginActivity:

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;
        }
    }
}

这是我的 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"]);
}

你可能没有传递参数,我通常使用这种语法:

 // 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);

此外,您可能希望在单例中处理所有的 volley 请求 class,看看这个 SO question

希望这对您有所帮助:)