【问题标题】:How to update weather with onCreate()?如何使用 onCreate() 更新天气?
【发布时间】:2018-01-05 05:31:04
【问题描述】:

我一直在开发一个天气应用程序,我知道它并不完美(我刚开始进行 android 开发),但我不确定如何在每次启动时更新天气信息。我试图将所有内容都保留在 onCreate() 方法中,但它只是“粘”在我刚开始时使用的位置和条件上。

我已经能够使用一个按钮来解决这个问题,当它被按下时,它会获取新的位置和天气状况,但这不是很直观。我想知道如何在应用启动时获得新条件。可能涉及调用 onRestart() 吗?

这是我在应用中的唯一活动:

package com.photonfighterlabs.dropweather;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.ftoslab.openweatherretrieverz.CurrentWeatherInfo;
import com.ftoslab.openweatherretrieverz.OpenWeatherRetrieverZ;
import com.ftoslab.openweatherretrieverz.WeatherCallback;
import com.ftoslab.openweatherretrieverz.WeatherUnitConverter;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class WeatherActivity extends Activity {

    private double lat;
    private double lng;

    private String temp;
    private String icon;

    private TextView tempTextView;
    private TextView cityTextView;
    private TextView conditionsTextView;

    private int LOCATION_PERMISSION_ID = 1001;

    CurrentWeatherInfo currentWeatherInfoF;

    private String city;
    private List<Address> addresses;

    private FusedLocationProviderClient mFusedLocationClient;

    OpenWeatherRetrieverZ retriever;

    ImageView image;

    Geocoder geocoder;

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_weather);

        retriever = new OpenWeatherRetrieverZ(API_KEY); // hidden for obvious reasons, but working


        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        geocoder = new Geocoder(this, Locale.getDefault());

        tempTextView = (TextView) findViewById(R.id.temp_text_view);
        cityTextView = (TextView) findViewById(R.id.city_text_view);
        conditionsTextView = (TextView) findViewById(R.id.conditions_text_view);

        image = (ImageView) findViewById(R.id.conditions_image);






        if (ContextCompat.checkSelfPermission(WeatherActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(WeatherActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_ID);
            return;
        }

        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location != null)
                            lat = location.getLatitude();
                        lng = location.getLongitude();

                        try {
                            addresses = geocoder.getFromLocation(lat, lng, 1);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        if (!addresses.isEmpty()) {
                            city = addresses.get(0).getLocality();
                            cityTextView.setText("Current Weather - " + city);
                            Log.d("City", city);
                        }

                        Log.d("LAT", String.valueOf(lat));
                        Log.d("LNG", String.valueOf(lng));
                    }
                });

        retriever.updateCurrentWeatherInfo(lat, lng, new WeatherCallback() {
            @Override
            public void onReceiveWeatherInfo(CurrentWeatherInfo currentWeatherInfo) {
                currentWeatherInfoF = WeatherUnitConverter.convertToImperial(currentWeatherInfo);

            }

            @Override
            public void onFailure(String error) {
                Toast.makeText(WeatherActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });

    }

    public void onRetrieveButtonClick(View view) {

        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location != null)
                            lat = location.getLatitude();
                        lng = location.getLongitude();

                        try {
                            addresses = geocoder.getFromLocation(lat, lng, 1);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        if (!addresses.isEmpty()) {
                            city = addresses.get(0).getLocality();
                            cityTextView.setText("Current Weather - " + city);
                            Log.d("City", city);
                        }

                        Log.d("LAT", String.valueOf(lat));
                        Log.d("LNG", String.valueOf(lng));
                    }
                });


        retriever.updateCurrentWeatherInfo(lat, lng, new WeatherCallback() {
            @Override
            public void onReceiveWeatherInfo(CurrentWeatherInfo currentWeatherInfo) {
                currentWeatherInfoF = WeatherUnitConverter.convertToImperial(currentWeatherInfo);

            }

            @Override
            public void onFailure(String error) {
                Toast.makeText(WeatherActivity.this, error, Toast.LENGTH_SHORT).show();
            }
        });

        temp = currentWeatherInfoF.getCurrentTemperature();

        Log.d("TMP : ", String.valueOf(temp));

        tempTextView.setText( String.valueOf((int) Double.parseDouble(temp)) + (char) 0x00B0);
        conditionsTextView.setText(currentWeatherInfoF.getWeatherDescriptionLong());


        String iconURL = currentWeatherInfoF.getWeatherIconLink().toString();

        Pattern p = Pattern.compile("\\d\\w(n|d)");
        Matcher m = p.matcher(iconURL);


        if (m.find()) {
            icon = m.group();
            Log.d("ICON", icon);
            String iconName = "r" + icon;
            image.setImageResource(getResources().getIdentifier(iconName, "drawable", getPackageName()));
            Log.d("NAME", iconName);
        }

    }




}

【问题讨论】:

  • 在恢复方法中每 10 秒调用一次方法
  • 为位置选择创建单独的活动
  • 在 oncreate 中创建一个更新数据的服务。

标签: android android-studio http-get openweathermap


【解决方案1】:

Awareness 提供snapshot-API 用于在设备位置通过getWeather() API 方法获取天气,无需管理位置访问或与从服务器按需查询天气的API 集成。

说明代码-sn-p:

Awareness.SnapshotApi.getWeather(mGoogleApiClient)
  .setResultCallback(new ResultCallback<WeatherResult>() {
    @Override
    public void onResult(@NonNull WeatherResult weatherResult) {
      if (!weatherResult.getStatus().isSuccess()) {
        Log.e(TAG, "Could not get weather.");
        return;
       }
       Weather weather = weatherResult.getWeather();
       Log.i(TAG, "Weather: " + weather);
    }
  });

API返回其实例的Weather类的描述请参考here

使用它的好处是您可以大大简化代码,避免管理位置请求并根据需要经常调用 API(我相信它有缓存以避免过多的网络请求耗尽电池电量)。

【讨论】:

    【解决方案2】:

    你尝试过 onResume() 方法吗?

    你可以使用它,当视图可见时

    【讨论】:

      【解决方案3】:

      getLastLocation()updateCurrentWeatherInfo(...) 都是异步操作。您同时启动它们,这意味着updateCurrentWeatherInfo 很可能会在职位可用之前运行。

      只有在获得位置后才能启动它,例如从onSuccess 侦听器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-30
        • 1970-01-01
        • 2019-08-01
        • 1970-01-01
        • 2014-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多