eclipse Android JSON 从 PHP 获取数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15736181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android JSON get data from PHP
提问by Shawn Gavett
Does anyone have any idea what I am doing wrong? I tried doing just about every example out there. I just want to get the lat and lon coords from the server using php to my android phone.
有谁知道我做错了什么?我试着做几乎所有的例子。我只想使用 php 从服务器获取经纬度坐标到我的 android 手机。
Thank you for your help in advanced
感谢您的高级帮助
This is the Section of my code which I am having problems with:
这是我遇到问题的代码部分:
public void connect()
{
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet("SERVER URL");
// Execute the request
HttpResponse response;
try {
response = httpclient.execute(httpget);
// Examine the response status
//Log.i("Info",response.getStatusLine().toString()); Comes back with HTTP/1.1 200 OK
// Get hold of the response entity
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result= convertStreamToString(instream);
JSONArray arr = new JSONArray(result);
JSONObject jObj = arr.getJSONObject(0);
String lat = jObj.getString("Lat");
Log.d("OutPut", jObj.getString("Lon"));
Toast.makeText(this, lat, Toast.LENGTH_LONG).show();
instream.close();
}
} catch (Exception e) {
Log.e("Error",e.toString());
}
}
I cannot get the data out of the JSONObject. I keep getting this exception.
我无法从 JSONObject 中获取数据。我不断收到此异常。
03-31 17:23:41.457: E/Error(317): org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONArray
The PHP code from my server is outputting:
我服务器上的 PHP 代码正在输出:
[{"Lat":"47.9255072","Lon":"-97.0846979","id":"34"}]
Here is all the code in my MainActivity
这是我的 MainActivity 中的所有代码
package com.misterbusllc.misterbusllc;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.os.StrictMode;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.widget.SlidingDrawer;
import android.widget.SlidingDrawer.OnDrawerCloseListener;
import android.widget.SlidingDrawer.OnDrawerOpenListener;
import android.widget.Toast;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connect();
//contactServer();
final SlidingDrawer slidingDrawerCost = (SlidingDrawer) findViewById(R.id.slidingDrawerCost);
final SlidingDrawer slidingDrawerInfo = (SlidingDrawer) findViewById(R.id.slidingDrawerInfo);
GoogleMap map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
LatLng latLng = new LatLng(47.922612,-97.060776);
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
map.addMarker(new MarkerOptions().position(latLng).title("MisterBus").snippet("MisterBus is currently here").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
map.getUiSettings().setCompassEnabled(true);
map.getUiSettings().setZoomControlsEnabled(true);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10));
slidingDrawerCost.setOnDrawerOpenListener(new OnDrawerOpenListener() {
@Override
public void onDrawerOpened() {
Intent intent = new Intent(getApplicationContext(), Cost.class);
startActivity(intent);
}
});
slidingDrawerCost.setOnDrawerCloseListener(new OnDrawerCloseListener() {
@Override
public void onDrawerClosed() {
slidingDrawerCost.close();
}
});
slidingDrawerInfo.setOnDrawerOpenListener(new OnDrawerOpenListener() {
@Override
public void onDrawerOpened() {
Intent intent = new Intent(getApplicationContext(), info.class);
startActivity(intent);
}
});
slidingDrawerInfo.setOnDrawerCloseListener(new OnDrawerCloseListener() {
@Override
public void onDrawerClosed() {
slidingDrawerInfo.close();
}
});
}
@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;
}
public void connect()
{
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet("SERVER URL");
// Execute the request
HttpResponse response;
try {
response = httpclient.execute(httpget);
// Examine the response status
//Log.i("Info",response.getStatusLine().toString()); Comes back with HTTP/1.1 200 OK
// Get hold of the response entity
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result= convertStreamToString(instream);
JSONArray arr = new JSONArray(result);
JSONObject jObj = arr.getJSONObject(0);
String lat = jObj.getString("Lat");
Log.d("OutPut", jObj.getString("Lon"));
Toast.makeText(this, lat, Toast.LENGTH_LONG).show();
instream.close();
}
} catch (Exception e) {
Log.e("Error",e.toString());
}
}
private static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}//end of class
PHP CODE:
代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset=utf-8" http-equiv="Content-Type" content="application/json"; />
<title>Gps Send</title>
</head>
<body>
<?php
header('Content-type: application/json');
mysql_connect("localhost", "root","password");
mysql_select_db("misterbus");
$last =mysql_query("SELECT * FROM location WHERE ID = (SELECT MAX(id) FROM location)");
while($row=mysql_fetch_assoc($last))
$output[]=$row;
print(json_encode($output));
mysql_close();
?>
</body>
</html>
回答by edwardmp
Your PHP page contains HTML tags:
您的 PHP 页面包含 HTML 标签:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Gps Send</title>
</head>
<body>
[{"Lat":"47.9255072","Lon":"-97.0846979","id":"34"}]
</body>
</html>
Therefore, the error you are getting is because Android doesn't understand the response correctly (it assumes pure JSON, not HTML). You need to remove the HTML tags so the response only contains the pure JSON.
因此,您得到的错误是因为 Android 无法正确理解响应(它假定纯 JSON,而不是 HTML)。您需要删除 HTML 标记,以便响应仅包含纯 JSON。
You might also want to set a header declaring it of a JSON content-type. You can do that this way:
您可能还想设置一个标头,将其声明为 JSON 内容类型。你可以这样做:
header('Content-type: application/json');
Put this code right after the first <?php
tag, before everything else.
将此代码放在第一个<?php
标签之后,在其他一切之前。
回答by user2288580
Here's a class from my personal project: http://developersfound.com/HttpPostThreadJSon.zipThis class will only work with verb POST but should be easy enough to refactor for use with other verbs.
这是我个人项目中的一个类:http: //developersfound.com/HttpPostThreadJSon.zip这个类只适用于动词 POST,但应该很容易重构以与其他动词一起使用。
package com.DevFound;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHttpResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONTokener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class HttpPostThreadJSon {
private static final int SUCCESS = 1;
private static final int FAILURE = 0;
protected static JSONArray doInBackground(HttpPost HttpPostObj) {
HttpClient HttpClientObj = new DefaultHttpClient();
ProtocolVersion ProtocolVersionObj = new HttpVersion(1, 1);
Integer codeVar = 0;
String ReasonObj = "";
HttpResponse HttpResponseObj = new BasicHttpResponse(ProtocolVersionObj, codeVar, ReasonObj);
try {
HttpResponseObj = HttpClientObj.execute(HttpPostObj);
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder stringBuilder = new StringBuilder();
String line;
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(HttpResponseObj.getEntity().getContent()));
} catch (IOException e) {
e.printStackTrace();
}
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
JSONTokener tokener = new JSONTokener(stringBuilder.toString());
JSONArray result = null;
try {
result = new JSONArray(tokener);
return result;
} catch (JSONException e) {
//e.printStackTrace();
}
return result;
}
}
From the client class you would have to build the post Object with something like:
从客户端类,您必须使用以下内容构建 post 对象:
HttpPostObj = new HttpPost((DGSession.getSessionStr("HttpPost", getBaseContext()) + "login.php"));
回答by dragonhunter09
$last =mysql_query("SELECT * FROM location WHERE ID = (SELECT MAX(id) FROM location)");
$last =mysql_query("SELECT * FROM location WHERE ID = (SELECT MAX(id) FROM location)");
i know this question is solved a long time ago but the mysql query you use isn't the best way to fetch the result. You execute a Select in a Select so it means it will search two times in the location tabel. a much better way would be
我知道这个问题很久以前就已经解决了,但是您使用的 mysql 查询并不是获取结果的最佳方式。您在 Select 中执行 Select,这意味着它将在位置表中搜索两次。更好的方法是
"SELECT * FROM location ORDER BY id DESC LIMIT 1"
“SELECT * FROM location ORDER BY id DESC LIMIT 1”
this would fetch the row with the highest id, the result of both query's is still equal but the execution time of the query with just 1 Select is faster than the query with 2 Select's.
这将获取具有最高 id 的行,两个查询的结果仍然相等,但只有 1 个 Select 的查询的执行时间比具有 2 个 Select 的查询快。