JSON Parsing работает на Android 4.0, но не на Android <4.0

Возможный дубликат:
Проблема синтаксического анализа JSON

Я разбираю файл JSON (который действителен). Он работает на Android 4.0 – 4.0.4, но не на старых версиях Android. Это часть моего манифеста:

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" /> 

И это мой синтаксический код:

 public JSONObject getJSONFromUrl(String url) { try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader(new InputStreamReader( is, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); json = sb.toString(); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } try { jObj = new JSONObject(json); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } return jObj; } 

И на более старых устройствах появляется следующее сообщение об ошибке (Но, как я уже говорил, на новых устройствах Android):

Org.json.JSONException: значение типа java.lang.String не может быть преобразовано в JSONObject

Я абсолютно не знаю, почему он работает на Android 4, но не на старых устройствах.

Найдите Джсона здесь

Возможно, что парсер JSONObject стал более мягким в новых версиях Android. Сообщение об ошибке, которое вы получаете, похоже, связано с сомнительно-юридическим JSON, особенно на принимающей стороне:

  • Ошибка инициализации JSONObject
  • Проблема синтаксического анализа JSON

Я бы посоветовал вам записать загруженный JSON в файл и сравнить его с вашим оригиналом, чтобы узнать, есть ли проблема с логикой загрузки.


ОБНОВИТЬ

Я не могу воспроизвести вашу проблему. Загрузка JSON из внешнего хранилища отлично работает на Android 4.0.3., 2.3.3, 2.2 и 2.1, используя следующую активность (примечание: я был ленив и жестко подключен к внешнему хранилищу):

 package com.commonsware.jsontest; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import org.json.JSONException; import org.json.JSONObject; public class JSONTestActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { BufferedReader in= new BufferedReader(new FileReader("/mnt/sdcard/test.json")); String str; StringBuilder buf=new StringBuilder(); while ((str=in.readLine()) != null) { buf.append(str); buf.append("\n"); } in.close(); JSONObject json=new JSONObject(buf.toString()); ((TextView)findViewById(R.id.stuff)).setText(json.toString()); } catch (IOException e) { Log.e(getClass().getSimpleName(), "Exception loading file", e); } catch (JSONException e) { Log.e(getClass().getSimpleName(), "Exception parsing file", e); } } } 

Обычно это следующие шаги для создания объекта json через Http-соединение в android.

  1. Откройте соединение и получите ответ.
  2. Получить контент и создать построитель строк.
  3. Сделайте построитель строк в объект массива json (этот шаг вы еще не сделали)
  4. Get json object из объекта json array.

Я думаю, вы пропустили преобразование String Buffer (sb) в объект json-массива. Вместо этого вы напрямую создаете объект json из буфера строк. Я не знаю, как он работал в android 4.0. Модифицированный код

 public JSONObject getJSONFromUrl(String url) { try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader(new InputStreamReader( is, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); json = sb.toString(); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } try { JSONArray jObj = new JSONArray(json); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } return jObj; } 

И вы можете получить json-объект, передав значение индекса, например,

jObj.getJSONObject(i); /*i is a integer, index value*/

Привет, я использовал следующий код, и я не получил никаких ошибок в 2.2, 2.3.3 код очень прост.

 import java.io.IOException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class NannuExpActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { JSONObject jo = getJSONObjectFromUrl("http://pastebin.com/raw.php?i=Jp6Z2wmX"); for(int i=0;i<jo.getJSONArray("map_locations").length();i++) Log.d("Data",jo.getJSONArray("map_locations").getJSONObject(i).getString("title")); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public JSONObject getJSONObjectFromUrl(String url) throws ClientProtocolException, IOException, JSONException{ JSONObject jobj = null; HttpClient hc = new DefaultHttpClient(); HttpGet hGet = new HttpGet(url); ResponseHandler<String> rHand = new BasicResponseHandler(); String resp = ""; resp = hc.execute(hGet,rHand); jobj = new JSONObject(resp); return jobj; } } 

Надеюсь, поможет.

