1

在我的 android 应用程序中,我使用 OpenWeatherMap 服务,我是 android 的新手。我将 JSON 日期解析到我的应用程序屏幕,但我对 SQLite 有点困惑,因为我从未使用过它,我使用 Fragment。(我发现的许多教程都与 Activity 相关,有些东西不适用于 Fragment)谁能告诉我正确的方式如何做接下来的事情:

1) I want to save date which I parsed to database when network is available.

2) When network is not available take last date from database and show it in screen.

谢谢你的帮助!

WeatherDB.java

public class WeatherDB extends SQLiteOpenHelper {

    public WeatherDB(Context context){
        super(context, "WeatherDB", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table WeatherTable ("+ "cityField text,"
                                                + "updatedField text,"
                                                + "detailsField text"
                                                + "currentTemperatureField text"
                                                + "weatherIcon text"
                                                + "sunrise text"
                                                + "sunset text" + ");");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

WeatherFragment.java

public class WeatherFragment extends Fragment{

    Typeface weatherFont;
    TextView cityField;
    TextView updatedField;
    TextView detailsField;
    TextView currentTemperatureField;
    TextView weatherIcon;
    TextView sunrise;
    TextView sunset;

    Button tButton;

    boolean isCelsius;
    double temp;

    Handler handler;

    WeatherDB weatherDB;

    public WeatherFragment(){
        handler = new Handler();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_weather, container, false);

        //Initialize button
        cityField = (TextView)view.findViewById(R.id.city_field);
        updatedField = (TextView)view.findViewById(R.id.updated_field);
        detailsField = (TextView)view.findViewById(R.id.details_field);
        currentTemperatureField = (TextView)view.findViewById(R.id.temperature_field);
        weatherIcon = (TextView)view.findViewById(R.id.weather_icon);
        sunrise = (TextView)view.findViewById(R.id.sunrise);
        sunset = (TextView)view.findViewById(R.id.sunset);

        //tButton = Change to ºC and ºF buttons
        tButton = (Button)view.findViewById(R.id.temp_toggle_button);
        tButton.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if( isCelsius ) {
                    // convert temp to Fahrenheit
                    temp = (temp * ((double) 9/5)) + 32;
                    currentTemperatureField.setText(String.format("%.2f ºF", temp));

                    tButton.setText(R.string.button_celsius);
                    isCelsius = false;
                } else {
                    // convert temp to Celsius
                    temp = (temp - 32) * ((double) 5/9);
                    currentTemperatureField.setText(String.format("%.2f ºC", temp));

                    tButton.setText(R.string.button_fahrenheit);
                    isCelsius = true;
                }
            }
        });

        weatherIcon.setTypeface(weatherFont);

        setHasOptionsMenu(true);

        weatherDB = new WeatherDB(getActivity());

