问题
UPDATE 4: Problem Solved Check my Answer Below
I am trying to retreive JSON result from PHP Webservice and save it into ListView But I got an errors
I'm not sure what is my mistake could you help me please
I was following this tutorial from Travis (mybringback)
http://www.mybringback.com/tutorial-series/13239/android-mysql-php-json-part-6-json-parsing-and-android-design/
His method (Only on this part) doesn't require any Parameters to get Posts (and it is actually workis using HIS PHP Method) But My web Service Method require 2 Parameters (kioskid (device ID), accesstoken) which are saved in SharedPreferense
Update1:
I modified the Android code also uninstall the old one and start from beginig (Login and so on) until i get to EventListActivity But no List is showing and I got only one error Line in Log (no error message in the device)
Update2: After Modifying the code and separating UpdateJSON() and trying to get JSON Response in doInBackground()
update 3: I Added JSONParse Class
I got a new Error message that I'm getting NullPointerexception at setListAdapter(adapter) inside the method updateList()
this is the error Log:
03-26 16:58:38.397: E/AndroidRuntime(16196): FATAL EXCEPTION: main
03-26 16:58:38.397: E/AndroidRuntime(16196): Process: com.test.event, PID: 16196
03-26 16:58:38.397: E/AndroidRuntime(16196): java.lang.NullPointerException
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.widget.ListView.setAdapter(ListView.java:480)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.app.ListActivity.setListAdapter(ListActivity.java:265)
03-26 16:58:38.397: E/AndroidRuntime(16196): at com.decoder.tapway.event1.EventListActivity.updateList(EventListActivity.java:140)
03-26 16:58:38.397: E/AndroidRuntime(16196): at com.decoder.tapway.event1.EventListActivity.access$3(EventListActivity.java:136)
03-26 16:58:38.397: E/AndroidRuntime(16196): at com.decoder.tapway.event1.EventListActivity$LoadEvents.onPostExecute(EventListActivity.java:221)
03-26 16:58:38.397: E/AndroidRuntime(16196): at com.decoder.tapway.event1.EventListActivity$LoadEvents.onPostExecute(EventListActivity.java:1)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.os.AsyncTask.finish(AsyncTask.java:632)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.os.Handler.dispatchMessage(Handler.java:102)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.os.Looper.loop(Looper.java:136)
03-26 16:58:38.397: E/AndroidRuntime(16196): at android.app.ActivityThread.main(ActivityThread.java:5050)
03-26 16:58:38.397: E/AndroidRuntime(16196): at java.lang.reflect.Method.invokeNative(Native Method)
03-26 16:58:38.397: E/AndroidRuntime(16196): at java.lang.reflect.Method.invoke(Method.java:515)
03-26 16:58:38.397: E/AndroidRuntime(16196): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-26 16:58:38.397: E/AndroidRuntime(16196): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-26 16:58:38.397: E/AndroidRuntime(16196): at dalvik.system.NativeStart.main(Native Method)
this is the PHP function (Yii Framework) that I'm trying to get its JSON result
public function actionEventList(){
if(isset($_POST['kioskid']) && isset($_POST['accesstoken'])){
$response = array();
$kiosk = Kiosk::model()->findByAttributes(array('kioskid'=>$_POST['kioskid'], 'accesstoken'=>$_POST['accesstoken']));
if($kiosk === null){
$response['status'] = '0';
$response['message'] = 'Invalid Kiosk';
} else {
$events = Event::model()->findAllByAttributes(array('createdby'=>$kiosk->userid, 'status'=>'A'));
$list = array();
foreach($events as $row){
$list[] = array('id'=>$row->id, 'name'=>$row->eventname);
}
$response['status'] = '1';
$response['list'] = $list;
}
$this->_sendResponse(200, CJSON::encode($response));
} else {
$this->_sendResponse(400);
}
}
This is my Java code in android: (UPDATED 2)
The Most Important Method is updateJSONdata() that Retrieves recent Events from the server
Then I call that method inside doInBackground()
public class EventListActivity extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
// testing on Server:
private static final String EVENT_LIST_URL = "http://www.XXX.com/XXX/XXX/eventList";
// JSON IDS:
private static final String TAG_STATUS = "status";
private static final String TAG_EVENT_LIST = "list";
private static final String TAG_EVENT_ID = "id";
private static final String TAG_EVENT_NAME = "name";
private static final String TAG_MESSAGE = "message";
// An array of all of our Events
private JSONArray jaEvents = null;
// manages all of our events in a list.
private ArrayList<HashMap<String, String>> arrayEventList;
// prerepare SharedPreferences file name
private static final String PREFS_NAME = "com.MyApp.event";
private SharedPreferences sharedPref ;
String accesstoken, username, kioskid,spKioskid, password ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.event_list_layout);
// setup SharedPreferences file
this.sharedPref = getSharedPreferences(PREFS_NAME,0);
// get data from previous activity
this.accesstoken = sharedPref.getString("accesstoken", null);
this.kioskid = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
Toast.makeText(EventListActivity.this, "onCreate\n"+kioskid, Toast.LENGTH_LONG).show();
Toast.makeText(EventListActivity.this, "onCreate\n"+accesstoken, Toast.LENGTH_LONG).show();
}
@Override
protected void onResume() {
super.onResume();
// assign data from SharedPreferences
this.accesstoken = sharedPref.getString("accesstoken", null);
this.kioskid = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
Toast.makeText(EventListActivity.this, "onResume\n"+kioskid, Toast.LENGTH_LONG).show();
Toast.makeText(EventListActivity.this, "onResume\n"+accesstoken, Toast.LENGTH_LONG).show();
// loading the comments via AsyncTask
new LoadEvents().execute();
}
/**
* Retrieves recent Events from the server.
*/
public void updateJSONdata() {
arrayEventList = new ArrayList<HashMap<String, String>>();
JSONParser jParser = new JSONParser();
JSONObject jsonObj = jParser.getJSONFromUrl(EVENT_LIST_URL);
try {
jaEvents = jsonObj.getJSONArray(TAG_EVENT_LIST);
// looping through all events according to the json object returned
for (int i = 0; i < jaEvents.length(); i++) {
JSONObject c = jaEvents.getJSONObject(i);
// gets the content of each tag
String eventID = c.getString(TAG_EVENT_ID);
String eventName = c.getString(TAG_EVENT_NAME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_EVENT_ID, eventID);
map.put(TAG_EVENT_NAME, eventName);
arrayEventList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Inserts the parsed data into the listview.
*/
private void updateList() {
ListAdapter adapter = new SimpleAdapter(this, arrayEventList,
R.layout.single_event_layout, new String[] { TAG_EVENT_ID, TAG_EVENT_NAME}, new int[] { R.id.event_id, R.id.event_name });
setListAdapter(adapter);
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// do something
}
});
}
public class LoadEvents extends AsyncTask<String, String, String> {
JSONParser jParser = new JSONParser();
// check for success tag
int status;
String accesstoken ;
String kioskid ;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EventListActivity.this);
pDialog.setMessage("Loading Events...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... arg0) {
this.accesstoken = sharedPref.getString("accesstoken", null);
this.kioskid = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
try {
// building parameters for Logout
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("accesstoken", accesstoken));
params.add(new BasicNameValuePair("kioskid", kioskid));
Log.d("request!", "Starting");
// getting product details by HTTPRequest
JSONObject json = jParser.makeHttpRequest(EVENT_LIST_URL,"POST",params);
// checking your log for JSON response
Log.d("Loding Events Attemp", json.toString());
// assign status to JSON "status" tag
status = json.getInt(TAG_STATUS);
if (status == 1){
// print in console success message + JSON response message
Log.d("Events Loaded Successfully",json.toString());
updateJSONdata();
return json.getString(TAG_MESSAGE);
}else{
// print in console failure message + JSON response message
Log.d("Faild loding Events!", json.getString(TAG_MESSAGE));
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
updateList();
}
}
}
Update 3
JSONParser Class
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// making HTTP Request
try {
// Construct the client and the HTTP request.
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
// Execute the POST request and store the response locally.
HttpResponse httpResponse = httpClient.execute(httpPost);
// Extract data from the response.
HttpEntity httpEntity = httpResponse.getEntity();
// Open an inputStream with the data content.
is = httpEntity.getContent();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
// Create a BufferedReader to parse through the inputStream.
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
// Declare a string builder to help with the parsing.
StringBuilder sb = new StringBuilder();
// Declare a string to store the JSON object data in string form.
String line = null;
// Build the string until null.
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
// Close the input stream.
is.close();
// Convert the string builder data to an actual string.
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try to 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;
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String loginUrl, String method,
List<NameValuePair> params) {
// making HTTP Request
try {
// check for request method
if(method == "POST"){
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(loginUrl);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else
// check for request method
if(method == "GET"){
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
loginUrl += "?" + paramString;
HttpGet httpGet = new HttpGet(loginUrl);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException 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 + "\n");
}
is.close();
json = sb.toString();
} catch (IOException e) {
Log.d("Buffer Error","Error Converting Reesult "+e.toString());
}
// try parse the string to JSON Object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error Parsing data" + e.toString());
}
// return JSON String
return jObj;
}
}
single_event_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/post_border_style"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:background="@drawable/post_background_style"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/tapway_event_logo" />
<LinearLayout
android:id="@+id/box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="@+id/event_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingBottom="2dip"
android:paddingLeft="5dp"
android:paddingTop="6dip"
android:textColor="#333"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/event_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="2dip"
android:paddingLeft="8dp"
android:textColor="#888" >
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
event_list_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient" >
<LinearLayout
android:id="@+id/top_layover"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@drawable/blue_gradient"
android:orientation="horizontal" >
<TextView
style="@style/BlackText"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/event_list"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/top_layover"
android:background="#fff"
android:divider="@android:color/transparent"
android:scrollbars="none" />
</RelativeLayout>
回答1:
The error message Value <!DOCTYPE> of type java.lang.String cannot be converted to JSONObject
indicates that you're not getting a JSON response from the server, but a markup document, most probably an error page.
You can either try executing the request outside Android to check whether it's working fine, or you can split your process into two steps:
- Get a text response from the web service into String, and
Log
it. - Parse that String into JSON
That way you will have a log of the response before the parsing fails, so you will have more info.
回答2:
Thanks to everyone for your responses
I found the mistake
Actually It's just an error passing a wrong parameter
in fact it's a mistake in the web server that there are should be 2 kind of access token one for Login and the other for the selected event But when I select an event the implementation change the one that comes with login to event access token
previously I was working on specific Event ID without to finish other things related to events that's why I didn't notice the changes
Now Problem Solved
Long story short The Code Is Correct
thank you again
来源:https://stackoverflow.com/questions/22652537/errors-when-getting-json-result-into-listview