Android使用JSON注册并从web服务获取结果- PHP


Android using JSON to register and get results from web service - PHP

我去年做了一个android应用程序,它工作得很好,我被重新分配到开发应用程序。

但是用户的注册已经停止。至于为什么,我也不知道。

这是我的开始屏幕,用户注册的活动:

public class Prompt extends Activity {
    public EditText u, p, e;
    public String username, password, emailadd;
    public Button createClient;
    final Context context = this;
    public TextView registerErrorMsg;
    // JSON Response node names
    private static String KEY_SUCCESS = "success";
    @SuppressWarnings("unused")
    private static String KEY_ERROR = "error";
    @SuppressWarnings("unused")
    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";
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.prompt);
        // Importing all assets like buttons, text fields
        u = (EditText) findViewById(R.id.username);
        p = (EditText) findViewById(R.id.Password);
        e = (EditText) findViewById(R.id.emailAddress);
        createClient = (Button) findViewById(R.id.createClient);
        registerErrorMsg = (TextView) findViewById(R.id.register_error);
        u.setText("usernametest");
        p.setText("passwordtest");
        e.setText("TEST@gmail.com");
        //Toast.makeText(getApplicationContext(), "...", Toast.LENGTH_LONG).show();
        createClient.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                username = u.getText().toString();
                password = p.getText().toString();
                emailadd = e.getText().toString();
                UserFunctions userFunction = new UserFunctions();
                //Toast.makeText(getApplicationContext(), username+" "+password+" "+emailadd, Toast.LENGTH_LONG).show();
                //now we have text input, validate them
                if(username.length() < 5 || password.length() < 5 || emailadd.length() < 5){
                    //minimum input for each field is > 5 characters
                    registerErrorMsg.setText("Username, password and email must have must than 5 characters");
                }
                else{
                    //if validated correctly upload
                    JSONObject json = userFunction.registerUser(username, emailadd, password);
                    Log.e("JSON RESULT", "JSON result: " + json);
                    //successfully make the check file and redirect to the homepage
                    try {
                            String FILE_NAME = "filename.txt";
                            FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_WORLD_READABLE);
                            try{
                                fos.write(username.getBytes());
                            }catch (IOException e){
                                e.printStackTrace();
                            }
                            fos.close();
                            //if all complete, redirect to home page
                            Intent intent2 = new Intent(Prompt.this, StrategicEnergyActivity.class);
                            intent2.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(intent2);
                            finish();
                    } 
                    catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } 
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
}

这是我的JSON解析器类来处理从web服务返回的JSON:

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) {
        Log.e("TESTTTT", " " + params.get(0) + " " + params.get(1) + " " + params.get(2)  + " " + params.get(3));
        // Making HTTP request
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            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);
            }
            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) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }
        // return JSON String
        return jObj;
    }
}

这是我的用户函数类,类做数据处理/方法调用:

public class UserFunctions {
    private JSONParser jsonParser;
    private static String registerURL = "http://www.website.com/api/index.php?";
    private static String register_tag = "register";
    // constructor
    public UserFunctions(){
        jsonParser = new JSONParser();
    }
    /**
     * function make Login Request
     * @param name
     * @param email
     * @param password
     * */
    public JSONObject registerUser(String name, String email, String password){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag", register_tag));
        params.add(new BasicNameValuePair("name", name));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("password", password));
        Log.e("Credentials", "Username: " + name + "'nEmail: " + email + "'nPassword: " + password);
        //Toast.makeText(getParent(), name+" "+email+" "+password, Toast.LENGTH_LONG).show();
        JSONObject json = jsonParser.getJSONFromUrl(registerURL, params);
        return json;
    }
}

下面是我的web服务的代码:

