2015-07-09 7 views
2

особенно, очень новый в android, и не знаю, хорошо его отладить. проблема возникает, когда я нажимаю кнопку обновления, ничего не происходит, вместо этого она должна показывать реальные данные, она продолжает показывать поддельные данные. logcat говорит, что файл не существует, не удалось найти ошибки здесь. вот мой кодприложение sunshine дает filenotfoundexception, когда я нажимаю кнопку обновления

Основная деятельность

package com.example.android.sunshine.app; 

import android.annotation.TargetApi; 
import android.support.v4.app.Fragment; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.TextView; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 


public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    /** if (savedInstanceState == null){ 
     getSupportFragmentManager().beginTransaction() 
     .add(R.id.container, new ForecastFragment()) 
     .commit(); 

     }*/ 
    } 


    @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; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     if (id == R.id.action_refresh){ 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

forecastFragment

package com.example.android.sunshine.app; 

import android.net.*; 
import android.os.*; 
import android.support.v4.app.*; 
import android.text.format.*; 
import android.util.*; 
import android.view.*; 
import android.widget.*; 

import org.json.*; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 


/** 
* Created by Nabahat on 7/8/2015. 
*/ 
public class ForecastFragment extends Fragment { 

    private ArrayAdapter<String> mForecastAdapter; 
    public ForecastFragment(){} 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ 
     inflater.inflate(R.menu.forecastfragment, menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item){ 
     int id = item.getItemId(); 
     if (id==R.id.action_refresh){ 
      FetchWeatherTask weatherTask = new FetchWeatherTask(); 
      weatherTask.execute("94043"); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
     String[] forecastArray = { 
       "Today - Sunny - 88/63", 
       "Tomorrow - Foggy - 70/40", 
       "Weds - Cloudy - 72/63", 
       "Thurs - Asteroids - 75/65", 
       "Fri - Heavy Rain - 65/56", 
       "Sat - HELP TRAPPED IN WEATHERSTATION - 60/51", 
       "Sun - Sunny - 80/68" 
     }; 

     List<String> weekForecast = new ArrayList<String>(
       Arrays.asList(forecastArray)); 

     ArrayAdapter<String> mForecastAdapter = new ArrayAdapter<String>(
       getActivity(), 
       R.layout.list_item_forecast, 
       R.id.list_item_forecast_textview, 
       weekForecast); 
     ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast); 
     listView.setAdapter(mForecastAdapter); 

     return rootView; 
    } 

    public class FetchWeatherTask extends AsyncTask<String, Void, String[]> { 

     private final String LOG_TAG = FetchWeatherTask.class.getSimpleName(); 

     /* The date/time conversion code is going to be moved outside the asynctask later, 
    * so for convenience we're breaking it out into its own method now. 
    */ 
     private String getReadableDateString(long time){ 
      // Because the API returns a unix timestamp (measured in seconds), 
      // it must be converted to milliseconds in order to be converted to valid date. 
      SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd"); 
      return shortenedDateFormat.format(time); 
     } 

     /** 
     * Prepare the weather high/lows for presentation. 
     */ 
     private String formatHighLows(double high, double low) { 
      // For presentation, assume the user doesn't care about tenths of a degree. 
      long roundedHigh = Math.round(high); 
      long roundedLow = Math.round(low); 

      String highLowStr = roundedHigh + "/" + roundedLow; 
      return highLowStr; 
     } 

     /** 
     * Take the String representing the complete forecast in JSON Format and 
     * pull out the data we need to construct the Strings needed for the wireframes. 
     * 
     * Fortunately parsing is easy: constructor takes the JSON string and converts it 
     * into an Object hierarchy for us. 
     */ 
     private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays) 
       throws JSONException { 

      // These are the names of the JSON objects that need to be extracted. 
      final String OWM_LIST = "list"; 
      final String OWM_WEATHER = "weather"; 
      final String OWM_TEMPERATURE = "temp"; 
      final String OWM_MAX = "max"; 
      final String OWM_MIN = "min"; 
      final String OWM_DESCRIPTION = "main"; 

      JSONObject forecastJson = new JSONObject(forecastJsonStr); 
      JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST); 

      // OWM returns daily forecasts based upon the local time of the city that is being 
      // asked for, which means that we need to know the GMT offset to translate this data 
      // properly. 

      // Since this data is also sent in-order and the first day is always the 
      // current day, we're going to take advantage of that to get a nice 
      // normalized UTC date for all of our weather. 

      Time dayTime = new Time(); 
      dayTime.setToNow(); 

      // we start at the day returned by local time. Otherwise this is a mess. 
      int julianStartDay = Time.getJulianDay(System.currentTimeMillis(), dayTime.gmtoff); 

      // now we work exclusively in UTC 
      dayTime = new Time(); 

      String[] resultStrs = new String[numDays]; 
      for(int i = 0; i < weatherArray.length(); i++) { 
       // For now, using the format "Day, description, hi/low" 
       String day; 
       String description; 
       String highAndLow; 

       // Get the JSON object representing the day 
       JSONObject dayForecast = weatherArray.getJSONObject(i); 

       // The date/time is returned as a long. We need to convert that 
       // into something human-readable, since most people won't read "1400356800" as 
       // "this saturday". 
       long dateTime; 
       // Cheating to convert this to UTC time, which is what we want anyhow 
       dateTime = dayTime.setJulianDay(julianStartDay+i); 
       day = getReadableDateString(dateTime); 

       // description is in a child array called "weather", which is 1 element long. 
       JSONObject weatherObject = dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0); 
       description = weatherObject.getString(OWM_DESCRIPTION); 

       // Temperatures are in a child object called "temp". Try not to name variables 
       // "temp" when working with temperature. It confuses everybody. 
       JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE); 
       double high = temperatureObject.getDouble(OWM_MAX); 
       double low = temperatureObject.getDouble(OWM_MIN); 

       highAndLow = formatHighLows(high, low); 
       resultStrs[i] = day + " - " + description + " - " + highAndLow; 
      } 
      for (String s : resultStrs){ 
       Log.v(LOG_TAG, "Forecast entry: " + s); 
      } 
      return resultStrs; 
     } 
     @Override 
     protected String[] doInBackground(String... params){ 

      if(params.length == 0){ 
       return null; 
      } 

      HttpURLConnection urlConnection = null; 
      BufferedReader reader = null; 
      String forecastJsonStr = null; 

      String format = "jason"; 
      String units = "metric"; 
      int numDays = 7; 

      try { 

       final String FORECAST_BASE_URL = 
         "http://api.openweathermap.org/data/2.5/forecast/daily?"; 
       final String QUERY_PARAM = "q"; 
       final String FORMAT_PARAM = "mode"; 
       final String UNITS_PARAM = "units"; 
       final String DAYS_PARAM = "cnt"; 

       Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon() 
         .appendQueryParameter(QUERY_PARAM, params[0]) 
         .appendQueryParameter(FORMAT_PARAM, format) 
         .appendQueryParameter(UNITS_PARAM, units) 
         .appendQueryParameter(DAYS_PARAM, Integer.toString(numDays)) 
         .build(); 

       URL url = new URL(builtUri.toString()); 

       Log.v(LOG_TAG, "Built URI " + builtUri.toString()); 

       urlConnection = (HttpURLConnection) url.openConnection(); 
       urlConnection.setRequestMethod("GET"); 
       urlConnection.setRequestProperty("API_KEY", "c84aeef73dfe54e9ec696154cfb89a5a"); 
       urlConnection.setDoInput(true); 
       urlConnection.setDoOutput(true); 
       urlConnection.connect(); 

       InputStream inputStream = urlConnection.getInputStream(); 
       StringBuffer buffer = new StringBuffer(); 
       if (inputStream == null) { 
        return null; 
       } 
       reader = new BufferedReader(new InputStreamReader(inputStream)); 

       String line; 
       while ((line = reader.readLine()) != null) { 
        buffer.append(line + "\n"); 
       } 

       if (buffer.length() == 0) { 
        return null; 
       } 
       forecastJsonStr = buffer.toString(); 
       Log.v(LOG_TAG, "Forecast JSON String: "+ forecastJsonStr); 
      } catch (IOException e) { 
       Log.e(LOG_TAG, "Error ", e); 
       return null; 

      } finally{ 
       if (urlConnection != null) { 
        urlConnection.disconnect(); 
       } 
       if (reader != null) { 
        try { 
         reader.close(); 
        } catch (final IOException e) { 
         Log.e(LOG_TAG, "Error closing stream", e); 
        } 
       } 
      } 
     try{ 
      return getWeatherDataFromJson(forecastJsonStr, numDays); 
     } catch (JSONException e){ 
      Log.e(LOG_TAG, e.getMessage(), e); 
      e.printStackTrace(); 
     } 
     return null; 
     } 
     @Override 
     protected void onPostExecute(String[] result){ 
      if (result != null){ 
       mForecastAdapter.clear(); 
       for (String dayForecastStr : result){ 
        mForecastAdapter.add(dayForecastStr); 
       } 
      } 
     } 
    } 
} 

