2013-04-01 180 views
1

有沒有人有任何想法我做錯了什麼?我嘗試了幾乎所有的例子。我只想從服務器使用php到我的android手機獲取經緯度。Android JSON從PHP獲取數據

感謝您對高級

你的幫助,這是我的代碼,我與有問題的部分:

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()); 
    } 
} 

我不能得到的數據出來的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 

從我的服務器,PHP代碼輸出:

[{"Lat":"47.9255072","Lon":"-97.0846979","id":"34"}] 

這裏是我的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代碼的所有代碼:

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

你可以發佈的PHP代碼? – hek2mgl

+0

它不會幫助,如果你刪除代碼中的PHP文件的URL,也不會發布您的PHP代碼.. – edwardmp

回答

4

你的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> 

因此,你所得到的錯誤是因爲Android不正確理解響應(它假定純JSON,而不是HTML)。您需要刪除HTML標記,以便響應僅包含純JSON。

您可能還想設置一個標頭,將其聲明爲JSON內容類型。 你能做到這一點是這樣的:

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

將這個代碼的第一<?php標籤之後,一切之前。

+0

可疑任何瀏覽器或應用程序中的任何json解析器將處理html/json混合 – charlietfl

+0

HTML部分是他的實際代碼服務器上,而不是我的,這就是爲什麼我糾正它。下次更好閱讀。 – edwardmp

+1

瞭解...只是詳細說明 – charlietfl

0

下面是我的個人項目中的一個類: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; 
    } 
} 

從客戶端類,你將有什麼樣訂做Post對象:

HttpPostObj = new HttpPost((DGSession.getSessionStr("HttpPost", getBaseContext()) + "login.php")); 
0

$去年=請求mysql_query(「SELECT * FROM位置WHERE ID =(SELECT MAX(ID ) FROM location)「);

我知道這個問題很久以前就解決了,但是您使用的mysql查詢並不是獲取結果的最佳方式。 您在選擇中執行選擇,這意味着它將在位置tabel中搜索兩次。一個更好的辦法是

「SELECT * FROM位置ORDER BY ID DESC LIMIT 1」

這將取最高的ID行,無論是查詢的結果仍然是平等的,但的執行時間只有1選擇的查詢比2選擇的查詢更快。

+0

Gotcha。感謝您的澄清:) –