文档章节

Android学习--14-天气练习

ssnoodles
 ssnoodles
发布于 2016/10/28 14:07
字数 2826
阅读 75
收藏 1

听说郭大的此系列的第二本快要出版了。

首先我们要做一个app需要实现哪些功能?

  1. 省、市、县的显示
  2. 以上是可选的
  3. 查看某地区的天气
  4. 提供手动更新天气和自动更新

由于书中提供的天气地址已经过时,基本不能用。天气更新基本就失效了。 所以我找了一个 和风天气api 注册下有每天有3000次免费试用

省 市 县数据,整理了sql 项目地址

包结构

  • activity 活动
  • db 操作数据的
  • model 数据模型
  • util 工具类
  • service 服务
  • receiver 接收

初始化数据

  1. Province City County 三个sql脚本放入 assets 文件夹下
  2. 创建表结构
  3. 插入表数据

怎么玩?

  1. extends SQLiteOpenHelper
  2. onCreate() 方法中执行一系列操作
public class DbHelper extends SQLiteOpenHelper{

    private static final String TAG = DbHelper.class.getSimpleName();

    public static final String DB_NAME = "weather.db";

    private Context mContext;

    public DbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    /**
     * Province表建表语句
     */
    public static final String CREATE_PROVINCE = "create table Province ("
            + "id integer primary key autoincrement, "
            + "province_name text, "
            + "province_code text)";
    /**
     * City表建表语句
     */
    public static final String CREATE_CITY = "create table City ("
            + "id integer primary key autoincrement, "
            + "city_name text, "
            + "city_code text, "
            + "province_code text)";
    /**
     * County表建表语句
     */
    public static final String CREATE_COUNTY = "create table County ("
            + "id integer primary key autoincrement, "
            + "county_name text, "
            + "county_code text, "
            + "city_code text)";

    @Override
    public void onCreate(SQLiteDatabase db) {

        // 创建表
        db.execSQL(CREATE_PROVINCE); // 创建Province表
        db.execSQL(CREATE_CITY); // 创建City表
        db.execSQL(CREATE_COUNTY); // 创建County表

        // 初始化数据
        executeAssetsSQL(db, "Province.sql");
        executeAssetsSQL(db, "City.sql");
        executeAssetsSQL(db, "County.sql");

        Log.d(TAG, "init city data success!!!");
    }

    /**
     * 读取数据库文件(.sql),并执行sql语句
     * */
    private void executeAssetsSQL(SQLiteDatabase db, String sqlFileName) {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(mContext.getAssets().open(sqlFileName)));

            String line;
            while ((line = in.readLine()) != null) {
                db.execSQL(line);
            }
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        } finally {
            try {
                if (in != null)
                    in.close();
            } catch (IOException e) {
                Log.e(TAG, e.toString());
            }
        }
    }

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

读取sqlite数据

实体

set... get... 就省了

// 省
public class Province {
    private int id;
    private String provinceName;
    private String provinceCode;
}
// 市
public class City {
    private int id;
    private String cityName;
    private String cityCode;
    private String provinceCode; // 对应省
}
// 县
public class County {
    private int id;
    private String countyName;
    private String countyCode;
    private String cityCode; //对应市
}

查询操作

封装到 WeatherDb

public class WeatherDb {

    public static final int VERSION = 1;

    private SQLiteDatabase db;

    private static WeatherDb weatherDb;

    // 单例
    private WeatherDb(Context context) {
        DbHelper dbHelper = new DbHelper(context, DbHelper.DB_NAME, null, VERSION);
        db = dbHelper.getWritableDatabase();
    }

    /**
     * 获取 实例
     * @param context
     * @return
     */
    public synchronized static WeatherDb getInstance(Context context) {
        if (weatherDb == null) {
            weatherDb = new WeatherDb(context);
        }
        return weatherDb;
    }

    /**
     * 从数据库读取全国所有的省份信息。
     */
    public List<Province> loadProvinces() {
        List<Province> list = new ArrayList<Province>();
        Cursor cursor = db.query("Province", null, null, null, null, null, "province_code asc");
        if (cursor.moveToFirst()) {
            do {
                Province province = new Province();
                province.setId(cursor.getInt(cursor.getColumnIndex("id")));
                province.setProvinceName(cursor.getString(cursor
                        .getColumnIndex("province_name")));
                province.setProvinceCode(cursor.getString(cursor.getColumnIndex("province_code")));
                list.add(province);
            } while (cursor.moveToNext());
        }
        cursor.close();
        return list;
    }

