Android studio 百度地图开发(5)查询周边服务(加油站)

email:chentravelling@163.com

开发环境:win7 64位,Android Studio,请注意是Android Studio,使用的导航SDK版本:3.1.0

  • 百度地图应用(1):Android studio 百度地图开发(1)配置工程、显示地图
  • 百度地图应用(2)Android studio 百度地图开发(2)地图定位
  • 百度地图应用(3):Android studio 百度地图开发(3)地图导航
  • 百度地图应用(4):Android studio 百度地图开发(4)触摸选点、地理编码

一.功能描述

大致功能为:通过百度地图定位获得当前位置,然后通过加油站数据接口(https://www.juhe.cn/docs/api/id/7)搜索周边的加油站信息,并在地图上显示。这里,我把访问加油站数据接口的部分放在了服务器上,因为后期还有一些其他功能,不可能都放在手机端去实现。

二.实现部分

1.加油站数据接口

需要先申请api_key,很简单,没有百度地图的API_KEY那么复杂,地址:https://www.juhe.cn/docs/api/id/7。

2.搭建服务器

这部分,本人不知道怎么去描述,因为有web基础,使用过SSM(spring+springMVC+Mybatis)架构,所以还是继续使用SSM。关于SSM架构的服务器环境搭建,资料很多,就不赘述了,而且,主要功能并不在于服务器上,换一个架构甚至“没有架构”都行。

在服务器端主要要实现对加油站数据的访问,按照官方的API说明,通过以下代码实现了数据访问:

package com.intveh.component.gas.controller;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.util.HashMap;import java.util.Map; import net.sf.json.JSONArray;import net.sf.json.JSONObject;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.intveh.component.car.model.Car;@Controllerpublic class GasController {public static final String DEF_CHATSET = "UTF-8";public static final int DEF_CONN_TIMEOUT = 30000;public static final int DEF_READ_TIMEOUT = 30000;public static String userAgent =  "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"; /** * 请求接口地址 */public static String url = "http://apis.juhe.cn/oil/local";/** * AppKey */public static String key = "cbee44f8a21c371***********51e8b9";//改为自己的key /** * 查询附近的加油站 *  * @param 经纬度 *             * @return 查询结果 json */@RequestMapping(value = "/gas/searchNear")@ResponseBodypublic void searchNear(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{//response.setHeader("Access-Control-Allow-Origin", "*");//Car car = carDAO.getCar(carId);//return car;String result = "";//System.out.println("开始搜索");/** * 纬度 */String latitude = request.getParameter("latitude");/** * 经度 */String longitude = request.getParameter("longitude");/** * 搜索范围 */String radius = request.getParameter("radius")==null?"1000":request.getParameter("radius");/** * 页数 */String page = "1";/** * 格式 */String format = "1";//System.out.println(longitude+","+latitude+","+radius+","+page+","+format);Map params = new HashMap();if(latitude!=null&&longitude!=null&&!"".equals(latitude)&&!"".equals(longitude)){params.put("lon", longitude);params.put("lat", latitude);params.put("r", radius);params.put("page", page);params.put("format",format);params.put("key", key);JSONObject object = new JSONObject();//System.out.println(longitude+","+latitude+","+radius+","+page+","+format);try{result =net(url, params, "GET");            object = JSONObject.fromObject(result);            if(object.getInt("error_code")==0){                System.out.println(object.get("result"));                            }else{               System.out.println(object.get("error_code")+":"+object.get("reason"));            }response.setContentType("text/json; charset=UTF-8");response.getOutputStream().write(object.get("result").toString().getBytes("UTF-8")); //System.out.println(object.get("result"));        } catch (Exception e) {            e.printStackTrace();        }//response.setHeader("Access-Control-Allow-Origin", "*");//response.reset();//response.setContentType(String);//response.getOutputStream().write(object.toString().getBytes("UTF-8"));}}/**    *    * @param strUrl 请求地址    * @param params 请求参数    * @param method 请求方法    * @return  网络请求字符串    * @throws Exception    */   public static String net(String strUrl, Map params,String method) throws Exception {       HttpURLConnection conn = null;       BufferedReader reader = null;       String rs = null;       try {           StringBuffer sb = new StringBuffer();           if(method==null || method.equals("GET")){               strUrl = strUrl+"?"+urlencode(params);           }           URL url = new URL(strUrl);           System.out.println("url = "+url);           conn = (HttpURLConnection) url.openConnection();           if(method==null || method.equals("GET")){               conn.setRequestMethod("GET");           }else{               conn.setRequestMethod("POST");               conn.setDoOutput(true);           }           conn.setRequestProperty("User-agent", userAgent);           conn.setUseCaches(false);           conn.setConnectTimeout(DEF_CONN_TIMEOUT);           conn.setReadTimeout(DEF_READ_TIMEOUT);           conn.setInstanceFollowRedirects(false);           conn.connect();       /*    if (params!= null && method.equals("POST")) {               try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {                   out.writeBytes(urlencode(params));               }           }*/           InputStream is = conn.getInputStream();           reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));           String strRead = null;           while ((strRead = reader.readLine()) != null) {               sb.append(strRead);           }           rs = sb.toString();       } catch (IOException e) {           e.printStackTrace();       } finally {           if (reader != null) {               reader.close();           }           if (conn != null) {               conn.disconnect();           }       }       return rs;   }   //将map型转为请求参数型   public static String urlencode(Map<String,Object>data) {       StringBuilder sb = new StringBuilder();       for (Map.Entry i : data.entrySet()) {           try {               sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue()+"","UTF-8")).append("&");           } catch (UnsupportedEncodingException e) {               e.printStackTrace();           }       }       return sb.toString();   }}
使用一下数据访问服务器即可查看获得的加油站信息:


3.手机端实现

(对于我)稍微有点难度的还是在手机端功能的实现。

第一步:加油站信息类GasStationModel.java

为了更加方便的传递数据,写了一个加油站信息类,对数据实体化。同时实现了Serializable接口,因为后面需要利用intent传递list<GasStationModel>时,将list强制转化成serializable。

package intvehapp.intvehapp;import java.io.Serializable;import java.util.Map;/** * Created by chen on 2016/4/2. */public class GasStationModel implements Serializable {    public GasStationModel(            String area,            String fwlsmc,            String address,            String areaname,            String distance,            String exhaust,            String discount,            String lon,            String brandname,            String type,            Map<String,String> price,            Map<String,String> gastprice,            String name,            String id,            String lat,            String position)    {        this.area = area;        this.address = address;        this.areaname = areaname;        this.brandname = brandname;        this.discount = discount;        this.distance = distance;        this.exhaust = exhaust;        this.fwlsmc = fwlsmc;        this.gastprice = gastprice;        this.id = id;        this.price = price;        this.lon = lon;        this.type = type;        this.name = name;        this.lat = lat;        this.position = position;    }    /**     * 邮编     */    private String area;    /**     * 加油卡信息     */    private String fwlsmc;    /**     * 加油站地址     */    private String address;    /**     * 城市区域     */    private String areaname;    /**     * 距离?     */    private String distance;    /**     * 尾气排放标准     */    private String exhaust;    /**     * 是否打折加油站     */    private String discount;    /**     * 百度地图经度     */    private String lon;    /**     * 运营商类型     */    private String brandname;    /**     * 加油站类型     */    private String type;    /**     * 省控基准油价     */    private Map<String,String> price;    /**     * 加油站油价     */    private Map<String,String> gastprice;    /**     * 加油站名字     */    private String name;    /**     * id     */    private String id;    /**     * 谷歌地图坐标     */    private String position;    /**     * 百度地图纬度     */    private String lat;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getArea() {        return area;    }    public void setArea(String area) {        this.area = area;    }    public String getFwlsmc() {        return fwlsmc;    }    public void setFwlsmc(String fwlsmc) {        this.fwlsmc = fwlsmc;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }    public String getAreaname() {        return areaname;    }    public void setAreaname(String areaname) {        this.areaname = areaname;    }    public String getDistance() {        return distance;    }    public void setDistance(String distance) {        this.distance = distance;    }    public String getDiscount() {        return discount;    }    public void setDiscount(String discount) {        this.discount = discount;    }    public String getExhaust() {        return exhaust;    }    public void setExhaust(String exhaust) {        this.exhaust = exhaust;    }    public String getLon() {        return lon;    }    public void setLon(String lon) {        this.lon = lon;    }    public String getBrandname() {        return brandname;    }    public void setBrandname(String brandname) {        this.brandname = brandname;    }    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    public Map<String, String> getPrice() {        return price;    }    public void setPrice(Map<String, String> price) {        this.price = price;    }    public Map<String, String> getGastprice() {        return gastprice;    }    public void setGastprice(Map<String, String> gastprice) {        this.gastprice = gastprice;    }    public String getPosition() {        return position;    }    public void setPosition(String position) {        this.position = position;    }    public String getLat() {        return lat;    }    public void setLat(String lat) {        this.lat = lat;    }}

第二步:新建线程访问数据,通过handler与主线程通信。

一开始,直接在主线程中访问服务器,最终发现失败了,查阅了资料后才知道:android4.0以后的版本,主线程(UI线程)不在支持网络请求,原因大概是影响主线程,速度太慢,容易卡机,所以需要开启新的线程请求数据。

 /**                 * 通过handler与主线程通信                 */                final Handler handler = new Handler()                {                    @Override                    public void handleMessage(Message msg) {                        super.handleMessage(msg);                        Bundle data = msg.getData();                        String err = data.getString("err");                        /**                         * 查询成功                         */                        if("0".equals(err))                        {                            List<GasStationModel> listGasStation = (List<GasStationModel> )data.getSerializable("listGasStation");                            Toast.makeText(BaiDuMapActivity.this, "查询成功"+listGasStation.size(), Toast.LENGTH_LONG).show();                            }                        else                        {                            Toast.makeText(BaiDuMapActivity.this, "附近没有加油站信息", Toast.LENGTH_LONG).show();                        }                        //Log.i("mylog", "请求结果为-->" + val);                        // TODO                        // UI界面的更新等相关操作                    }                };                /**                 * 开启一个新的线程,访问服务器                 * 当有数据返回时,通过handler传递消息                 */                new Thread(new Runnable() {                    @Override                    public void run() {                        //请求数据                        List<GasStationModel> listGasStation = ConnectServer.searchNearGas(params);                        //发送消息                        Message message = new Message();                        Bundle bundle = new Bundle();                        if(listGasStation!=null)                        {                            bundle.putSerializable("listGasStation", (Serializable) listGasStation);                            bundle.putString("err","0");//成功                        }                        else                            bundle.putString("err","1");//失败                        message.setData(bundle);                        handler.sendMessage(message);                    }                }).start();

第三步:ConnectServer.java访问服务器类

考虑到后期对服务器访问还会很多,所以就单独建了一个访问服务器的类。

实现对服务器的访问,搜索周边加油站。

/** * Created by chen on 2016/4/2. */public class ConnectServer {        public static List<GasStationModel> searchNearGas(Map<String, String> params)    {        /**         * 请求地址         */        String path = serverURL+"gas/searchNear?key="+key+"&";        /**         * 添加参数         */        List<GasStationModel> listGasStation = new ArrayList<GasStationModel>();        try {            StringBuilder url = new StringBuilder(path);            URL nURL = new URL("http://www.baidu.com");            //url.append("?");            for (Map.Entry<String, String> entry : params.entrySet()) {                url.append(entry.getKey()).append("=");                url.append(URLEncoder.encode(entry.getValue(), "UTF-8"));// 编码                url.append('&');            }            url.deleteCharAt(url.length() - 1);            HttpURLConnection connection = (HttpURLConnection) new URL(                    url.toString()).openConnection();           //HttpURLConnection connection = (HttpURLConnection) nURL.openConnection();            connection.setConnectTimeout(5000);            connection.setRequestMethod("GET");            String result = "";            InputStream in = connection.getInputStream();            try {                Thread.sleep(300);                result = read(connection.getInputStream());            } catch (InterruptedException e) {                e.printStackTrace();            }                      /**             * 解析JSON数据等等<span style="font-family:Microsoft YaHei;">操作</span>             */                       }        }catch (Exception e )        {            e.printStackTrace();        }        return listGasStation;    }    private static String read(InputStream in) throws Exception {        byte[] data;        int length = in.available();        ByteArrayOutputStream bout = new ByteArrayOutputStream();        byte[]buf = new byte[1024];        int len = 0;        while((len = in.read(buf))!=-1){            bout.write(buf, 0, len);        }        data = bout.toByteArray();        return new String(data,"UTF-8");    }}

三.效果与分析


其实整个流程的思路还是很简单:定位获取当前数据->访问加油站数据接口获得周边加油站位置信息->回调,在地图上显示。但是,实现起来有些地方还是很费心,比如手机端接收数据不完整的情况。

更多相关文章

  1. Android使用HttpURLConnection进行POST请求,向服务器上传数据
  2. android 百度地图类参考 MKGeneralListener
  3. Android数据库中查找一条数据使用的方法 query详解
  4. udacity android 学习笔记: lesson 4 part a
  5. android数据保存
  6. zz:Android使用HttpPost向服务器发送Json数据
  7. 在android中使用Realm数据库
  8. Android函数响应式编程——必学的RxJava组合操作符startWith、me
  9. android-market-api

随机推荐

  1. Android消息机制之三---Message
  2. Android中ProgressDialog的简单示例
  3. Android(安卓)Studio添加aar依赖的两种方
  4. android project 文件夹
  5. 使用air进行移动app开发常见功能和问题(二
  6. 使用Android系统自带的icon图标
  7. android:shape的使用
  8. android调用系统发短信界面功能
  9. Android(安卓)requires compiler complia
  10. Android(安卓)studio生成APK打包,修改生成