来源:网易云课堂GeekBand第七次作业

作业要求:

做一个天气应用

  1. 接口参考: http://apistore.baidu.com/apiworks/servicedetail/880.html,只是参考API,可自行查找使用其他API接口
  2. 考察内容:获取数据,解析JSON
  3. 数据缓存在数据库中,使用ContentProvider来处理
  4. 如果不强制刷新,则使用缓存数据每隔一定时间再刷新一次

前期准备

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,把四大组件都用到了,把基本用法复习了一遍,温故知新.

android开发练习:天气应用的更多相关文章

  1. Android经典项目开发之天气APP实例分享

    原文:Android经典项目开发之天气APP实例分享 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/mzc186/article/details/5 ...

  2. 50个Android开发人员必备UI效果源码[转载]

    50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面 ...

  3. 【Mood-12】Android开发相关书籍推荐

    新年伊始,找到Android进阶干货若干,2015拜读. 1.Android应用UI设计模式 目前,谷歌Android操作系统在移动市场中风头正劲,并且未来发展势不可挡.<Android应用UI ...

  4. Android开发中常见的设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...

  5. Android开发心得(转)

    前言: 很早以前,就听人说过android以后会火起来,作为一个前瞻性对它有所了解会是一个转型的好机会,javaweb太成熟饱和了,现在市面上各种android手机层出不穷,网上各种android视频 ...

  6. Android解析中国天气网的Json数据

    在Android开发中.一般的APP都是通过获取server端的数据来更新UI.从server获取到的数据能够是Json.它的数据量要比XML要小,这里解析中国天气网上获取的数据,尽管已经不再更新了. ...

  7. Android开发周报:反编译对抗研究、动手制作智能镜子

    新闻 <Android Wear落地中国 谷歌增强安卓生态控制力> :9月8日,由摩托罗拉推出的智能手表Moto 360二代作为国内发售的第一款搭载官方Android Wear的设备,正式 ...

  8. Android开发周报:Android L默认加密用户数据

    Android开发周报:Android L默认加密用户数据 新闻 <iCloud前车之鉴,Android L默认开启加密功能>:iCloud 艳照风波再起,第二波女星照片流出,大量女星的裸 ...

  9. Android开发10:传感器器及地图相关应用

    前言 啦啦啦~各位小伙伴们好~经过这一学期的Android知识的学习,我们学到了很多和Android开发相关的知识,这一学期的学习也要告一段落了. 一起进入我们今天的相关内容~这次我们将一起学习使用 ...

随机推荐

  1. 关于MVC中模型model的验证问题

    今天在做项目练习的时候发现,MVC中使用自带的模型验证时会提前显示在界面上,比如下面所示: 这是什么原因了,是因为我在表示get请求的action里面返回了其界面所显示使用的model,我们知道mvc ...

  2. 【UWP】UI适配整理

    做UWP有几个月了,期间发布了几个应用,在这里整理一下适配相关的一些东西,UWP关于UI的适配主要有两种方式: 1.VisualState+Trigger:通过触发器出发界面更变,通常在Desktop ...

  3. 线程池ThreadPool的初探

    一.线程池的适用范围 在日常使用多线程开发的时候,一般都构造一个Thread示例,然后调用Start使之执行.如果一个线程它大部分时间花费在等待某个事件响应的发生然后才予以响应:或者如果在一定期间内重 ...

  4. css3飞机起飞进度条

    效果:http://hovertree.com/texiao/css3/27/ 源码下载:http://hovertree.com/h/bjaf/pgwql1x2.htm 本效果使用Font Awes ...

  5. 使用DataConnectionDialog在运行时设置数据源连接字符串

    介绍: DataConnectionDialog 类: 打开“数据连接”对话框,获取用户选择的数据连接信息. 命名空间为:Microsoft.Data.ConnectionUI 所在程序集:Micro ...

  6. 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native

    [源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...

  7. 【Java每日一题】20161018

    20161017问题解析请点击今日问题下方的"[Java每日一题]20161018"查看 package Oct2016; public class Ques1018 { publ ...

  8. c++之string.find(string)

    先来看一个例子吧: #include "iostream" #include "string" using namespace std; // 定义函数求str ...

  9. uums

    http://blog.csdn.net/hudon/article/details/1506042 http://www.cnblogs.com/biakia/p/4779655.html http ...

  10. R语言XML格式数据导入与处理

    数据解析 XML是一种可扩展标记语言,它被设计用来传输和存储数据.XML是各种应用程序之间进行数据传输的最常用的工具.它与Access,Oracle和SQL Server等数据库不同,数据库提供了更强 ...