    /**
     * 从数据库读取某省下所有的城市信息。
     */
    public List<City> loadCities(String provinceCode) {
        List<City> list = new ArrayList<City>();
        Cursor cursor = db.query("City", null, "province_code = ?",
                new String[] { provinceCode }, null, null, null);
        if (cursor.moveToFirst()) {
            do {
                City city = new City();
                city.setId(cursor.getInt(cursor.getColumnIndex("id")));
                city.setCityName(cursor.getString(cursor
                        .getColumnIndex("city_name")));
                city.setCityCode(cursor.getString(cursor
                        .getColumnIndex("city_code")));
                city.setProvinceCode(provinceCode);
                list.add(city);
            } while (cursor.moveToNext());
        }
        cursor.close();
        return list;
    }

    /**
     * 从数据库读取某城市下所有的县信息。
     */
    public List<County> loadCounties(String cityCode) {
        List<County> list = new ArrayList<County>();
        Cursor cursor = db.query("County", null, "city_code = ?",
                new String[] { cityCode }, null, null, null);
        if (cursor.moveToFirst()) {
            do {
                County county = new County();
                county.setId(cursor.getInt(cursor.getColumnIndex("id")));
                county.setCountyName(cursor.getString(cursor
                        .getColumnIndex("county_name")));
                county.setCountyCode(cursor.getString(cursor
                        .getColumnIndex("county_code")));
                county.setCityCode(cityCode);
                list.add(county);
            } while (cursor.moveToNext());
        }
        cursor.close();
        return list;
    }

}

HttpUtil

用 URL 也好 , HttpClient 也行。

选择地区

布局

choose_area.xml

  1. 显示标题 选择的地方 TextView
  2. 显示列表 ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#484E61">

        <TextView
            android:id="@+id/title_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textColor="#fff"
            android:textSize="24sp"/>

    </RelativeLayout>

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

</LinearLayout>

地区活动

为了识别 在哪一层级,是 省呢,还是市呢,还是县呢? 定义三个常量:

public static final int LEVEL_PROVINCE = 0;
public static final int LEVEL_CITY = 1;
public static final int LEVEL_COUNTY = 2;

然后得知道当前到底是哪个被选择了呢?

  /**
     * 当前选中的级别
     */
 private int currentLevel;
 /**
     * 当前列表数据
     */
private List<String> dataList = new ArrayList<String>();

主要代码 ChooseAreaActivity

  ... 省略变量

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.choose_area);

        titleView = (TextView) findViewById(R.id.title_text);
        listView = (ListView) findViewById(R.id.list_view);
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
        listView.setAdapter(adapter);

        // 获取实例 ,初始化数据
        weatherDb = WeatherDb.getInstance(this);
        
        // 加载省级数据
        queryProvinces();
    }
    /**
     * 查询全部省,同时设置当前级别和列表数据
     */
    private void queryProvinces() {
        provinceList = weatherDb.loadProvinces();
        if (provinceList != null && provinceList.size() > 0 ) {
            dataList.clear();
            for (Province province : provinceList) {
                dataList.add(province.getProvinceName());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);
            titleView.setText("中国");
            currentLevel = LEVEL_PROVINCE;
        }
    }

这样省的列表就展示出来了

点击切换省市县数据

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // 省
                if (currentLevel == LEVEL_PROVINCE) {
                    selectedProvince = provinceList.get(position);
                    queryCities();
                 // 市
                }else if (currentLevel == LEVEL_CITY){
                    selectedCity = cityList.get(position);
                    queryCounties();
                // 县
                }else if (currentLevel == LEVEL_COUNTY) {
                    String countyCode = countyList.get(position).getCountyCode();
                   // ...具体待下一步操作
                }
            }

        });

// 根据省code加载市数据,同时设置当前级别和列表数据
private void queryCities() {
        cityList = weatherDb.loadCities(selectedProvince.getProvinceCode());
        if (cityList != null && cityList.size() > 0 ) {
            dataList.clear();
            for (City city : cityList) {
                dataList.add(city.getCityName());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);
            titleView.setText(selectedProvince.getProvinceName());
            currentLevel = LEVEL_CITY;
        }
    }
// 根据市code加载县数据,同时设置当前级别和列表数据
    private void queryCounties() {
        countyList = weatherDb.loadCounties(selectedCity.getCityCode());
        if (countyList != null && countyList.size() > 0) {
            dataList.clear();
            for (County county : countyList) {
                dataList.add(county.getCountyName());
            }
            adapter.notifyDataSetChanged();
            listView.setSelection(0);
            titleView.setText(selectedCity.getCityName());
            currentLevel = LEVEL_COUNTY;
        }
    }

