2

Я создаю приложение погоды, и моя текущая проблема заключается в том, что погода обновляется на основе значений по умолчанию для местоположения, а не ждет метода getLocation() для обновления местоположения. Как только я обновляюсь, все работает, но это не то, что я предпочел бы сделать в своем приложении. Вот мой MainActivity.java: Пожалуйста, извините беспорядок. Он скомпилирован из фрагмента кода после фрагмента кода и нуждается в некоторой реорганизации.Обновление местоположения до получения прогноза

package com.nrsmac.stormy.ui; 

import android.content.Context; 
import android.content.Intent; 
import android.location.Address; 
import android.location.Geocoder; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.util.Log; 
import android.view.View; 
import android.widget.ImageView; 
import android.widget.ProgressBar; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.nrsmac.stormy.R; 
import com.nrsmac.stormy.weather.Current; 
import com.nrsmac.stormy.weather.Day; 
import com.nrsmac.stormy.weather.Forecast; 
import com.nrsmac.stormy.weather.Hour; 
import com.squareup.okhttp.Call; 
import com.squareup.okhttp.Callback; 
import com.squareup.okhttp.OkHttpClient; 
import com.squareup.okhttp.Request; 
import com.squareup.okhttp.Response; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.IOException; 
import java.util.List; 
import java.util.Locale; 

import butterknife.ButterKnife; 
import butterknife.InjectView; 
import butterknife.OnClick; 


public class MainActivity extends ActionBarActivity { 

    public static final String TAG = MainActivity.class.getSimpleName(); 

    public static final String DAILY_FORECAST = "DAILY_FORECAST"; 
    public static final String HOURLY_FORECAST = "HOURLY_FORECAST"; 

    //9.927128 -84.082012 San José, Costa Rica 
    private double mLatitude = 0; 
    private double mLongitude = 0; 

    public static String cityName = null; 
    public static int backgroundColor; 

    private Forecast mForecast; 

    @InjectView(R.id.relativeLayout) 
    RelativeLayout mRelativeLayout; 
    @InjectView(R.id.timeLabel) 
    TextView mTimeLabel; 
    @InjectView(R.id.temperatureLabel) 
    TextView mTemperatureLabel; 
    @InjectView(R.id.humidityValue) 
    TextView mHumidityValue; 
    @InjectView(R.id.precipValue) 
    TextView mPrecipValue; 
    @InjectView(R.id.summaryLabel) 
    TextView mSummaryLabel; 
    //@InjectView(R.id.iconImageView) ImageView mIconImageView; 
    @InjectView(R.id.refreshImageView) 
    ImageView mRefreshImageView; 
    @InjectView(R.id.progressBar) 
    ProgressBar mProgressBar; 
    @InjectView(R.id.locationLabel) 
    TextView mLocationLabel; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ButterKnife.inject(this); 

     mProgressBar.setVisibility(View.INVISIBLE); 

     getLocation(); 