Logcat

10670-10670/com.example.android.sunshine.app W/art﹕ Before Android 4.1, method int android.support.v7.internal.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView 
07-09 06:12:19.182 10670-10692/com.example.android.sunshine.app W/EGL_emulation﹕ eglSurfaceAttrib not implemented 
07-09 06:12:19.182 10670-10692/com.example.android.sunshine.app W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa5403460, error=EGL_SUCCESS 
07-09 06:12:19.627 10670-10677/com.example.android.sunshine.app W/art﹕ Suspending all threads took: 21.107ms 
07-09 06:12:21.091 10670-10764/com.example.android.sunshine.app V/FetchWeatherTask﹕ Built URI http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=jason&units=metric&cnt=7 
07-09 06:12:21.163 10670-10670/com.example.android.sunshine.app W/InputEventReceiver﹕ Attempted to finish an input event but the input event receiver has already been disposed. 
07-09 06:12:22.087 10670-10764/com.example.android.sunshine.app E/FetchWeatherTask﹕ Error 
    java.io.FileNotFoundException: http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=jason&units=metric&cnt=7 
      at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:206) 
      at com.example.android.sunshine.app.ForecastFragment$FetchWeatherTask.doInBackground(ForecastFragment.java:217) 
      at com.example.android.sunshine.app.ForecastFragment$FetchWeatherTask.doInBackground(ForecastFragment.java:75) 
      at android.os.AsyncTask$2.call(AsyncTask.java:292) 
      at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
      at java.lang.Thread.run(Thread.java:818) 
07-09 06:12:31.513 10670-10677/com.example.android.sunshine.app W/art﹕ Suspending all threads took: 8.898ms 

ответ

0

Исходя из вашего журнала, такие же проблема была решена путем проверки ответа, добавив этот код две строки

urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 (compatible) "); 
urlConnection.setRequestProperty("Accept","*/*"); 

и установить

urlConnection.setDoOutput(false); 

Вы можете обратиться к этим двум ответам:

HttpURLConnection java.io.FileNotFoundException

FileNotFoundException while getting the InputStream object from HttpURLConnection

+0

все еще не работает для меня – user102303

+0

попробуйте удалить urlConnection.setDoOutput (false); – zzas11

+0

вам нужно добавить urlConnection.setRequestProperty ("API_KEY", "c84aeef73dfe54e9ec696154cfb89a5a"); ? – zzas11

0

Вам необходимо добавить ключ API Open Weather к URL-адресу.

Смежные вопросы