Я использовал следующий код для json, для меня он поддерживает всю версию Android.

 List<NameValuePair> postParameters = new ArrayList<NameValuePair>(); postParameters.add(new BasicNameValuePair("data", qry)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters); HttpPost request = new HttpPost(your url); request.setEntity(formEntity); HttpResponse rp = hc.execute(request); Log.d("UkootLog", "Http status code " + rp.getStatusLine().getStatusCode()); if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK || rp.getStatusLine().getStatusCode() >= 600) { Log.d("JsonLog", "Success !!"); String result = EntityUtils.toString(rp.getEntity()); } else { Log.d("UkootLog", "Failed while request json !!"); } 

Я надеюсь, что это поможет вам.

Решение здесь решит вашу проблему из-за того, что кодировка utf-8 возвращается с сервера.

Проблема синтаксического анализа JSON

Я не очень уверен, почему вы получаете эту ошибку. Но я тоже столкнулся с подобной проблемой, и она была решена путем изменения charSet. Попробуйте использовать iso-8859-1 вместо UTF-8 .

Вы пробовали Джексона? Я использовал его для каждой версии Android, и он работает очень хорошо.

http://jackson.codehaus.org/

Я скопировал ваш код и использовал http://pastebin.com/raw.php?i=Jp6Z2wmX как вход в ваш getJSONFromUrl(String url) . Интересно, что я не смог воспроизвести вашу проблему (с несколькими комбинациями AVD и / или целевого API 15, 10 или 7).

Некоторые вещи, которые я замечаю:

  • InputStream is , String json , JSONObject jObj объявлен внешне для вашего getJSONFromUrl() и есть вероятность, что они каким-то образом по-разному затрагиваются какой-либо другой частью вашего кода при работе на одном API по сравнению с другим.

  • Глядя на исключение, которое вы получили, вполне вероятно, что оно JSONObject из-за того, что входная String для конструктора JSONObject представляет собой пустую строку (""). Возможно ли, что каким-то образом ваш сервер предоставил другие данные вашему старшему Android?

Вот мои предложения:

  • Добавьте следующие строки в начало вашего getJSONFromUrl() :

     InputStream is = null; String json = null; JSONObject jObj = null; 
  • Добавьте строку кода отладки, чтобы распечатать загруженную строку между двумя последними блоками try-catch, например:

     // ----- cut ---- Log.e("Buffer Error", "Error converting result " + e.toString()); } Log.d("getJSONFromUrl", "json=(" + json + ")"); try { jObj = new JSONObject(json); // ----- cut ---- 

Я думаю, что мы узнаем больше о вашей проблеме после того, как вы сделаете одно или оба из вышеперечисленных изменений 🙂

Вы пробовали JSONParser?

Вот пример, который я использую:

  JSONObject json = new JSONObject(); JSONParser jsonParser = new JSONParser(); try { if(jsonString != null) json = (JSONObject) jsonParser.parse(jsonString); } catch (ParseException e) { e.printStackTrace(); } 

Джексон или GSON.

Могут быть немецкие дополнительные символы и проблема интернационализации (i18n) или utf-8.

Я перезапустил Eclipse, сделаю чистую сборку и повторю попытку.

Каков тип переменной json в строке: json = sb.toString();

Это строка? Если это JSONObject , измените его тип на String и ваш код будет работать отлично.


Другим замечанием является обработка исключений. Похоже, что если в первом блоке создается исключение, когда вы строите свою String, инициализация JSONObject будет JSONObject с некоторыми ошибочными данными.


В любом случае попробуйте это (я подозреваю, что ваш метод загрузки не работает):

 public JSONObject getJSONFromUrl(String url) { try { HttpPost postMethod = new HttpPost(SERVER_URL); ResponseHandler<String> res = new BasicResponseHandler(); ResponseHandler<String> res = new ResponseHandler<String>() { public String handleResponse(final HttpResponse response) throws HttpResponseException, IOException { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException( statusLine.getStatusCode(), statusLine.getReasonPhrase()); } HttpEntity entity = response.getEntity(); return entity == null ? null : EntityUtils.toString(entity, "UTF-8"); } }; String response = (new DefaultHttpClient()).execute(postMethod, res); return new JSONObject(json); } catch (Exception e) { e.printStackTrace(); return null; } } 