别忘了配置AndroidManifest

<activity
android:name="com.coolweather.app.activity.ChooseAreaActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

写到这里基本 切换省市县的效果就出来了

到县就可以根据县的code去请求api 查询相关天气的数据,然后展示出来。

显示天气信息

封装http请求的天气数据

public class WeatherInfoUtil {

    /**
     * 解析服务器返回的JSON数据,并将解析出的数据存储到本地。
     */
    public static void handleWeatherResponse(Context context, String response) {
        try {
            JSONObject jsonObject = new JSONObject(response);
            JSONArray jsonArray = jsonObject.getJSONArray("HeWeather data service 3.0");
            JSONObject weatherInfo = jsonArray.getJSONObject(0);
            String status = weatherInfo.getString("status");
            if ("ok".equals(status)) {
                // 基础信息
                JSONObject basic = weatherInfo.getJSONObject("basic");
                // 现在天气
                JSONObject now = weatherInfo.getJSONObject("now");
                // 天气预报, 1 -7 天
                JSONArray daily_forecast = weatherInfo.getJSONArray("daily_forecast");
                // 小时预报 3小时
                JSONArray hourly_forecast = weatherInfo.getJSONArray("hourly_forecast");

                // 空气质量 有可能没有
                JSONObject aqi = weatherInfo.optJSONObject("aqi");
                // 提醒 有可能没有
                JSONObject suggestion = weatherInfo.optJSONObject("suggestion");

                // =================基础信息=================
                // 城市
                String cityName = basic.getString("city");
                // ID
                String weatherCode = basic.getString("id");
                JSONObject update = basic.getJSONObject("update");
                // 更新时间
                String publishTime = update.getString("loc");
                // =================现在天气===============
                // 当前温度
                String temp = now.getString("tmp");
                // 当前天气描述
                JSONObject cond = now.getJSONObject("cond");
                String weatherDesp = cond.getString("txt");

                JSONObject wind = now.getJSONObject("wind");
                // 风向
                String dir = wind.getString("dir");
                // 风力
                String sc = wind.getString("sc");
                // =================天气预报===============
                for (int i = 0; i < daily_forecast.length(); i++) {
                    JSONObject daily = daily_forecast.getJSONObject(i);
                    String date = daily.getString("date");
                    JSONObject condDaily = daily.getJSONObject("cond");
                    String txt_d = condDaily.getString("txt_d");
                    String txt_n = condDaily.getString("txt_n");

                    JSONObject tmpDaily = daily.getJSONObject("tmp");
                    String minTemp = tmpDaily.getString("min");
                    String maxTemp = tmpDaily.getString("max");

                    JSONObject windDaily = daily.getJSONObject("wind");
                    String dirDaily = windDaily.getString("dir");
                    String scDaily = windDaily.getString("sc");
                }

                saveWeatherInfo(context, cityName, weatherCode, temp, weatherDesp, publishTime, dir, sc);

            }
            if ("unknown city".equals(status)) {
                saveWeatherInfo(context, null, null, null, "未知城市", null, null, null);
            }
            if ("no more requests".equals(status)) {
                saveWeatherInfo(context, null, null, null, "超过访问次数", null , null, null);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    /**
     * 将服务器返回的所有天气信息存储到SharedPreferences文件中。
     */
    private static void saveWeatherInfo(Context context, String cityName, String weatherCode, String temp, String weatherDesp, String publishTime,
    String dir, String sc) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日", Locale.CHINA);

        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
        editor.putBoolean("city_selected", true);
        editor.putString("city_name", cityName);
        editor.putString("weather_code", weatherCode);
        editor.putString("temp", temp + "℃");
        editor.putString("weather_desp", weatherDesp);
        editor.putString("publish_time", publishTime);
        editor.putString("current_date", sdf.format(new Date()));

        editor.putString("wind_dir", dir);
        editor.putString("wind_sc", sc + "级");
        editor.commit();

    }
}

以上就是解析json 数据,然后存到SharedPreferences 中,key-value 形式。

天气布局

来想想我们要什么?

  1. 标题
    1. 县 居中
    2. 返回重新选择
    3. 刷新数据按钮
  2. 数据时间
  3. 天气信息
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!--标题 城市名称-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#484E61">
        
        <Button
            android:id="@+id/switch_city"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:background="@drawable/home"/>

        <TextView
            android:id="@+id/city_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textColor="#fff"
            android:textSize="24sp"
            />
        
        <Button
            android:id="@+id/refresh_weather"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:background="@drawable/refresh"/>

    </RelativeLayout>

    <!--天气信息-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#27A5F9">

        <TextView
            android:id="@+id/publish_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:textColor="#fff"
            android:textSize="24sp"
            />

        <LinearLayout
            android:id="@+id/weather_info_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:orientation="vertical">


            <!--描述-->
            <TextView
                android:id="@+id/weather_desp"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:layout_gravity="center_horizontal"
                android:gravity="center"
                android:textColor="#fff"
                android:textSize="40sp"
                />

            <!--温度-->
            <TextView
                android:id="@+id/temp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:gravity="center"
                android:textColor="#FFF"
                android:textSize="40sp"
                />
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal"
               >
                <TextView
                    android:id="@+id/wind_dir"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#fff"
                    android:textSize="18sp"
                    android:gravity="center"
                    />

                <TextView
                    android:id="@+id/wind_sc"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#fff"
                    android:textSize="18sp"
                    android:gravity="center"

                    />

            </LinearLayout>

            <!--日期-->
            <TextView
                android:id="@+id/current_date"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:gravity="center"
                android:textColor="#fff"
                android:textSize="18sp"
                />
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>

天气活动 WeatherActivity

首先 从 选择地区活动 到 天气活动 并把 code传递过来

ChooseAreaActivity

// 
}else if (currentLevel == LEVEL_COUNTY) {
                    String countyCode = countyList.get(position).getCountyCode();
                    Intent intent = new Intent(ChooseAreaActivity.this, WeatherActivity.class);
                    intent.putExtra("county_code", countyCode);
                    startActivity(intent);
                    finish();
                }

但是如果之前已经选中,那就不要再加载了,直接跳到天气。 这个可能一开始不太理解,可以后面再加。

isFromWeatherActivity = getIntent().getBooleanExtra("from_weather_
activity", false);
// 是否选中天气 , 选择就不用再加载了
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
        if (preferences.getBoolean("city_selected", false) && !isFromWeatherActivity) {
            Intent intent = new Intent(this, WeatherActivity.class);
            startActivity(intent);
            finish();
            return;
        }

WeatherActivity

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.weather_layout);

