2016-10-11 42 views
0

我想學習Android Async和json數據解析。我正在使用openweathermap.org API來顯示地點用戶類型的當前天氣。我的應用程序顯示它然而,它不靈活,因爲它顯示所有不同的細節,如天氣描述,緯度,經度,風速,當前溫度..所有在一個單一的字符串,所以它不能重複使用,我們應該做的。假設如果我想在地圖標記上顯示當前溫度的谷歌地圖上的位置,我應該只能得到我想要的在這種情況下當前的溫度和經度和緯度。 我想要這些細節顯示在單獨的文本框。我是Android的初學者。請查看我的代碼,並提供解決方案和指導。如何在Android中單獨顯示openweather地圖數據?

這裏是我的JSONWeatherData.java

public class JSONWeatherData { 
    public static String getData(String weatherJson) throws JSONException { 
     String jsonResult = ""; 
     try { 
      JSONObject JsonObject = new JSONObject(weatherJson); 
      String cod = jsonHelperGetString(JsonObject, "cod"); 
      if(cod != null) { 
       if (cod.equals("200")) { 
        jsonResult += jsonHelperGetString(JsonObject, "name") + "\n"; 
        JSONObject sys = jsonHelperGetJSONObject(JsonObject, "sys"); 
        if (sys != null) { 
         jsonResult += jsonHelperGetString(sys, "country") + "\n"; 
        } 
        jsonResult += "\n"; 
        JSONObject coord = jsonHelperGetJSONObject(JsonObject, "coord"); 
        if(coord != null){ 
         String lon = jsonHelperGetString(coord, "lon"); 
         String lat = jsonHelperGetString(coord, "lat"); 
         jsonResult += "Lon: " + lon + "\n"; 
         jsonResult += "Lat: " + lat + "\n"; 
        } 
        jsonResult += "\n"; 
        JSONArray weather = jsonHelperGetJSONArray(JsonObject, "weather"); 
        if(weather != null){ 
         for(int i=0; i<weather.length(); i++){ 
          JSONObject thisWeather = weather.getJSONObject(i); 
          jsonResult += "Weather " + i + ":\n"; 
          jsonResult += jsonHelperGetString(thisWeather, "main") + "\n"; 
          jsonResult += jsonHelperGetString(thisWeather, "description") + "\n"; 
          jsonResult += "\n"; 
         } 
        } 
        JSONObject main = jsonHelperGetJSONObject(JsonObject, "main"); 
        if(main != null){ 
         jsonResult += "temp: " + jsonHelperGetString(main, "temp") + "\n"; 
         jsonResult += "\n"; 
        } 
        JSONObject wind = jsonHelperGetJSONObject(JsonObject, "wind"); 
        if(wind != null){ 
         jsonResult += "Wind Speed: " + jsonHelperGetString(wind, "speed") + "\n"; 
         jsonResult += "\n"; 
        } 
       } 
       else if(cod.equals("404")){ 
        String message = jsonHelperGetString(JsonObject, "message"); 
        jsonResult += "cod 404: " + message; 
       } 
      } else{ 
       jsonResult += "cod == null\n"; 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
      Log.e(TAG, e.getMessage(), e); 
      jsonResult += e.getMessage(); 
     } 
     return jsonResult; 
    } 
    private static String jsonHelperGetString(JSONObject obj, String k){ 
     String v = null; 
     try { 
      v = obj.getString(k); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return v; 
    } 
    private static JSONObject jsonHelperGetJSONObject(JSONObject obj, String k){ 
     JSONObject o = null; 
     try { 
      o = obj.getJSONObject(k); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return o; 
    } 
    private static JSONArray jsonHelperGetJSONArray(JSONObject obj, String k){ 
     JSONArray a = null; 
     try { 
      a = obj.getJSONArray(k); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return a; 
    } 
} 

主要活動

Public class MainActivity extends Activity { 
    Button btnSubmitCity, btnMap; 
    EditText editCityText; 
    TextView weather_description, current_temp, wind_speed, textViewResult; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     editCityText = (EditText) findViewById(R.id.editCity); 
     btnMap =(Button) findViewById(R.id.mapButton); 
     btnSubmitCity = (Button) findViewById(R.id.submitCity); 
     weather_description = (TextView) findViewById(R.id.weatherDescription); 
     current_temp = (TextView) findViewById(R.id.currentTemp); 
     wind_speed = (TextView) findViewById(R.id.windSpeed); 
     //textViewResult = (TextView)findViewById(R.id.result); 
     textViewResult = (TextView)findViewById(R.id.result); 
     btnMap.setVisibility(View.INVISIBLE); 
     btnMap.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
      } 
     }); 
     btnSubmitCity.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       //editCityText.getText().toString(); 
       //HttpGetTask 
       String cityString = editCityText.getText().toString(); 
       if(TextUtils.isEmpty(cityString)) { 
        Toast.makeText(MainActivity.this, "Enter a place", Toast.LENGTH_LONG).show(); 
        return; 
       } else{ 
        new HttpGetTask(cityString, weather_description).execute(cityString); 
        btnMap.setVisibility(View.VISIBLE); 
       } 
       //String cityString = city.getText().toString(); 
       //new HttpGetTask().execute(); 
       /* 
        new HttpGetTask(
         editCityText.getText().toString(), 
         textViewResult).execute(); 
       */ 
      } 
     }); 
    } 
    private class HttpGetTask extends AsyncTask<String, Void, String> { 
     final String FORECAST_BASE_URL = "http://api.openweathermap.org/data/2.5/weather?"; 
     private static final String TAG = "HttpGetTask"; 
     String cityName; 
     TextView tvResult; 
     HttpGetTask(String cityName, TextView tvResult){ 
      this.cityName = cityName; 
      this.tvResult = tvResult; 
     } 
     @Override 
     protected String doInBackground(String... params){ 
      InputStream in = null; 
      HttpURLConnection httpUrlConnection = null; 
      String result = ""; 
      try { 
       Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon() 
         .appendQueryParameter("q", cityName+",us") // city 
         .appendQueryParameter("mode", "json") // json format as result 
         .appendQueryParameter("units", "imperial") // metric unit 
         .appendQueryParameter("APPID", "Replace with your openweathermap API ID") 
         .build(); 
       URL url = new URL(builtUri.toString()); 
       httpUrlConnection = (HttpURLConnection) url.openConnection(); 
       in = new BufferedInputStream(
         httpUrlConnection.getInputStream()); 
       String data = readStream(in); 
       result = edu.uco.rawal.p6rabina.JSONWeatherData.getData(data); 
      } catch (MalformedURLException exception) { 
       Log.e(TAG, "MalformedURLException"); 
      } catch (IOException exception) { 
       Log.e(TAG, "IOException"); 
      } catch (JSONException e) { 
       Log.e(TAG, e.getMessage(), e); 
       e.printStackTrace(); 
      } finally { 
       if (null != httpUrlConnection) { 
        httpUrlConnection.disconnect(); 
       } 
       if (in != null) { 
        try { 
         in.close(); 
        } catch (final IOException e) { 
         Log.e(TAG, "Error closing stream", e); 
        } 
       } 
     } 
      return result; 
     } 
     @Override 
     protected void onPostExecute(String result) { 
      if (result == null || result == "") { 
       Toast.makeText(MainActivity.this, 
         "Invalid weather data. Possibly a wrong query", 
         Toast.LENGTH_SHORT).show(); 
       return; 
      } else { 
       //btnMap.setVisibility(View.VISIBLE); 
       tvResult.setText(result); 
      } 

     } 
     private String readStream(InputStream in) { 
      BufferedReader reader = null; 
      StringBuffer data = new StringBuffer(""); 
      try { 
       reader = new BufferedReader(new InputStreamReader(in)); 
       String line ; 
       while ((line = reader.readLine()) != null) { 
        data.append(line); 
       } 
      } catch (IOException e) { 
       Log.e(TAG, "IOException"); 
      } finally { 
       if (reader != null) { 
        try { 
         reader.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
      return data.toString(); 
     } 
    } 
} 

此代碼運行和輸出電流的天氣,但它不是reusuable因爲一切都將連接到單個字符串。

回答

2

爲了使它可以重複使用,並且可以方便地訪問每個屬性,那麼如何使包含這些屬性的Weather類以及何時開始解析json,創建它的一個實例並將它們寫到那裏。

例如,而不是僅僅這一點:

String lon = jsonHelperGetString(coord, "lon"); 
String lat = jsonHelperGetString(coord, "lat"); 
jsonResult += "Lon: " + lon + "\n"; 
jsonResult += "Lat: " + lat + "\n"; 
... 

改變某事物,如:

Weather aWeather = new Weather(); 
String lon = jsonHelperGetString(coord, "lon"); 
String lat = jsonHelperGetString(coord, "lat"); 
aWeather.lon = long; 
aWeather.lat = lat; 
... 
return aWeather; 

記住更改返回類型onPostExcute(字符串字符串)到onPostExcute(天氣天氣);

+0

私人類HttpGetTask如何擴展AsyncTask 。我需要改變它嗎?你能否詳細說明一下。我知道的知識有限,因爲我剛剛學習了2-3周的時間。 – robinleathal

+1

我不能解釋所有,但我會盡我所能,給你甜蜜的部分: HttpGetTask延伸的AsyncTask <字符串,太虛,天氣> { 覆蓋 保護天氣doInBackground(虛空...... PARAMS){// 過程解析並返回Weather對象,而不是 } 覆蓋 保護無效onPostExecute(天氣響應){// 現在你可以在這裏操作從響應信息 }} //很抱歉的格式錯誤,基本上你需要調整返回類型從AsyncTask(3rd params)到AsyncTask