Конечно, это сработает. В версии 4.0 для Android мы должны создать asynctask, чтобы избежать исключения, т. NetworkOnMainThreadException Получить NetworkOnMainThreadException . Его работа прекрасна для меня.

 public class Http_Get_JsonActivity extends Activity implements OnClickListener { String d = new Date().toString(); private static final String TAG = "MyPost"; private boolean post_is_running = false; private doSomethingDelayed doSth; private String url = "http://192.168.1.1"; private InputStream is; private String json; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button pushButton = (Button) findViewById(R.id.button1); pushButton.setOnClickListener(this); } @Override protected void onPause() { super.onPause(); if (post_is_running) { // stop async task if it's running if app gets // paused Log.v(TAG, "Stopping Async Task onPause"); doSth.cancel(true); } } @Override protected void onResume() { super.onResume(); if (post_is_running) { // start async task if it was running previously and was stopped by // onPause() Log.v(TAG, "Starting Async Task onResume"); doSth = (doSomethingDelayed) new doSomethingDelayed().execute(); // ((Button) findViewById(R.id.push_button)).setText("Resuming.."); } } public void onClick(View v) { if (post_is_running == false) { post_is_running = true; Log.v(TAG, "Starting Async Task onClick"); doSth = (doSomethingDelayed) new doSomethingDelayed().execute(); // ((Button) findViewById(R.id.push_button)).setText("Starting.."); } else { Log.v(TAG, "Stopping Async Task onClick"); post_is_running = false; doSth.cancel(true); // ((Button) findViewById(R.id.push_button)).setText("Stopping.."); } } private class doSomethingDelayed extends AsyncTask<Void, Integer, Void> { private int num_runs = 0; @Override protected Void doInBackground(Void... gurk) { // while (!this.isCancelled()) { Log.v(TAG, "going into postData"); long ms_before = SystemClock.uptimeMillis(); Log.v(TAG, "Time Now is " + ms_before); postData(); Log.v(TAG, "coming out of postData"); publishProgress(num_runs); return null; } @Override protected void onCancelled() { Context context = getApplicationContext(); CharSequence text = "Cancelled BG-Thread"; int duration = Toast.LENGTH_LONG; Toast.makeText(context, text, duration).show(); } @Override protected void onProgressUpdate(Integer... num_runs) { Context context = getApplicationContext(); } } /** * Method to send data to the server */ public void postData() { try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet httpPost = new HttpGet(url); System.out.println("--httppost----" + httpPost); HttpResponse httpResponse = httpClient.execute(httpPost); System.out.println("--httpResponse----" + httpResponse); HttpEntity httpEntity = httpResponse.getEntity(); System.out.println("--httpEntity----" + httpEntity); is = httpEntity.getContent(); System.out.println("--is----" + is); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader(new InputStreamReader( is, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); json = sb.toString(); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } try { JSONArray jObj = new JSONArray(json); System.out.println("--jObjt--" + jObj); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } } } 

наслаждаться..

Intereting Posts
Есть ли способ навсегда скрывать мягкую клавиатуру, но сохранить возможность фокусировки на EditText? Как я могу просматривать видео в видеообъявлениях в определенной позиции? Android – Как сделать диалог прогресса, встроенный в пользовательский интерфейс? Как явным образом отключить режим потоковой передачи для HTTP-соединений в Android? Каков самый быстрый способ для выполнения более чем 64 табличных объединений в SQlite? Должен ли я создавать активность для каждого экрана? Eclipse / Android: «Ошибки, выполняемые застройщиком Android Pre Compiler» в проекте … » Тема Android Holo не включает несколько выпадающих элементов линейки Spinner Android Gapless Audio Looping Android – расчеты с временем, прошедшим в хронометре ANDROID-Не удалось выделить память: 1455 Android & libgdx – отключить размытую визуализацию Автозаполнение логинов в Chrome с помощью AccessibilityService Android Где я могу получить исходный код календаря Android 1.5 и 1.6? Как импортировать формат android.os.bundle в обычные проекты Java?