<?php
    print_r($_POST);
    $tag = "register";
    // include db handler
    require_once 'include/DB_Functions.php';
    $db = new DB_Functions();
    // response Array
    $response = array("tag" => $tag, "success" => 0, "error" => 0);
    // check for tag type
    if ($tag == 'register') {
        // Request type is Register new user
        $name = $_POST['name'];
        $email = $_POST['email'];
        $password = $_POST['password'];
        // check if user is already existed
        if($db->isUserExisted($email)){
            // user is already exists - error response
            $response["error"] = 2;
            $response["error_msg"] = "User Already Exists";
            echo json_encode($response). "User Already Exists";
        } 
        else{       
            // store user
            $user = $db->storeUser($name, $email, $password);
            if($user){
                // user stored successfully
                $response["success"] = 1;
                $response["uid"] = $user["unique_id"];
                $response["user"]["name"] = $user["name"];
                $response["user"]["email"] = $user["email"];
                $response["user"]["created_at"] = $user["created_at"];
                $response["user"]["updated_at"] = $user["updated_at"];
                echo json_encode($response). "User Stored Successfully";
            } 
            else{
                // user failed to store
                $response["error"] = 1;
                $response["error_msg"] = "Error occured in Registration";
                echo json_encode($response);
            }
        }
    } 
    else{
        echo "Invalid Request";
    }
?>

最后这是当前抛出给我的错误,它发生在JSONParser类的sb.append(line)行:

05-21 16:35:46.304: E/Buffer Error(4278): Error converting result java.lang.NullPointerException
05-21 16:35:46.308: E/JSON Parser(4278): Error parsing data org.json.JSONException: End of input at character 0 of 
05-21 16:35:46.308: E/JSON RESULT(4278): JSON result: null

有人能发现我在这里做错了什么吗?无论如何,我都将非常感谢你的帮助。

提前感谢!

当您尝试解析JSON中没有任何内容时,会发生错误。例如,如果你的手机没有连接到互联网,而你试图连接到你的服务器,你会看到类似的响应。没有数据要解析所以你会得到一个JSONException

我猜这与你的I/O函数不在后台线程上有关。根据所提供的代码,您将在主UI线程的JSONParser类中运行HttpPost。自API 11以来,这是不允许的。因此,您将没有值可以解析并抛出JSONException

尝试将此函数移动到AsyncTask。如果在任务的doInBackground方法中执行HttpPost,则可以消除错误。这里是AsyncTask相关的android文档的链接。他们提供了一些有用的代码示例。

AsyncTask的基本结构如下:

private class DownloadFilesTask extends AsyncTask<URL, Void, Long> {
     protected Long doInBackground(URL... urls) {
        //stuff to do in background 
        return result;
     }
     protected void onPostExecute(Long result) {
        //stuff that runs on the UI thread using the result of background thread 
     }
 }

在这个例子中,取自android文档,你可以看到一些关键参数。(1) &lt中指示的任务的参数/返回值;> (2) doInBackground方法,令人震惊的是,在后台线程上运行;(3)onPostExecute方法,在doInBackground方法完成后在UI线程上运行。onPostExecute接受doInBackground返回的值作为参数。如果你注意到,该参数的类型对应于<在上课开始的时候。>

你将不得不玩周围这适合你的代码,但基本的想法是,任何I/O函数-像你的HttpPost发生在后台线程。任何UI更新,如改变TextView中的文本,使用Toast或移动屏幕上的东西都发生在onPostExecute中。换句话说,在doInBackground中下载你需要的东西并返回结果-在你的情况下是一些JSON/字符串-到onPostExecute,在那里你可以通知用户更改,例如他们是否成功注册。

如何传递值给AsyncTask

你在评论中问了另一个问题,关于如何将URL传递给AsyncTask。将值传递给AsyncTask发生在用于启动任务的execute()方法中。因为AsyncTask是它自己的类,所以需要首先创建任务的实例

DownloadFilesTask t = new DownloadFilesTask();

创建任务实例后,使用execute()方法启动该任务。在这里,您可以传递您希望任务在doInBackgroundMethod中接收的值。

t.execute(myUrl);

要传递多个值,只需将它们以逗号分开添加

t.execute(myUrl1, myUrl2, myUrl3);

要检索传入的值,您可以在doInBackground方法中访问它们。AsyncTask接受称为varargs的参数。这些基本上是特定类型的值列表。在您的示例中,它们将是url。要访问它们,您可以通过索引获取值。

URL first = urls[0] 

例如,引用您传递给AsyncTask的第一个URL值。您用来检索它的名称对应于…后面的名称。作为doInBackground方法的参数。例如,如果你将一个URL传递给AsyncTask然后想在getWhatever方法中检索它你只需使用

getWhatever(urls[0]);

如果有多个URL并且这是一个迭代过程你可以使用for循环或任何其他方法遍历所提供的URL