博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10天学安卓-第六天
阅读量:4359 次
发布时间:2019-06-07

本文共 10270 字,大约阅读时间需要 34 分钟。

原文:

经过前几天的学习,我们的天气预报程序已经可以把天气正常的呈现出来了,正如之前说的,现在的APP只能显示固定地区的天气,那么我们要怎样才能显示我们本身所在地的天气呢?

Android定位

Android系统本身提供了三种定位方式,分别是网络、基站和GPS,主要利用的是LocationManager、TelephonyManager相关的类库,但是因为一些原因,Google的API在国内访问经常出现问题,所以在这里我就不对这些API做介绍了,有想了解的可以自行查询相关资料。

百度地图定位

除了Android本身提供的定位功能外,在国内也有很多供我们使用的定位系统,比如百度地图、高德地图都提供了相应的功能,我这里主要介绍一下百度地图的使用方式。

需要到 http://lbsyun.baidu.com/sdk/download?selected=location 下载定位功能的开发包,然后把开发包的内容放到libs文件夹,这样我们就引入了百度地图定位功能的API。

然后,开工吧。

 

配置Manifest

首先添加定位功能所需要的权限,还记得添加到哪吧。

 

然后在application节点内,添加一个service,这个service是运行于后台的获取定位的服务,

 

最后,在application节点内,添加我们申请的百度地图API的Accesskey。

 

就这样,百度地图的引入就算是完成了。那么如何在代码中使用?

 

打开MainActivity.java,我们需要简单重构一下代码。

你可以使用Eclipse的重构工具,也可以手动修改代码,修改为如下:

@Override    protected void onCreate( Bundle savedInstanceState )    {        super.onCreate( savedInstanceState );        setContentView( R.layout.activity_main );        ViewUtils.inject( this );        datas = new ArrayList
(); adapter = new WeatherAdapter( getApplicationContext(), datas ); lstWeather.setAdapter( adapter ); getWeather( "北京" ); } private void getWeather( String city ) { HttpUtils http = new HttpUtils(); RequestParams params = new RequestParams(); params.addQueryStringParameter( "location", city ); params.addQueryStringParameter( "output", "json" ); params.addQueryStringParameter( "ak", "YknGmxIoPugT7YrNrG955YLS" ); http.send( HttpMethod.GET, "http://api.map.baidu.com/telematics/v3/weather", params, new RequestCallBack
() { @Override public void onSuccess( ResponseInfo
responseInfo ) { String weather = responseInfo.result; Gson gson = new Gson(); data = gson.fromJson( weather, BaiduData.class ); datas.clear(); datas.addAll( data.getResults().get( 0 ).getWeather_data() ); adapter.notifyDataSetChanged(); Log.v( "onSuccess", data.toString() ); } @Override public void onFailure( HttpException arg0, String arg1 ) { Log.v( "onFailure", arg1 ); } } ); }

 

 

这里新增加了一个以城市为参数方法getWeather,做好了重构之后,我们加入百度的定位功能。

 

声明两个变量:

private LocationClient mLocationClient;    private BDLocationListener myListener;

 

添加初始化这两个变量的方法,

private void initLocationClient()    {        mLocationClient = new LocationClient( getApplicationContext() );         myListener = new MyLocationListener();        LocationClientOption option = new LocationClientOption();        option.setLocationMode( LocationMode.Hight_Accuracy );        option.setIsNeedAddress( true );        mLocationClient.setLocOption( option );        mLocationClient.registerLocationListener( myListener );    }

 

我们是用到了MyLocationListener,这个类需要自定义,作为MainActivity的内部类存在,

public class MyLocationListener implements BDLocationListener    {        @Override        public void onReceiveLocation( BDLocation location )        {            String city = location.getCity();            getWeather( city );            setTitle( city + "天气" );        }    }

 

然后,修改onCreate方法,

protected void onCreate( Bundle savedInstanceState )    {        super.onCreate( savedInstanceState );        setContentView( R.layout.activity_main );        ViewUtils.inject( this );        datas = new ArrayList
(); adapter = new WeatherAdapter( getApplicationContext(), datas ); lstWeather.setAdapter( adapter ); initLocationClient(); mLocationClient.start(); }

 

最后,添加onStop方法,

@Override    protected void onStop()    {        super.onStop();        mLocationClient.stop();    }

 

打完收工。

 

运行吧,看看是怎样的效果,反正我的是这样:

 

是不是你所在的城市呢?

 

既然看到效果了,那么稍微解释一下上面那些代码。

首先在界面加载的时候,会调用initLocationClient方法,这个方法初始化了LocationClient和BDLocationListener,LocationClient的作用是异步获取定位,MyLocationListener则是在LocationClient获取定位后的回调方法,我们在这个回调方法中调用了获取天气的方法getWeather,并且调用setTitle方法修改了APP页面的标题为“城市名+天气”。

整个流程堪称完美,只差一点点。

 

这一点点是什么地方呢?

 

就在于我们每一次获取天气之前都需要定位,而你是不会每天都换一个城市的,为此我们的程序需要优化一下。优化后的流程为:

1. 从本地读取城市,并且同时调用百度定位

2. 如果1中的本地城市不为空,则获取天气

3. 如果1中百度定位的城市跟本地城市一致,就不再次获取天气;若不一致,则覆盖本地城市,并且重新获取天气

这样做的好处有两个:

1. 只有第一次启动APP的时候,本地城市为空,那么就是获取天气会比较快

2. 即使更换了城市,也能准确应对

 

既然整理好思路了,那么就开工吧。

 

Android本地存储数据有多种方式,主要有Preference、Sqlite、File这三种,我们今天使用的是Preference这种方式。

Preference

Preference适合存储轻量数据,如String、Int、Boolean等类型的数据,我们所需要保存的城市数据就是一个简单的字符串,非常适合这种方式。

在MainActivity.java 内添加两个方法,分别为存储、读取数据的方法。

private void saveCity( String city )    {        SharedPreferences sharedPreferences = getSharedPreferences( "weather", Context.MODE_PRIVATE );        Editor editor = sharedPreferences.edit();        editor.putString( "city", city );        editor.commit();    }    private String readCity()    {        SharedPreferences sharedPreferences = getSharedPreferences( "weather", Context.MODE_PRIVATE );        return sharedPreferences.getString( "city", "" );    }

 

有些经验的程序员一眼就能看明白,Preference中是以Key/Value的形式存储数据的。

 

然后修改onCreate方法,

protected void onCreate( Bundle savedInstanceState )    {        super.onCreate( savedInstanceState );        setContentView( R.layout.activity_main );        ViewUtils.inject( this );        datas = new ArrayList
(); adapter = new WeatherAdapter( getApplicationContext(), datas ); lstWeather.setAdapter( adapter ); initLocationClient(); mLocationClient.start(); String city = readCity(); if( city != null && city.length() > 0 ) { getWeather( city ); } }

 

这里加入了读取本地城市,并且获取天气的逻辑。

 

接下来修改MyLocationListener,

public class MyLocationListener implements BDLocationListener    {        @Override        public void onReceiveLocation( BDLocation location )        {            String city = location.getCity();            String localCity = readCity();            if( !localCity.equals( city ) )            {                saveCity( city );                getWeather( city );            }        }    }

 

这里加入了定位的城市和本地城市判断的逻辑,并且删掉了对setTitle 方法的调用.

 

最后,修改getWeather方法,在方法第一行加入对setTitle的调用。

setTitle( city + "天气" );

 

打完收工,最后MainActivity.java是这个样子的:

public class MainActivity extends Activity{    @ViewInject( R.id.weather_list )    private ListView lstWeather;    private WeatherAdapter adapter;    private BaiduData data;    private List
datas; private LocationClient mLocationClient; private BDLocationListener myListener; @Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.activity_main ); ViewUtils.inject( this ); datas = new ArrayList
(); adapter = new WeatherAdapter( getApplicationContext(), datas ); lstWeather.setAdapter( adapter ); initLocationClient(); mLocationClient.start(); String city = readCity(); if( city != null && city.length() > 0 ) { getWeather( city ); } } private void getWeather( String city ) { setTitle( city + "天气" ); HttpUtils http = new HttpUtils(); RequestParams params = new RequestParams(); params.addQueryStringParameter( "location", city ); params.addQueryStringParameter( "output", "json" ); params.addQueryStringParameter( "ak", "YknGmxIoPugT7YrNrG955YLS" ); http.send( HttpMethod.GET, "http://api.map.baidu.com/telematics/v3/weather", params, new RequestCallBack
() { @Override public void onSuccess( ResponseInfo
responseInfo ) { String weather = responseInfo.result; Gson gson = new Gson(); data = gson.fromJson( weather, BaiduData.class ); datas.clear(); datas.addAll( data.getResults().get( 0 ).getWeather_data() ); adapter.notifyDataSetChanged(); Log.v( "onSuccess", data.toString() ); } @Override public void onFailure( HttpException arg0, String arg1 ) { Log.v( "onFailure", arg1 ); } } ); } private void initLocationClient() { mLocationClient = new LocationClient( getApplicationContext() ); // 声明LocationClient类 myListener = new MyLocationListener(); LocationClientOption option = new LocationClientOption(); option.setLocationMode( LocationMode.Hight_Accuracy ); option.setIsNeedAddress( true ); mLocationClient.setLocOption( option ); mLocationClient.registerLocationListener( myListener ); } @Override protected void onStop() { super.onStop(); mLocationClient.stop(); } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation( BDLocation location ) { String city = location.getCity(); String localCity = readCity(); if( !localCity.equals( city ) ) { saveCity( city ); getWeather( city ); } } } private void saveCity( String city ) { SharedPreferences sharedPreferences = getSharedPreferences( "weather", Context.MODE_PRIVATE ); Editor editor = sharedPreferences.edit(); editor.putString( "city", city ); editor.commit(); } private String readCity() { SharedPreferences sharedPreferences = getSharedPreferences( "weather", Context.MODE_PRIVATE ); return sharedPreferences.getString( "city", "" ); }}

 

今天的主要任务就是嵌入了百度地图,重构了代码,优化了流程,最最重要的是我们学习了SharedPreferences的使用,这种保存数据方式在做APP的时候是经常会用到的,希望大家能熟练掌握。

 

请注意,本文用到的key是我个人使用的,请勿将其用于任何商业用途。如果有商业需要,请联系我或者自行在百度官网申请Accesskey。

 

附件是本次的工程文件, http://pan.baidu.com/s/1jG9puYU 。

此系列文章系本人原创,如需转载,请注明出处 www.liuzhibang.cn

 

posted on
2015-02-02 09:23 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/4266820.html

你可能感兴趣的文章
C++:文件的输入和输出
查看>>
Http协议、Tomcat、servlet
查看>>
Spring Boot (11) mybatis 关联映射
查看>>
macOS 下安装tomcat
查看>>
字符串格式化复习笔记
查看>>
jquery之ajax
查看>>
Pro Git(中文版)
查看>>
解决phpmyadmin-1800秒超时链接失效问题
查看>>
OpenGL第十一节:拉伸和过滤
查看>>
AlertDialog的onCreateDialog与onPrepareDialog用法
查看>>
swift菜鸟入门视频教程-12-21讲
查看>>
探偵ガリレオー転写る2
查看>>
快速排序算法C++实现[评注版]
查看>>
七尖记
查看>>
SAP(最短增广路算法) 最大流模板
查看>>
安装 OpenSSL 工具
查看>>
用长微博工具发布长微博
查看>>
大庆金桥帆软报表案例
查看>>
Proxy模式
查看>>
读书多些会怎样
查看>>