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

Posted 生活没有if-else

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android studio 百度地图开发查询周边服务(加油站)相关的知识,希望对你有一定的参考价值。

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

email:chentravelling@163.com

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

一.功能描述

      大致功能为:通过百度地图定位获得当前位置,然后通过加油站数据接口(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;

@Controller
public 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")
	@ResponseBody
	public 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");
    }
}

三.效果与分析


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

以上是关于Android studio 百度地图开发查询周边服务(加油站)的主要内容,如果未能解决你的问题,请参考以下文章

Android 百度地图周边雷达(v6.1.3)及覆盖物

Android studio 百度地图开发地图导航

Android studio 百度地图开发地图定位

百度地图实现普通地图定位周边搜索功能

Android studio 百度地图开发之2022地图显示与定位

android 怎么使用地图生成工具