我想在mysql数据库中使用web服务在android应用程序中注册用户。 我在php端使用下面的代码:
<?php
header("Content-type: application/json; charset=utf-8");
require_once("dbconnect.php");
require_once 'jdf.php';
if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){
throw new Exception('Request must be in POST method!');
}
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if(strcasecmp($contentType, 'application/json') != 0){
throw new Exception('Request must send in json format!');
}
$content = trim(file_get_contents("php://input"));
$decoded = json_decode($content, true);
if(!is_array($decoded)){
throw new Exception('invalid request!');
}
$res = $decoded;
$data = array();
if(array_key_exists('username',$res)){
//username exist
$username = $res['username'];
$pass = md5($res['password']);
$mobile = $res['mobile'];
$stmt = $db->prepare("SELECT * FROM users WHERE username = :a");
$stmt->bindparam(':a',$username);
$stmt->execute();
$c = $stmt->rowCount();
if($c == 0){
$date = jdate("Y/m/d H:i",'','','','en');
$stmt = $db->prepare("INSERT INTO users (mobile, username, password, reg_date)VALUES(:a, :b, :c, :d)");
$stmt->bindparam(':a',$mobile);
$stmt->bindparam(':b',$username);
$stmt->bindparam(':c',$pass);
$stmt->bindparam(':d',$date);
$stmt->execute();
$s = false;
$m = 'register successful!';
}else{
$s = true;
$m = 'this user already registered!';
$res_u = $stmt->fetch();
$username = $res_u['username'];
$date = $res_u['reg_date'];
$data = array('username' => $username, 'date' => $date);
}
}else{
$s = true;
$m = 'username is not sent!';
}
$back = array('error' => $s, 'message' => $m, 'data' => $data);
$json_response = json_encode($back);
echo $json_response;
在android中我是新手,只是在下面的链接中找到了一个示例代码: https://www.simplifiedcoding.net/android-volley-tutorial/
我在这个页面中使用了完全相同的代码,所以我不会把它们放在这里,只是在注册活动中我有这个代码:
package ir.sample.project;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class activity_reg extends AppCompatActivity {
EditText txtUser, txtMobile, txtPass;
ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reg);
progressBar = findViewById(R.id.progressBar);
//if the user is already logged in we will directly start the profile activity
if (SharedPrefManager.getInstance(this).isLoggedIn()) {
finish();
startActivity(new Intent(this, activity_dashboard.class));
return;
}
txtUser = findViewById(R.id.txt_user);
txtMobile = findViewById(R.id.txt_mobile);
txtPass = findViewById(R.id.txt_pass);
findViewById(R.id.btn_reg).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
registerUser();
}
});
findViewById(R.id.btn_open_log).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
startActivity(new Intent(activity_reg.this, activity_login.class));
}
});
}
private void registerUser() {
final String username = txtUser.getText().toString().trim();
final String mobile = txtMobile.getText().toString().trim();
final String password = txtPass.getText().toString().trim();
progressBar.setVisibility(View.VISIBLE);
if(TextUtils.isEmpty(username)){
txtUser.setError("Enter username!");
txtUser.requestFocus();
}
if(TextUtils.isEmpty(mobile)){
txtMobile.setError("Enter mobile!");
txtMobile.requestFocus();
}
if(TextUtils.isEmpty(password)){
txtPass.setError("Enter password!");
txtPass.requestFocus();
}
StringRequest stringRequest = new StringRequest(Request.Method.POST, URLs.URL_REGISTER, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressBar.setVisibility(View.GONE);
try {
//converting response to json object
JSONObject obj = new JSONObject(response);
//if no error in response
if (!obj.getBoolean("error")) {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
//getting the user from the response
JSONObject userJson = obj.getJSONObject("user");
//creating a new user object
User user = new User(
userJson.getInt("id"),
userJson.getString("username"),
userJson.getString("mobile")
);
//storing the user in shared preferences
SharedPrefManager.getInstance(getApplicationContext()).userLogin(user);
//starting the profile activity
finish();
startActivity(new Intent(getApplicationContext(), activity_dashboard.class));
} else {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("username", username);
params.put("mobile",mobile);
params.put("password",password);
return params;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
}
我已经用Fiddler测试了我的php端并且它运行良好(就像异常一样),但是当我运行应用程序并单击注册按钮时没有任何反应并且不能在所有的地方工作没有显示错误。我想知道如何在这些代码中找到错误,因为我知道有一种方法可以打印和显示错误,就像我在php中做的那样(我擅长php)。 (对不起,如果我的英语不好)
更新1
在吐司中打印异常错误后,我收到此错误:
"Value <br of type java.lang.string cannot be converted to JSONObject"
我用谷歌搜索了一下,有人在这里发布了这个解决方案:
int jsonStart = response.indexOf("{");
int jsonEnd = response.lastIndexOf("}");
if (jsonStart >= 0 && jsonEnd >= 0 && jsonEnd > jsonStart) {
response = response.substring(jsonStart, jsonEnd + 1);
}
我使用了上面的代码然后收到了这个代码:
"expected ' ' after main at character 6 of {main}"
解决这个问题的任何方法?
注意!在服务器端,我用Fiddler测试了它,注册成功了,返回的代码也是正确的json格式,没有任何HTML代码。