android开发练习:天气应用
2016-03-11 05:25
459 查看
来源:网易云课堂GeekBand第七次作业
作业要求:
做一个天气应用
接口参考: http://apistore.baidu.com/apiworks/servicedetail/880.html,只是参考API,可自行查找使用其他API接口
考察内容:获取数据,解析JSON
数据缓存在数据库中,使用ContentProvider来处理
如果不强制刷新,则使用缓存数据每隔一定时间再刷新一次
2.gson.如何添加依赖库 http://www.cnblogs.com/happyhacking/p/5257002.html
(注意:cursor.moveToFirst(),Long.valueOf()和Long.getLong()的用法.)
这里注意两个问题:
1.使用gson解析json数据时,不需要为整个json数据创建实体类,只需要为需要解析的数据定义变量和提供getter/setter方法.
2.注意区分什么是json数组:
AutoUpdateService.class
AutoUpdateReceiver.class
很久没有使用contentprovider,以下为基本使用方法.
github地址:https://github.com/zhangbz/WeatherDemo
总结:写这个demo,把四大组件都用到了,把基本用法复习了一遍,温故知新.
作业要求:
做一个天气应用
接口参考: http://apistore.baidu.com/apiworks/servicedetail/880.html,只是参考API,可自行查找使用其他API接口
考察内容:获取数据,解析JSON
数据缓存在数据库中,使用ContentProvider来处理
如果不强制刷新,则使用缓存数据每隔一定时间再刷新一次
前期准备
1.选择合适的API!选择合适的API!选择合适的API!(重要的话说三遍,中途变更API严重影响效率和心情).2.gson.如何添加依赖库 http://www.cnblogs.com/happyhacking/p/5257002.html
目录结构
UI
注意:在布局的过程中weightSum和layout_weight要慎用,尤其是在内容长度可变的情况下,使用结果往往不符合预期.主要逻辑
主要逻辑集中在查询按钮的点击事件上(注意:cursor.moveToFirst(),Long.valueOf()和Long.getLong()的用法.)
mQueryButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //判断用户是否输入了城市名称 if (!TextUtils.isEmpty(mCityName.getText())) { //首先查询本地数据库 Uri uri = Uri.parse("content://com.example.janiszhang.weatherdemo.provider/weatherdata"); Cursor cursor = getContentResolver().query(uri, null, "cityname = ?", new String[]{mCityName.getText() + ""}, null); if (cursor.moveToFirst()) {// 查询成功 //这里不可以使用cursor!= null来判断!!!! Log.i("zhangbz", cursor.getString(cursor.getColumnIndex("savetime"))); if ((System.currentTimeMillis() - Long.valueOf(cursor.getString(cursor.getColumnIndex("savetime")))) < (1000*60)) {//这里不可以使用Long.getLong(),因为它返回的是系统属性的值,其参数是被请求的系统属性的名称 //如果数据库中的数据没有过期,就从数据库中查询 updateUIfromDatabase(cursor); } else { //如果数据库中的数据过期了,则通过网络查询并update到数据库 shouldUpdate = true; try { httpArg = "city=" + URLEncoder.encode(mCityName.getText().toString(), "UTF-8");//中文需要编码 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } new MyAsyncTask().execute(httpArg);//使用asynctask } } else { //网络查询并insert到数据库 shouldUpdate = false;//需要insert try { httpArg = "city=" + URLEncoder.encode(mCityName.getText().toString(), "UTF-8");//中文需要编码 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } new MyAsyncTask().execute(httpArg); } SharedPreferences sp = getSharedPreferences("last", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString("cityname", mCityName.getText().toString()); editor.apply(); //开启自动更新 Intent intent = new Intent(MainActivity.this, AutoUpdateService.class); startService(intent); } } });
重点记录
使用Gson解析数据
Gson gson = new Gson(); WeatherDataStatus weatherDataStatus = gson.fromJson(s, WeatherDataStatus.class);
这里注意两个问题:
1.使用gson解析json数据时,不需要为整个json数据创建实体类,只需要为需要解析的数据定义变量和提供getter/setter方法.
2.注意区分什么是json数组:
//json数组:中括号 [{ "这是json数组": "这是json数组" }, { "这是json数组": "这是json数组" }, { "这是json数组": "这是json数组" }] //注意和这种情况区分开 { "这不是json数组": [{ "这才是json数组": "这才是json数组" }, { "这才是json数组": "这才是json数组" }, { "这才是json数组": "这才是json数组" }] }
自动更新的实现
service需要由Activity启动,之后由service和receiver配合相互唤醒.AutoUpdateService.class
public class AutoUpdateService extends Service{ private String mCityname; @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 manager = (AlarmManager) getSystemService(ALARM_SERVICE); int anHour = 8 * 60 *60 * 1000;//8小时 long triggerAtTime = SystemClock.elapsedRealtime() + anHour; //service -> receiver Intent i = new Intent(this, AutoUpdateReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); return super.onStartCommand(intent, flags, startId); } //... }
AutoUpdateReceiver.class
public class AutoUpdateReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //receiver->service Intent i = new Intent(context, AutoUpdateService.class); context.startService(i); } }
contentprovider的练习
虽然用在这里很牵强,但是目的是练习嘛.很久没有使用contentprovider,以下为基本使用方法.
public class MyProvider extends ContentProvider{ public static final int WEATHERDATA_DIR = 0; public static final String AUTHORITY = "com.example.janiszhang.weatherdemo.provider"; private static UriMatcher sUriMatcher; private MyDBHelper mMyDBHelper; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(AUTHORITY, "weatherdata", WEATHERDATA_DIR); } @Override public boolean onCreate() { mMyDBHelper = new MyDBHelper(getContext(), "weatherDataDB.db", null, 1); return true; } @Nullable @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = mMyDBHelper.getReadableDatabase(); Cursor cursor = null; switch (sUriMatcher.match(uri)) { case WEATHERDATA_DIR: cursor = db.query("weatherdata", projection, selection, selectionArgs, null, null, sortOrder); break; } return cursor; } @Nullable @Override public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case WEATHERDATA_DIR: return "vnd.android.cursor.dir/vnd.com.example.janiszhang.weatherdemo.provider.weatherdata"; } return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = mMyDBHelper.getReadableDatabase(); Uri uriReturn = null; switch (sUriMatcher.match(uri)) { case WEATHERDATA_DIR: long newId = db.insert("weatherdata", null, values); uriReturn = Uri.parse("content://" + AUTHORITY + "/weatherdata/" + newId); break; } return uriReturn; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = mMyDBHelper.getWritableDatabase(); int updateRows = 0; switch (sUriMatcher.match(uri)) { case WEATHERDATA_DIR: updateRows = db.update("weatherdata", values, selection, selectionArgs); break; } return updateRows; } }
github地址:https://github.com/zhangbz/WeatherDemo
总结:写这个demo,把四大组件都用到了,把基本用法复习了一遍,温故知新.
相关文章推荐
- wifi强度数据采集器(android)
- 判断当前应用程序处于前台还是后台 ANDROID
- Android系统亮屏、锁屏、屏幕解锁事件(解决部分手机亮屏后未解锁即进入resume状态)
- Android 监听屏幕解锁事件
- Android 设置Activity永不过期
- android 线程池管理20160311学习
- Android程序真退出与假退出后台运行详解
- Android四大组件之BroadcastReceiver.
- AndroidStudio快捷键
- Android Studio 1.5 opencv开发
- 【Android中文API】Bitmap
- BLE 扫描及连接 android程序开发(一)
- android 屏幕适配
- Android 透明度对照表
- 配置文件:android:inputType参数类型说明
- 拨号操作——android.intent.action.CALL
- 配置文件:android:inputType参数类型说明
- android获得图片
- Android效果书签
- android开发到底难不难 经典方法指导