        return view;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        weatherFont = Typeface.createFromAsset(getActivity().getAssets(), "fonts/weather.ttf");
        updateWeatherData(new CityPreference(getActivity()).getCity());
    }

    /*----------------------------------------------------------------------------------------------
     * Method: updateWeatherData( final String city)
     * Parameter: final String city: city that will be looked for in the Open Weather Maps API
     * Description: Creates the thread used by renderWeather to update the weather data
     * ---------------------------------------------------------------------------------------------
     */
    private void updateWeatherData(final String city){
        new Thread(){
            public void run(){
                final JSONObject json = RemoteFetch.getJSON(getActivity(), city);
                if(json == null){
                    handler.post(new Runnable(){
                        public void run(){
                            Toast.makeText(getActivity(), getActivity().getString(R.string.place_not_found), Toast.LENGTH_LONG).show();
                        }
                    });
                } else {
                    handler.post(new Runnable(){
                        public void run(){
                            renderWeather(json);
                        }
                    });
                }
            }
        }.start();
    }

    /*
     * ---------------------------------------------------------------------------------------------
     * Method: renderWeather
     * Parameter: - JSONObject json: object containing the weather data from Open Weather Map's API
     * Description: Uses the inputted JSONObject to write the relevant weather data to the text
     * views.
     * ---------------------------------------------------------------------------------------------
     */
    private void renderWeather(JSONObject json){
        try {
            cityField.setText(json.getString("name").toUpperCase(Locale.US) +
                    ", " +
                    json.getJSONObject("sys").getString("country"));

            JSONObject details = json.getJSONArray("weather").getJSONObject(0);
            JSONObject main = json.getJSONObject("main");
            detailsField.setText(
                    details.getString("description").toUpperCase(Locale.US) +
                            "\n" + "Humidity: " + main.getString("humidity") + "%" +
                            "\n" + "Pressure: " + main.getString("pressure") + " hPa");

            currentTemperatureField.setText(String.format("%.2f", main.getDouble("temp"))+ "ºC");
            temp = main.getDouble("temp");
            isCelsius = true;

            DateFormat df = DateFormat.getDateTimeInstance();
            String updatedOn = df.format(new Date(json.getLong("dt")*1000));
            updatedField.setText("Last update: " + updatedOn);

            setWeatherIcon(details.getInt("id"), json.getJSONObject("sys").getLong("sunrise") * 1000, json.getJSONObject("sys").getLong("sunset") * 1000);

            //Sunrise
            String javaTimestampSunrise = new SimpleDateFormat("HH:mm").format(new Date(json.getJSONObject("sys").getLong("sunrise")*1000L));
            sunrise.setText("Sunrise\n " + javaTimestampSunrise);
            //Sunset
            String javaTimestampSunset = new SimpleDateFormat("HH:mm").format(new Date(json.getJSONObject("sys").getLong("sunset")*1000L));
            sunset.setText("Sunset\n " + javaTimestampSunset);

        }catch(Exception e){
            Log.e("SimpleWeather", "One or more fields not found in the JSON data");
        }
    }

    /*----------------------------------------------------------------------------------------------
     * Method: setWeatherIcon(int actualId, long sunrise, long sunset)
     * Parameters: - int actualId: Open Weather Map's id for the inputted weather condition
     *             - long sunrise: The time when the sunrise occurs in the inputted city
     *             - long sunset: The time when the sunset occurs in the inputted city
     * Description: Called by renderWeather to set the weather icon (in the main/assets/fonts
     * folder) based on the current time of day and weather conditions.
     *----------------------------------------------------------------------------------------------
     */
    private void setWeatherIcon(int actualId, long sunrise, long sunset){
        int id = actualId / 100;
        String icon = "";
        if(actualId == 800){
            long currentTime = new Date().getTime();
            if(currentTime>=sunrise && currentTime<sunset) {
                icon = getActivity().getString(R.string.weather_sunny);
            } else {
                icon = getActivity().getString(R.string.weather_clear_night);
            }
        } else {
            switch(id) {
                case 2 : icon = getActivity().getString(R.string.weather_thunder);
                    break;
                case 3 : icon = getActivity().getString(R.string.weather_drizzle);
                    break;
                case 7 : icon = getActivity().getString(R.string.weather_foggy);
                    break;
                case 8 : icon = getActivity().getString(R.string.weather_cloudy);
                    break;
                case 6 : icon = getActivity().getString(R.string.weather_snowy);
                    break;
                case 5 : icon = getActivity().getString(R.string.weather_rainy);
                    break;
            }
        }
        weatherIcon.setText(icon);
    }

    /*
     * ---------------------------------------------------------------------------------------------
     * Method: updateWeatherData(final String city)
     * Parameter: String city: The city that will the search will be changed to
     * Description: Calls updateWeather(city) to change the weather information in the View to the
     * specified city's weather information.
     * ---------------------------------------------------------------------------------------------
    */
    public void changeCity(String city){
        new CityPreference(getActivity()).setCity(city);
        updateWeatherData(city);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_weather, menu);
        MenuItem item = menu.findItem(R.id.change_city);
        item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.change_city:
                        showInputDialog();
                        //Your stuff
                        break;

                }
                return false;
            }

        });
        super.onCreateOptionsMenu(menu, inflater);
    }

    /*
     * ---------------------------------------------------------------------------------------------
     * Method: showInputDialog():
     * Description: Creates the "Change City" option on the Action Bar
     * ---------------------------------------------------------------------------------------------
     */
    private void showInputDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        LayoutInflater inflater = getActivity().getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_city_weather, null);
        builder.setView(dialogView);

        final EditText input = (EditText) dialogView.findViewById(R.id.input_location);
        input.setInputType(InputType.TYPE_CLASS_TEXT);

        builder.setPositiveButton("GET STARTED", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                changeCity(input.getText().toString());
            }
        });
        builder.show();
    }
}
4

0 回答 0