简体   繁体   English

Android JSON从PHP获取数据

[英]Android JSON get data from PHP

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手机获得lat和lon coords。

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. 我无法从JSONObject中获取数据。 I keep getting this exception. 我一直得到这个例外。

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: PHP代码:

<!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>

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). 因此,您得到的错误是因为Android无法正确理解响应(它假定纯JSON,而不是HTML)。 You need to remove the HTML tags so the response only contains the pure JSON. 您需要删除HTML标记,以便响应仅包含纯JSON。

You might also want to set a header declaring it of a JSON content-type. 您可能还想设置一个标头,声明它是JSON内容类型。 You can do that this way: 你可以这样做:

header('Content-type: application/json');

Put this code right after the first <?php tag, before everything else. 将此代码放在第一个<?php标记之后,在其他所有标记之前。

Here's a class from my personal project: http://developersfound.com/HttpPostThreadJSon.zip This 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"));

$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. 我知道很久以前这个问题已经解决了,但你使用的mysql查询并不是获取结果的最佳方法。 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 一个更好的方法

"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的查询的执行时间快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM