android开发练习:天气应用
来源:网易云课堂GeekBand第七次作业
作业要求:
做一个天气应用
- 接口参考: 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() {@Overridepublic 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;//需要inserttry {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@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//在子线程中发起网络请求,将请求结果保存到数据库中new Thread(new Runnable() {@Overridepublic void run() {updateWeather();}}).start();//使用AlarmManager实现定时任务AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);int anHour = 8 * 60 *60 * 1000;//8小时long triggerAtTime = SystemClock.elapsedRealtime() + anHour;//service -> receiverIntent 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{@Overridepublic void onReceive(Context context, Intent intent) {//receiver->serviceIntent 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);}@Overridepublic boolean onCreate() {mMyDBHelper = new MyDBHelper(getContext(), "weatherDataDB.db", null, 1);return true;}@Nullable@Overridepublic 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@Overridepublic 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@Overridepublic 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;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {return 0;}@Overridepublic 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,把四大组件都用到了,把基本用法复习了一遍,温故知新.
转载于:https://www.cnblogs.com/happyhacking/p/5264168.html
android开发练习:天气应用相关推荐
- 基于Android实现的天气预测APP
基于Android开发的天气预测APP 一.相关技术 1.1 网络 网络数据源使用 Retrofit 库访问彩云 API 提供的 Webservice 接口来实现. Retrofit 通过封装络请求和 ...
- 用于android天气开发的背景图,Android开发天气预报APP的设计与实现毕业设计.pdf
摘要 随着移动互联网技术和通信技术的发展,智能手机几乎成为人们 生活的必需品.近年来,Android系统已经成为智能手机中用户量最 多的操作系统.通过Android程序开发和设计天气预报手机应用,可 ...
- Compose Android 开发终极挑战赛: 天气应用
前因后果 Compose beta 版发布也快一个月了,Google 官方发起的 Android 开发挑战赛也举办到了最后一期,四期的挑战分别是: 第一期挑战是做一个领养宠物的应用,全球一共有五百份礼 ...
- 应用程序基础知识:activity和intent——Android开发秘籍
应用程序基础知识:activity和intent --Android开发秘籍 v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#defaul ...
- android开发模式,Android开发中无处不在的设计模式
Android开发中无处不在的设计模式――单例模式 Android开发中无处不在的设计模式――Builder模式 前面介绍了单例模式和Builder模式,有兴趣的见上面两个链接,这篇文章侧重介绍1下视 ...
- Android开发中常见的设计模式
对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...
- 《Android开发案例驱动教程》
<Android开发案例驱动教程> 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式展开讲解知识点,即介绍案例->案例涉及技术->展开 ...
- Android开发笔记(一百一十八)自定义悬浮窗
WindowManager 在前面< Android开发笔记(六十六)自定义对话框>中,我们提到每个页面都是一个Window窗口,许多的Window对象需要一个管家来打理,这个管家我们称之 ...
- Android开发学习持续更新中
Android开发 单个Activity界面内的操作 控件1TextView控件使用 控件2Button控件使用 1首先对于android的按键格式 2对按键监听事件进行绑定 控件3EditText文 ...
- Android开发:开源库集合
开源库大全 目录 抽屉菜单 ListView WebView SwitchButton 按钮 点赞按钮 进度条 TabLayout 图标 下拉刷新 ViewPager 图表(Chart) 菜单(Men ...
最新文章
- 关于hql一些不常见但好用的技巧(个人总结)
- 【Codeforces Round #767 (Div. 2)】 C. Meximum Array 题解
- C#中StringBuilder类的使用
- 《实用》secureCRT远程连接linux虚拟机-突然连接不上-解决办法
- redis存储新闻列表_Redis对象——集合(Set)
- 2007高考:考生要根据家庭经济条件慎重填报按办学成本收费的高校及专业
- tensorflow2.0学习(一)
- Caffe中如果高效实现卷积层
- 使用 HTML5 File API 实现client log
- 吴陆 java,成年人的世界,崩溃无声。
- 学python能做什么-学了Python都能干什么,哪个最赚钱?
- 中国工业行业分类英文翻译
- 开源iTunes替代品– aTunes
- 路飞学城mysql练习
- PhalAPI学习笔记拓展篇 ——— 基于MySQL数据库交互题目
- java 动态定时提醒_java实现定时提醒功能
- quarz定时任务 spring整合quartz
- 谈谈浏览器中富文本编辑器的技术演进
- 中国三大互联网巨头陷入移动战争
- linux批量重命名脚本,Mac / Linux Shell 批量重命名的方法总览
热门文章
- pycharm调试步骤(详细)
- 类的加载器ClassLoader及其示例
- 电脑已安装软件提取安装包_SPSS 24,软件安装包及安装教程
- 凸优化第三章凸函数 3.6关于广义不等式的凸性
- mysql 指定驱动表_了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表
- Raki的读paper小记:Word2Vec
- 940mx黑苹果驱动_黑苹果intel网卡驱动方法
- PHP MD5 SHA1 比较 漏洞绕过
- 拦截器(Interceptor)和过滤器(Filter)区别
- 第二章:WebDriver 打开Firefox浏览器 和 Chrome 浏览器