Android JSON服务器响应可能无效错误

时间:2014-08-21 15:11:36

标签: android mysql json sqlite

我已开发和应用程序,因为我需要将本地数据库同步到远程我的sql数据库,所以我已经在mysql中创建了一个表,并为这些脚本文件编写了一些脚本

<?php

class DB_Functions {

private $db;

//put your code here
// constructor
function __construct() {
    include_once './db_connect.php';
    // connecting to database
    $this->db = new DB_Connect();
    $this->db->connect();
}

// destructor
function __destruct() {

}

/**
 * Storing new user
 * returns user details
 */
public function storeUser($Name,$Email,$Phnum) {
    // Insert user into database
    $result = mysql_query("INSERT INTO              games(name,email,phno)VALUES('$Name','$Email',$Phnum)");

    if ($result) {
        return true;
    } else {
        if( mysql_errno() == 1062) {
            // Duplicate key - Primary Key Violation
            return true;
        } else {
            // For other errors
            return false;
        }            
    }
}
 /**
 * Getting all users
 */
public function getAllUsers() {
    $result = mysql_query("select name,email,phno FROM games");
    return $result;
}
}

?>  

这是我的insertuser.php文件

 <?php
include_once './db_functions.php';
//Create Object for DB_Functions clas
$db = new DB_Functions(); 
//Get JSON posted by Android Application
$json = $_POST["usersJSON"];
//Remove Slashes
if (get_magic_quotes_gpc()){
$json = stripslashes($json);  
}
//Decode JSON into an Array
$data = json_decode($json);
//Util arrays to create response JSON
$a=array();
$b=array();
//Loop through an Array and insert data read from JSON into MySQL DB
for($i=0; $i<count($data) ; $i++)
{
//Store User into MySQL DB
$res = $db->storeUser($data[$i]->userName,$data[$i]->userEmail,$data[$i]->userPhno);
//Based on insertion, create JSON response
if($res){
    $b["name"] = $data[$i]->userName;
    $b["status"] = 'yes';
    array_push($a,$b);
}else{
    $b["name"] = $data[$i]->userName;
    $b["status"] = 'no';
    array_push($a,$b);
}
}
//Post JSON response back to Android Application
  echo json_encode($a);  
  ?>

这是我的DBController.java文件

public class DBController  extends SQLiteOpenHelper {

public DBController(Context applicationcontext) {
    super(applicationcontext, "syncscore.db", null, 1);
}
//Creates Table
@Override
public void onCreate(SQLiteDatabase database) {
    String query;
    query = "CREATE TABLE games ( userName TEXT, userEmail TEXT,userPhno TEXT, udpateStatus TEXT)";
    database.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
    String query;
    query = "DROP TABLE IF EXISTS games";
    database.execSQL(query);
    onCreate(database);
}
/**
 * Inserts User into SQLite DB
 * @param queryValues
 */
public void insertUser(HashMap<String, String> queryValues) {
    SQLiteDatabase database = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("userName", queryValues.get("userName"));
    values.put("userEmail", queryValues.get("userEmail"));
    values.put("userPhno", queryValues.get("userPhno"));
    values.put("udpateStatus", "no");
    database.insert("games", null, values);
    database.close();
}

/**
 * Get list of Users from SQLite DB as Array List
 * @return
 */
public ArrayList<HashMap<String, String>> getAllUsers() {
    ArrayList<HashMap<String, String>> wordList;
    wordList = new ArrayList<HashMap<String, String>>();
    String selectQuery = "SELECT  * FROM games";
    SQLiteDatabase database = this.getWritableDatabase();
    Cursor cursor = database.rawQuery(selectQuery, null);
    if (cursor.moveToFirst()) {
        do {
             HashMap<String, String> map = new HashMap<String, String>();
            map.put("userName", cursor.getString(0));
            map.put("userEmail", cursor.getString(1));
            map.put("userPhno", cursor.getString(2));
           wordList.add(map);
        } while (cursor.moveToNext());
    }
    database.close();
    return wordList;
}

/**
 * Compose JSON out of SQLite records
 * @return
 */
public String composeJSONfromSQLite(){
    ArrayList<HashMap<String, String>> wordList;
    wordList = new ArrayList<HashMap<String, String>>();
    String selectQuery = "SELECT  * FROM games where udpateStatus = '"+"no"+"'";
    SQLiteDatabase database = this.getWritableDatabase();
    Cursor cursor = database.rawQuery(selectQuery, null);
    if (cursor.moveToFirst()) {
        do {
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("userName", cursor.getString(0));
            map.put("userEmail", cursor.getString(1));
            map.put("userPhno", cursor.getString(2));
            wordList.add(map);
        } while (cursor.moveToNext());
    }
    database.close();
    Gson gson = new GsonBuilder().create();
    //Use GSON to serialize Array List to JSON
    return gson.toJson(wordList);
}

/**
 * Get Sync status of SQLite
 * @return
 */
public String getSyncStatus(){
    String msg = null;
    if(this.dbSyncCount() == 0){
        msg = "SQLite and Remote MySQL DBs are in Sync!";
    }else{
        msg = "DB Sync needed\n";
    }
    return msg;
}

/**
 * Get SQLite records that are yet to be Synced
 * @return
 */
public int dbSyncCount(){
    int count = 0;
    String selectQuery = "SELECT  * FROM games where udpateStatus = '"+"no"+"'";
    SQLiteDatabase database = this.getWritableDatabase();
    Cursor cursor = database.rawQuery(selectQuery, null);
    count = cursor.getCount();
    database.close();
    return count;
}

/**
 * Update Sync status against each User ID
 * @param id
 * @param status
 */
public void updateSyncStatus(String name, String status){
    SQLiteDatabase database = this.getWritableDatabase();     
    String updateQuery = "Update games set udpateStatus = '"+ status +"' where userName="+"'"+ name +"'";
    Log.d("query",updateQuery);        
    database.execSQL(updateQuery);
    database.close();
}

}

这是我的MainActivity.java文件

public class MainActivity extends Activity {
//DB Class to perform DB related operations
DBController controller = new DBController(this);
//Progress Dialog Object
ProgressDialog prgDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //Get User records from SQLite DB 
    ArrayList<HashMap<String, String>> userList =  controller.getAllUsers();
    //
    if(userList.size()!=0){
        //Set the User Array list in ListView
        ListAdapter adapter = new SimpleAdapter( MainActivity.this,userList, R.layout.view_user_entry, new String[] { "userId","userName"}, new int[] {R.id.userId, R.id.userName});
        ListView myList=(ListView)findViewById(android.R.id.list);
        myList.setAdapter(adapter);
        //Display Sync status of SQLite DB
        Toast.makeText(getApplicationContext(), controller.getSyncStatus(), Toast.LENGTH_LONG).show();
    }
    //Initialize Progress Dialog properties
    prgDialog = new ProgressDialog(this);
    prgDialog.setMessage("Synching SQLite Data with Remote MySQL DB. Please wait...");
    prgDialog.setCancelable(false);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    //When Sync action button is clicked
    if (id == R.id.refresh) {
        //Sync SQLite DB data to remote MySQL DB
        syncSQLiteMySQLDB();
        return true;
    }
    return super.onOptionsItemSelected(item);
}
//Add User method getting called on clicking (+) button
public void addUser(View view) {
    Intent objIntent = new Intent(getApplicationContext(), NewUser.class);
    startActivity(objIntent);
}

public void syncSQLiteMySQLDB(){
    //Create AsycHttpClient object
    AsyncHttpClient client = new AsyncHttpClient();
    RequestParams params = new RequestParams();
    ArrayList<HashMap<String, String>> userList =  controller.getAllUsers();
    if(userList.size()!=0){
        if(controller.dbSyncCount() != 0){
            prgDialog.show();
            params.put("usersJSON", controller.composeJSONfromSQLite());
            client.post("http://10.0.2.2/syncscore/viewusers.php",params ,new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(String response) {
                    System.out.println(response);
                    prgDialog.hide();
                    try {
                        JSONArray arr = new JSONArray(response);
                        System.out.println(arr.length());
                        for(int i=0; i<arr.length();i++){
                            JSONObject obj = (JSONObject)arr.get(i);
                            //System.out.println(obj.get("name"));
                            //System.out.println(obj.get("status"));
                            controller.updateSyncStatus(obj.get("name").toString(),obj.get("status").toString());
                        }
                        Toast.makeText(getApplicationContext(), "DB Sync completed!", Toast.LENGTH_LONG).show();
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        Toast.makeText(getApplicationContext(), "Error Occured [Server's JSON response might be invalid]!", Toast.LENGTH_LONG).show();
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(int statusCode, Throwable error,
                    String content) {
                    // TODO Auto-generated method stub
                    prgDialog.hide();
                    if(statusCode == 404){
                        Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
                    }else if(statusCode == 500){
                        Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
                    }else{
                        Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]", Toast.LENGTH_LONG).show();
                    }
                }
            });
        }else{
            Toast.makeText(getApplicationContext(), "SQLite and Remote MySQL DBs are in Sync!", Toast.LENGTH_LONG).show();
        }
    }else{
            Toast.makeText(getApplicationContext(), "No data in SQLite DB, please do enter User name to perform Sync action", Toast.LENGTH_LONG).show();
    }
}

}