        // 初始化各控件
        weatherInfoLayout = (LinearLayout) findViewById(R.id.weather_info_layout);
        cityNameText = (TextView) findViewById(R.id.city_name);
        publishText = (TextView) findViewById(R.id.publish_text);
        weatherDespText = (TextView) findViewById(R.id.weather_desp);
        tempText = (TextView) findViewById(R.id.temp);

        currentDateText = (TextView) findViewById(R.id.current_date);
        switchCity = (Button) findViewById(R.id.switch_city);
        refreshWeather = (Button) findViewById(R.id.refresh_weather);


        windDir = (TextView) findViewById(R.id.wind_dir);
        windSc = (TextView) findViewById(R.id.wind_sc);

        switchCity.setOnClickListener(this);
        refreshWeather.setOnClickListener(this);
        // ChooseAreaActivity  传过来的值
        String countyCode = getIntent().getStringExtra("county_code");
        // 有代号显示 选择城市的天气,没有就本地已存储的天气
        if (!TextUtils.isEmpty(countyCode)) {
            publishText.setText("同步中...");
            // 隐藏
            weatherInfoLayout.setVisibility(View.INVISIBLE);
            cityNameText.setVisibility(View.VISIBLE);
           // 查天气
            queryWeatherInfo(countyCode);
        } else {
            showWeather();
        }

    }

/**
     * 显示天气,直接从 SharedPreferences 去取,取不到就存。
     */
    private void showWeather() {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        cityNameText.setText( prefs.getString("city_name", ""));
        tempText.setText(prefs.getString("temp", ""));
        weatherDespText.setText(prefs.getString("weather_desp", ""));
        String publish_time = prefs.getString("publish_time", "");
        publish_time = publish_time.split(" ").length > 1 ? publish_time.split(" ")[1] : "";
        publishText.setText("今天" + publish_time + "发布");

        windDir.setText(prefs.getString("wind_dir", ""));
        windSc.setText(prefs.getString("wind_sc", ""));

        currentDateText.setText(prefs.getString("current_date", ""));
        // 显示
        weatherInfoLayout.setVisibility(View.VISIBLE);
        cityNameText.setVisibility(View.VISIBLE);
    }

