首页 > 代码库 > 基于百度定位及天气获取的DEMO

基于百度定位及天气获取的DEMO

demo基于百度定位APIv4.0版、新浪天气(不用查询城市代码)。

需求:

1、button实现触发定位监听和天气捕获

2、两个textview 分别显示详细地址、天气。

界面很简陋,侧重功能实现。

 

下面记录下主要技术点:

1.百度定位

    /**     * 发起定位     */    public void requestLocationInfo() {        setLocationOption();        if (mLocationClient != null && !mLocationClient.isStarted()) {            mLocationClient.start();        }        if (mLocationClient != null && mLocationClient.isStarted()) {            mLocationClient.requestLocation();        }    }    /**     * 设置相关参数     */    private void setLocationOption() {        LocationClientOption option = new LocationClientOption();        option.setOpenGps(true); // 打开gps        option.setCoorType("bd09ll"); // 设置坐标类型        option.setServiceName("com.baidu.location.service_v2.9");        option.setPoiExtraInfo(true);        option.setAddrType("all");        option.setPoiNumber(10);        option.disableCache(true);        mLocationClient.setLocOption(option);    }    /**     * 监听函数,有更新位置的时候,格式化成字符串,输出到屏幕中     */    public class MyLocationListenner implements BDLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {            if (location == null) {                sendBroadCast(new ParcelableInfo("获取失败","获取失败"));                return;            }                        address=location.getAddrStr();                    }        public void onReceivePoi(BDLocation poiLocation) {            if (poiLocation == null) {                sendBroadCast(new ParcelableInfo("获取失败","获取失败"));                return;            }            sendBroadCast(new ParcelableInfo(poiLocation.getDistrict(),poiLocation.getAddrStr()));        }    }

2.异步获取天气信息

异步多线程一般处理方式有;1.handler处理:后续补充

2、AsyncTask:AsyncTask能够更恰当和更简单的去使用UI线程。这个类允许执行后台操作和展现结果在UI线程上,无需操纵线程和/或处理程序。AsyncTask的内部实现是一个线程池,每个后台任务会提交到线程池中的线程执行,然后使用Thread+Handler的方式调用回调函数。

使用AsyncTask类,以下是几条必须遵守的准则: 
  1) Task的实例必须在UI thread中创建 
  2) execute方法必须在UI thread中调用 
  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法 
  4) 该task只能被执行一次,否则多次调用时将会出现异常 
      doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。

关键代码:

package com.liucanwen.baidulocation;/* * 异步多线程加载网络信息,并更新UI * 通常有两种方法:1、handler和Threat * 2、AsyncTask   * 参考网址 http://www.cnblogs.com/dawei/archive/2011/04/18/2019903.html */import java.net.URL;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import com.liucanwen.baidulocation.util.UTF82GBK;import com.liucanwen.baidulocation.util.Weather;import android.os.AsyncTask;import android.widget.TextView;public class LoadWeatherAsyncTask extends AsyncTask<Object, Integer, String> {    private TextView tv;    String getweather;    //表明对哪个textview进行异步更新    public LoadWeatherAsyncTask(TextView tv) {        this.tv = tv;    }    //准备工作,一般初始化textview    @Override    protected void onPreExecute() {            }    //注意:1) Task的实例必须在UI thread中创建  2) execute方法必须在UI thread中调用 )    @Override    protected String doInBackground(Object... params) {        return new Weather().getWeather((String)params[0]);//真正的异步工作,从服务器获取xml数据并解析,但不能对UI操作        }    protected void onPostExecute(String result) {        // 该方法运行在UI线程内        tv.setText(result);    }}

3.困扰好几天的编码问题导致返回天气数据为null

由于之前直接将“广州“的UTF8编码传入URL(ADT默认编码UTF8)导致获取不到天气数据,

URL ur = new URL("http://php.weather.sina.com.cn/xml.php?city="                    + str+ "&password=DJOYnieT8234jlsK&day=" + day);

后来发现,传入的str需要为GB2312编码数据。所以需要转码

new UTF82GBK().getCoding(str)
public String getCoding(String str) throws IOException{    String s1 = URLEncoder.encode(str, "gb2312");    return s1;    }
public String getWeather(String str) {        try {            DocumentBuilderFactory domfac = DocumentBuilderFactory                    .newInstance();            DocumentBuilder dombuilder = domfac.newDocumentBuilder();            Document doc;            Element root;            NodeList books;            // 浏览器中识别的是GBK编码,直接输入汉字是接收不到数据的            URL ur = new URL("http://php.weather.sina.com.cn/xml.php?city="                    + new UTF82GBK().getCoding(str)                    + "&password=DJOYnieT8234jlsK&day=" + day);            // 解析XML            doc = (Document) dombuilder.parse(ur.openStream());            root = (Element) doc.getDocumentElement();            books = ((Node) root).getChildNodes();            for (Node node = books.item(1).getFirstChild(); node != null; node = node                    .getNextSibling()) {                if (node.getNodeType() == Node.ELEMENT_NODE) {                    if (node.getNodeName().equals("status1"))                        weather = node.getTextContent(); // 获取天气状况                    else if (node.getNodeName().equals("temperature1"))                        high = node.getTextContent(); // 获取最高温度                    else if (node.getNodeName().equals("temperature2"))                        low = node.getTextContent(); // 获取最低温度                }            }        } catch (Exception e) {            e.getMessage();        }        String getweather = str + " " + weather + " " + low + "度~" + high + "度";        return getweather;    }

 

4.Intent传递对象

需要从传入MyApplication将City和address传入到MainActivity中,将需要传递的数据封装到LocationInfo类中。

使用intent传递对象的方法有两种:

1、实现Serializable接口

2、实现Parcelable接口

我采用 实现Parcelable接口:

LocationInfo .java用于确定传递数据的数据模型
public class LocationInfo implements Serializable {    private String city;    private String address;        public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }        }
/** * 实现了Parcelable接口的ParcelableInfo类: */import android.os.Parcel;import android.os.Parcelable;public class ParcelableInfo implements Parcelable {    private String city;    private String address;    public ParcelableInfo() {    }    public ParcelableInfo(String city, String address) {        this.city = city;        this.address = address;    }    public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }    public static final Parcelable.Creator<ParcelableInfo> CREATOR = new Creator<ParcelableInfo>() {        @Override        public ParcelableInfo createFromParcel(Parcel source) {            ParcelableInfo parcelableInfo = new ParcelableInfo();            parcelableInfo.city = source.readString();            parcelableInfo.address = source.readString();            return parcelableInfo;        }        @Override        public ParcelableInfo[] newArray(int size) {            return new ParcelableInfo[size];        }    };    @Override    public int describeContents() {        // TODO Auto-generated method stub        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        // TODO Auto-generated method stub        dest.writeString(city);        dest.writeString(address);    }    }
public void sendBroadCast(ParcelableInfo parcelableInfo) {        stopLocationClient();        Intent intent = new Intent(MainActivity.LOCATION_BCR);        //ParcelableInfo parcelableUser = new ParcelableInfo(city,address);         //intent.putExtra("address", address);        Bundle bundle = new Bundle();         bundle.putParcelable("parcelableInfo", parcelableInfo);         intent.putExtras(bundle);         sendBroadcast(intent);    }

在MyApplication中发送

public void sendBroadCast(ParcelableInfo parcelableInfo) {        stopLocationClient();        Intent intent = new Intent(MainActivity.LOCATION_BCR);                Bundle bundle = new Bundle();         bundle.putParcelable("parcelableInfo", parcelableInfo); //将parcelableInfo对象封装在bundle中        intent.putExtras(bundle); //intent传递bundle        sendBroadcast(intent);    }

在MainActivity中接收

parcelableInfo = intent.getParcelableExtra("parcelableInfo");    locInfo.setText("你所在的地址为:" + parcelableInfo.getAddress());

 

本人初学上路,语言表达不准确,见谅···

源码地址:http://download.csdn.net/detail/xiejun1026/8411437

 

基于百度定位及天气获取的DEMO