在模拟器中运行此应用程序后,用户输入的数据存储在本地数据库中,如果我在应用程序中单击一个名为sync的按钮,则表示JSON服务器响应可能无效。

任何人都可以让我知道我错在哪里..?从2天开始坚持这个请帮助解决这个问题 谢谢   请检查我的Log cat

08-22 00:28:31.790: W/System.err(19929): org.json.JSONException: Value <html> of type       java.lang.String cannot be converted to JSONArray
08-22 00:28:31.800: W/System.err(19929):    at org.json.JSON.typeMismatch(JSON.java:111)
08-22 00:28:31.800: W/System.err(19929):    at org.json.JSONArray.<init>(JSONArray.java:96)
08-22 00:28:31.810: W/System.err(19929):    at org.json.JSONArray.<init>(JSONArray.java:108)
08-22 00:28:31.810: W/System.err(19929):    at   com.sathya.syncandroid.MainActivity$1.onSuccess(MainActivity.java:96)
08-22 00:28:31.810: W/System.err(19929):    at     com.loopj.android.http.AsyncHttpResponseHandler.onSuccess(AsyncHttpResponseHandler.java:232    )
08-22 00:28:31.810: W/System.err(19929):    at        com.loopj.android.http.AsyncHttpResponseHandler.onSuccess(AsyncHttpResponseHandler.java:220    )
08-22 00:28:31.810: W/System.err(19929):    at com.loopj.android.http.AsyncHttpResponseHandler.onSuccess(AsyncHttpResponseHandler.java:245    )
08-22 00:28:31.810: W/System.err(19929):    at   com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java    :365)
08-22 00:28:31.810: W/System.err(19929):    at         com.loopj.android.http.AsyncHttpResponseHandler$ResponderHandler.handleMessage(AsyncHttpRes    ponseHandler.java:135)
08-22 00:28:31.820: W/System.err(19929):    at                  android.os.Handler.dispatchMessage(Handler.java:102)
08-22 00:28:31.820: W/System.err(19929):    at android.os.Looper.loop(Looper.java:136)

1 个答案:

答案 0 :(得分:0)

看看你的php代码,你的响应似乎不是一个数组,它应该是一个JSONObject,总是在解析之前记录数据并检查对象图:

Log.d("mylog", "json = " + response.toString());

像这样更改你的php:

<?php
$response = array():

if(isset($_POST['usersJSON'])){

try {
    $json = $_POST["usersJSON"];
    include_once './db_functions.php';
    $db = new DB_Functions(); 

    if (get_magic_quotes_gpc()){
        $json = stripslashes($json);  
    }

    //pass true to json_decode
    $records = json_decode($json, true);

    $data = array();
    foreach($records as $record){
        $res = $db->storeUser($data['userName'],$data['userEmail'],$data['userPhno']);
        $data['name'] = $record['userName'];
        $data['name'] = $res ? 'yes' : 'no';
        array_push($response['data'], $data);   
    }
    $response['success'] = true;
} catch (Exception $e) {
    $response['success'] = false;
    $respnose['message'] = $e->getMessage();
}


}else{
    $response['success'] = false;
    $respnose['message'] = 'missing JSON data';

}

echo json_encode($response); 

这样你总会得到一个回复​​,如果没有输入循环,你的方式就不会给你回复