     mRefreshImageView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       getForecast(mLatitude, mLongitude); 
      } 
     }); 

     getForecast(mLatitude, mLongitude); 

     Log.d(TAG, "Main UI code is running!"); 
    } 

    public void getLocation() { 
     LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     LocationListener ll = new LocationListener() { 
      @Override 
      public void onLocationChanged(Location location) { 
       if (location != null){ 
        double pLong = location.getLongitude(); 
        double pLat = location.getLatitude(); 

        mLongitude = pLong; 
        mLatitude = pLat; 
       } 


       String longitude = "Longitude: " + location.getLongitude(); 
       Log.v(TAG, longitude); 
       String latitude = "Latitude: " + location.getLatitude(); 
       Log.v(TAG, latitude); 
      /*----------to get City-Name from coordinates ------------- */ 
       Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault()); 
       List<Address> addresses; 
       try { 
        addresses = gcd.getFromLocation(location.getLatitude(), 
          location.getLongitude(), 1); 
        if (addresses.size() > 0) 
         System.out.println(addresses.get(0).getLocality()); 
        cityName = addresses.get(0).getLocality(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       mLocationLabel.setText(cityName); 


      } 


      @Override 
      public void onStatusChanged(String provider, int status, Bundle extras) { 

      } 

      @Override 
      public void onProviderEnabled(String provider) { 

      } 

      @Override 
      public void onProviderDisabled(String provider) { 

      } 
     }; 


//took this to line 123 out to test for gps always on bug, using only line 124 right now 
     //exceptions will be thrown if provider is not permitted. 
     // try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){} 
     //try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){} 


     // if(gps_enabled) { 
     // lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 100, ll); 
     //if(network_enabled) 
     // lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100, 100, ll); 

     // } 
     lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100, 100, ll); 
     // if update broke it, try un-commenting this line, comment out above line? 
     //lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10, 10, ll); 

    } 





    private void getForecast(double latitude, double longitude) { 
     String apiKey = "7a73984cc278e10ed332f1e5d6db96e9"; 

     String forecastUrl = "https://api.forecast.io/forecast/" + apiKey + "/" + latitude + "," + longitude; 

     if (isNetworkAvailable()) { 

      toggleRefresh(); 

      OkHttpClient client = new OkHttpClient(); 
      Request request = new Request.Builder() 
        .url(forecastUrl) 
        .build(); 

      Call call = client.newCall(request); 
      call.enqueue(new Callback() { 
       @Override 
       public void onFailure(Request request, IOException e) { 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          toggleRefresh(); 
         } 
        }); 
        alertUserAboutError(); 
       } 

       @Override 
       public void onResponse(Response response) throws IOException { 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          toggleRefresh(); 
         } 
        }); 

        try { 
         String jsonData = response.body().string(); 
         Log.v(TAG, jsonData); 
         if (response.isSuccessful()) { 
          mForecast = parseForecastDetails(jsonData); 
          runOnUiThread(new Runnable() { 
           @Override 
           public void run() { 
            updateDisplay(); 
           } 
          }); 

         } else { 
          alertUserAboutError(); 
         } 
        } catch (IOException e) { 
         Log.e(TAG, "Exception caught", e); 
        } catch (JSONException e) { 
         Log.e(TAG, "Exception caught", e); 
        } 
       } 
      }); 
     } else { 
      Toast.makeText(this, getString(R.string.network_unavailible_message), 
        Toast.LENGTH_LONG).show(); 
     } 
    } 

    private void toggleRefresh() { 
     getLocation(); 
     if (mProgressBar.getVisibility() == View.INVISIBLE) { 
      mProgressBar.setVisibility(View.VISIBLE); 
      mRefreshImageView.setVisibility(View.INVISIBLE); 
     } 
     else { 
      mProgressBar.setVisibility(View.INVISIBLE); 
      mRefreshImageView.setVisibility(View.VISIBLE); 
     } 

    } 

    private void updateDisplay() { 
     getLocation(); 
     Current current = mForecast.getCurrent(); 
     mTemperatureLabel.setText(current.getTemperature() + " degrees"); 
     mTimeLabel.setText(current.getFormattedTime()); 
     mHumidityValue.setText(current.getHumidity() + ""); 
     mPrecipValue.setText(current.getPrecipChance() + "%"); 
     mSummaryLabel.setText(current.getSummary()); 

//  Drawable drawable = getResources().getDrawable(current.getIconId()); 
//  mIconImageView.setImageDrawable(drawable); 
     backgroundColor = current.getBackgroundColor(); 
     mRelativeLayout.setBackgroundColor(backgroundColor); 

    } 

    private Forecast parseForecastDetails(String jsonData) throws JSONException { 
     Forecast forecast = new Forecast(); 

     forecast.setCurrent(getCurrentDetails(jsonData)); 
     forecast.setHourlyForecast(getHourlyForecast(jsonData)); 
     forecast.setDailyForecast(getDailyForecast(jsonData)); 

     return forecast; 
    } 

    private Day[] getDailyForecast(String jsonData) throws JSONException { 
     JSONObject forecast = new JSONObject(jsonData); 
     String timezone = forecast.getString("timezone"); 
     JSONObject daily = forecast.getJSONObject("daily"); 
     JSONArray data = daily.getJSONArray("data"); 

     Day[] days = new Day[data.length()]; 

     for (int i = 0; i < data.length(); i++) { 
      JSONObject jsonDay = data.getJSONObject(i); 
      Day day = new Day(); 

      day.setSummary(jsonDay.getString("summary")); 
      day.setIcon(jsonDay.getString("icon")); 
      day.setTemperatureMax(jsonDay.getDouble("temperatureMax")); 
      day.setTime(jsonDay.getLong("time")); 
      day.setTimezone(timezone); 

      days[i] = day; 
     } 

     return days; 
    } 

    private Hour[] getHourlyForecast(String jsonData) throws JSONException{ 
     JSONObject forecast = new JSONObject(jsonData); 
     String timezone = forecast.getString("timezone"); 
     JSONObject hourly = forecast.getJSONObject("hourly"); 
     JSONArray data = hourly.getJSONArray("data"); 

     Hour[] hours = new Hour[data.length()]; 

     for (int i = 0; i < data.length(); i++) { 
      JSONObject jsonHour = data.getJSONObject(i); 
      Hour hour = new Hour(); 
      hour.setSummary(jsonHour.getString("summary")); 
      hour.setTemperature(jsonHour.getDouble("temperature")); 
      hour.setIcon(jsonHour.getString("icon")); 
      hour.setTime(jsonHour.getLong("time")); 
      hour.setTimezone(timezone); 

      hours[i] = hour; 
     } 
     return hours; 
    } 

    private Current getCurrentDetails(String jsonData) throws JSONException { 
     JSONObject forecast = new JSONObject(jsonData); 
     String timezone = forecast.getString("timezone"); 
     Log.i(TAG, "From JSON: " + timezone); 

     JSONObject currently = forecast.getJSONObject("currently"); 

     Current current = new Current(); 
     current.setHumidity(currently.getDouble("humidity")); 
     current.setTime(currently.getLong("time")); 
     current.setIcon(currently.getString("icon")); 
     current.setPrecipChance(currently.getDouble("precipProbability")); 
     current.setSummary(currently.getString("summary")); 
     current.setTemperature(currently.getDouble("temperature")); 
     current.setTimeZone(timezone); 

     Log.d(TAG, current.getFormattedTime()); 

     return current; 
    } 

    private boolean isNetworkAvailable() { 
     ConnectivityManager manager = (ConnectivityManager) 
       getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo networkInfo = manager.getActiveNetworkInfo(); 
     boolean isAvailible = false; 
     if (networkInfo != null && networkInfo.isConnected()) { 
      isAvailible = true; 
     } 

     return isAvailible; 
    } 

    private void alertUserAboutError() { 
     AlertDialogFragment dialog = new AlertDialogFragment(); 
     dialog.show(getFragmentManager(), "error_dialog"); 

    } 

    @OnClick (R.id.dailyButton) 
    public void startDailyActivity(View view) { 
     Intent intent = new Intent(this, DailyForecastActivity.class); 
     intent.putExtra(DAILY_FORECAST, mForecast.getDailyForecast()); 
     startActivity(intent); 
    } 

    @OnClick (R.id.hourlyButton) 
    public void startHourlyActivity(View view) { 
     Intent intent = new Intent(this, HourlyForecastActivity.class); 
     intent.putExtra(HOURLY_FORECAST, mForecast.getHourlyForecast()); 
     startActivity(intent); 
    } 

} 

ответ

2

Я сделал вид такой же ваш, мы находимся на той же самой лодке :)

Удалить getForecast() в onCreate. Вам необходимо обновить текущее местоположение, используя Google FusedLocationApi, , потому что это позволяет избежать аварии getLastKnowLocation. Как использовать это, пожалуйста, обратитесь к here, и получите код here.

Затем вам необходимо handleNewLocation (обновить погоду) в onLocationChanged метод.

и образец кода:

@Override 
    public void onLocationChanged(Location location) { 
     handleNewLocation(location); 
    } 

    private void handleNewLocation(Location location) { 
     Log.d(TAG, location.toString()); 

     mLatitude = location.getLatitude(); 
     mLongitude = location.getLongitude(); 
     getForecast(mLatitude, mLongitude); 
     getCityName(); 

    } 

Помните, всегда проверяйте mLongitude != 0 && mLatitude != 0 перед обновлением информации о погоде.

Если вы все еще не можете понять, обратитесь к моему Github here.

0

Удалить звонок, чтобы получить прогноз в onCreate. Это заставит его не пытаться немедленно получить прогноз на основе неправильного местоположения. Вызывается только getForecast после вызова onLocationUpdates, поэтому у вас есть правильное местоположение.