基于百度定位及天气获取的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

时间: 2024-10-13 01:12:57

基于百度定位及天气获取的DEMO的相关文章

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

此工程较BaiduLocationXML相比:1.植入fragment,结合微信UI2.在原本主界面的button  textview  textview 移植到Fragment13.增加网络判断,网络不通的情况下做另外处理4.在网络通畅的情况下,将地址信息.天气信息存入xml(sharedpreferences),    网络不通的情况下,将原先xml信息读出展现 fragment植入 public class Fragment1 extends Fragment { @Override pu

百度定位SDK实现获取当前经纬度及位置

使用Android自带的LocationManager和Location获取位置的时候,经常会有获取的location为null的情况,并且操作起来也不是很方便,在这个Demo里我使用了百度地图API中的定位SDK,可以一次性获取当前位置经纬度以及详细地址信息,还可以获取周边POI信息,同时可以设定位置通知点,当到达某一位置时,发出通知信息等方式来告知用户.jar包下载以及官方文档请参照:百度定位SDK,前提是需要注册百度开发者账号.下面来看看定位的基本原理,目前,定位SDK可以通过GPS.基站

Android之百度定位API使用

API版本: 百度定位API:V5.0(http://developer.baidu.com/map/wiki/index.php?title=android-locsdk/guide/v5-0) 百度Geocoding API:V2.0(http://developer.baidu.com/map/index.php?title=webapi/guide/webservice-geocoding#7..E9.80.86.E5.9C.B0.E7.90.86.E7.BC.96.E7.A0.81.E

基于百度地图程序eclipse导出APK密匙key出错

       最近基于百度地图sdk写了个demo,在eclipse上真机测试的时候是正常运行的,没有任何问题,但是当我导出apk安装到手机上的时候,却发现地图都是白格子,经调试发现程序并没有访问百度地图后台失败,发现原来是密匙key出错了       通过再三调试,原来在打包成apk的时候,eclipse的用来申请密匙的sha1变了       如图示,这是eclipse原来的sha1                                                   图一  

android 基于百度地图api开发定位以及获取详细地址

一:百度地图开发必须要到百度开发平台android开发api下载相应的库,已经申请百度地图开发key. 二:新建项目baidumaplocation.设计main.xml文件这里注意的是MapView控件必须使用来自百度库封装好的com.baidu.mapapi.MapView .设计代码如下: Xml代码   <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&q

Android定位&amp;地图&amp;导航——基于百度地图实现的定位功能

一.问题描述 LBS位置服务是android应用中重要的功能,应用越来越广泛,下面我们逐步学习和实现lbs相关的应用如定位.地图.导航等,首先我们看如何基于百度地图实现定位功能 二.配置环境 1.注册密钥:地址http://developer.baidu.com/map/ 2.下载定位SDK,并导入SDK如图所示: 三.编写MyApplication类 编写MyApplication类,为了使用方便我们可以将实现定位的方法封装的Application组件中 封装下列方法 1.  获取定位信息——

使用百度定位Api获取当前用户登录地址

最近在做一个商城项目,客户想把网站做成类似于美团的效果,切换地区时,内容也跟随变化.这就要首先解决根据用户id获得地址的问题,最终决定使用百度定位(不适用于搭建反向代理的项目) String url = request.getRemoteAddr(); // url = "58.56.23.118"; //本地代码测试ip,使用本地公网 // 这里调用百度的ip定位api服务 详见 ak需要申请 // http://api.map.baidu.com/lbsapi/cloud/ip-l

Android使用百度定位SDK 方法及错误处理

之前我的项目中的位置定位使用的是基站方法,使用的Google提供的API,但是前天中午突然就不返回数据了,到网上搜了一下才知道,Google的接 口不提供服务了,基于时间紧迫用了百度现有的SDK,但是在使用过程中第一次获取位置总是空值,经过多次实验终于成功.当然,如果需要精确的位置,你可以 再加上位置偏移算法.我的应用对这个要求不高,就没做,一搜一大把,就不多说了. 下面这段话来自 百度地图API>定位SDK 百度地图定位SDK免费对外开放,无需申请key.在使用百度定位SDK前,希望先阅读百度

开源基于百度地图SDK的Android交通助手App

BaiduMap-TrafficAssistant ?? 该项目是基于百度地图SDK开发的一款交通助手App,目前已经上线豌豆荚.魅族应用市场.搜狗手机助手等多个安卓应用市场.目前我决定开源该项目,为更多的安卓应用开发者或者基于百度地图SDK开发人员提供服务和便利.当然App中还有不少bug和可扩展的功能模块,也希望各位开发者为该项目贡献自己的code力量.项目地址:https://github.com/chenyufeng1991/BaiduMap-TrafficAssistant 1.项目简