// 查天气信息
private void queryWeatherInfo(String weatherCode) {
        String address = String.format("https://api.heweather.com/x3/weather?cityid=CN%s&key=%s", weatherCode, "填写api key");
        Log.d(TAG, address);
        queryFromServer(address);
    }

    /**
     * 从服务器 获取 最新的天气数据
     * @param address
     */
    private void queryFromServer(String address) {
        HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
            @Override
            public void onFinish(String response) {
                WeatherInfoUtil.handleWeatherResponse(WeatherActivity.this, response);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        showWeather();
                    }
                });
            }

            @Override
            public void onError(final Exception e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        e.printStackTrace();
                        publishText.setText("同步失败");
                    }
                });
            }
        });
    }
// 点击返回 和 刷新效果
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.switch_city:
                // 选择城市,返回上一层
                Intent intent = new Intent(this, ChooseAreaActivity.class);
                intent.putExtra("from_weather_activity", true);
                startActivity(intent);
                finish();
                break;
            case R.id.refresh_weather:
                // 刷新天气
                publishText.setText("同步中...");
                SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
                String weatherCode = preferences.getString("weather_code", "");
                // 获取id 重新去访问天气信息
                if (!TextUtils.isEmpty(weatherCode)) {
                    queryWeatherInfo(weatherCode);
                }
                break;
            default:
                break;
        }
    }

加入权限和注册活动

<uses-permission android:name="android.permission.INTERNET"/>
<activity android:name=".activity.WeatherActivity"/>

后台定时更新活动

这部分功能不加也行,后续扩展吧。

public class AutoUpdateService extends Service{
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                updateWeather();
            }
        }).start();

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        // 8h
        int anHour = 8 * 60 * 60 * 1000;
        long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
        Intent i = new Intent(this, AutoUpdateReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        return super.onStartCommand(intent, flags, startId);
    }

    private void updateWeather() {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
        String weatherCode = preferences.getString("weather_code", "");
        String address = String.format("https://api.heweather.com/x3/weather?cityid=CN%s&key=%s", weatherCode, "填写app key");
        HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
            @Override
            public void onFinish(String s) {
                WeatherInfoUtil.handleWeatherResponse(AutoUpdateService.this, s);
            }

            @Override
            public void onError(Exception e) {
                e.printStackTrace();
            }
        });
    }
}

来个定时接收

public class AutoUpdateReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, AutoUpdateService.class);
        context.startActivity(i);
    }
}

别忘注册

<service android:name=".service.AutoUpdateService"/>
<receiver android:name=".service.AutoUpdateReceiver"/>

在哪里启动这个服务呢?

成功载入天气数据的时候: showWeather()方法内

// 启动服务
Intent intent = new Intent(this, AutoUpdateService.class);
startService(intent);

差不多就完了。

其实这个很简陋,只显示今天的,可以搞个折线图,把7天的天气预报也显示出来。

还有一些天气的图标,也可以获取到,这个api还是很全的。

© 著作权归作者所有

ssnoodles
粉丝 2
博文 31
码字总数 9574
作品 0
张家港
私信 提问
求一份上海的 Android 实习工作

一名应届毕业生,在一些招聘网站上投了不少简历,但都没什么回应,而且好多都是培训公司。 在此寻求一份上海的 Android实习 工作,工资要求不高,至少能满足自己个人的生活需求。 自学Andro...

FecTung
2016/06/27
735
3
Android 开发者应该知道的 Kotlin 技巧

今年的 Google I/O 大会上,Google 是这样评价 Kotlin:在过去一年里,有35%的专业 Android 开发者在使用 Kotlin,其中95%的开发者都对 Kotlin 非常满意。虽然 Kotlin 正处于发展的初始阶段,...

码云Gitee
2018/05/28
0
0
Android 学习小结

Android 学习已有一年半有余,先后做过两款游戏、三款应用和搭建一台服务端,也了解过一些Android相关的源码(JDK、SDK和NDK) 后来想学深入点,搞过两款开源项目(LGame 和 AChartEngine),...

长平狐
2013/01/06
213
0
分享一个我开发的MVVM架构的开源小项目

版权声明:本文出自郭霖的博客,转载必须注明出处。 https://blog.csdn.net/sinyu890807/article/details/87900605 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖...

guolin
03/01
0
0
Android实战经验之图像处理及特效处理的集锦(总结版)

1 Android学习笔记进阶之在图片上涂鸦(能清屏) 2 Android学习笔记之详细讲解画圆角图片 3 Android学习笔记进阶20之得到图片的缩略图 4 Android学习笔记进阶19之给图片加边框 5 Android学习笔...

xiaosi
2012/03/12
40.2K
25

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部