android调用外部地图APP导航路线规划全解

来源:互联网 发布:那个淘宝网站的商品是正品 编辑:程序博客网 时间:2024/04/30 16:38

1.效果

终于有点时间了,将项目中调用外部地图(高德和百度)做个总结吧!
这里写图片描述
这里写图片描述

2.干货

在做这个需求前首先要知道一些东西。
1. 导航一定有起点和终点,一般起点和终点有两种形式,坐标和名称。
2. 坐标一般常见的有三种火星坐标、百度坐标、高德坐标
3. 通过百度定位或者通过名字反编码出来的坐标都是百度坐标
4. 通过高德定位或者通过名字反编码出来的坐标都是高德坐标,不是火星坐标,我看资料的时候总是见别人说是火星坐标,但是高德sdk里面说了是高德坐标,见
https://lbs.amap.com/api/android-location-sdk/guide/android-location/getlocation#stop-location
5.导航参数中如果有坐标,坐标的优先级大于名字

我从下面6个不同的方向测试了下,到底怎样写请求参数准确最高
1.起点终点都是坐标使用高德
2.起点终点都是名称使用高德
3.当前位置到终点使用高德
4.起点终点都是坐标使用百度
5.起点终点都是名称使用百度
6.当前位置到终点使用百度

我们做项目一般都只是会集成其中的一个 要么百度要么高德sdk,所以其中只要牵扯到坐标都是相关的坐标系,我这里为了省事,使用坐标拾取来获取坐标测试

先来测试前面三个调用高德地图的,我用高德拾取 弄了两个位置坐标,如下

   private static final double LATITUDE_A = 28.1903;  //起点纬度    private static final double LONGTITUDE_A = 113.031738;  //起点经度    private static final double LATITUDE_B = 28.187519;  //终点纬度    private static final double LONGTITUDE_B = 113.029713;  //终点经度

先将这个方法写出来,判断客户端是否安装

    /**     * 判断是否安装目标应用     * @param packageName 目标应用安装后的包名     * @return 是否已安装目标应用     */    private boolean isInstallByread(String packageName) {        return new File("/data/data/" + packageName).exists();    }

对于第一种情况,使用起点和终点的坐标如下

   /**     * 确定起终点坐标BY高德     */    void setUpGaodeAppByLoca(){        try {            Intent intent = Intent.getIntent("androidamap://route?sourceApplication=softname&slat="+LATITUDE_A+"&slon="+LONGTITUDE_A+"&sname="+"万家丽国际Mall"+"&dlat="+LATITUDE_B+"&dlon="+LONGTITUDE_B+"&dname="+"东郡华城广场|A座"+"&dev=0&m=0&t=1");            if(isInstallByread("com.autonavi.minimap")){                startActivity(intent);                Log.e(TAG, "高德地图客户端已经安装") ;            }else {                Log.e(TAG, "没有安装高德地图客户端") ;            }        } catch (URISyntaxException e) {            e.printStackTrace();        }    }

可以发现,其中的起点和终点都有坐标并且都有名称,运行后发现效果并不是很好,因为有一个公交规划路线没有,但是其实是有的,下面的方法测试时可以看到,这样就知道坐标的优先级要比名字高

第二个情况,起点终点都是名称

   /**     * 确认起终点名称BY高德     */    void setUpGaodeAppByName(){        try {            Intent intent = Intent.getIntent("androidamap://route?sourceApplication=softname"+"&sname="+"万家丽国际Mall"+"&dname="+"东郡华城广场|A座"+"&dev=0&m=0&t=1");            if(isInstallByread("com.autonavi.minimap")){                startActivity(intent);                Log.e(TAG, "高德地图客户端已经安装") ;            }else {                Log.e(TAG, "没有安装高德地图客户端") ;            }        } catch (URISyntaxException e) {            e.printStackTrace();        }    }

通过这种方法所有的导航规划路线都可以查到,比较不错,这里有个小技巧,起点和终点的名称最好不要写的太广了,举个例子这里的起点写的是万家丽国际mall 如果你写成湖南省长沙市芙蓉区万家丽国际mall,很容易出问题,这里的问题指找不到导航规划路线,本人就是在这里对地址没处理导致一直找不到原因

第三个情况实际上是最好用的方法,如下

   /**     * 我的位置BY高德     */    void setUpGaodeAppByMine(){        try {             Intent intent = Intent.getIntent("androidamap://route?sourceApplication=softname&sname=我的位置&dlat="+LATITUDE_B+"&dlon="+LONGTITUDE_B+"&dname="+"东郡华城广场|A座"+"&dev=0&m=0&t=1");            if(isInstallByread("com.autonavi.minimap")){                startActivity(intent);                Log.e(TAG, "高德地图客户端已经安装") ;            }else {                Log.e(TAG, "没有安装高德地图客户端") ;            }        } catch (URISyntaxException e) {            e.printStackTrace();        }    }

这个方法好用而且实际,毕竟导航一般都是通过当前位置去终点,使用上面的方法直接写入参数 我的位置 就可以了,这样进入高德或者百度地图app中直接就给定位了获取到当前位置了。不用在自己的项目中通过sdk获取到当前位置的坐标然后传入参数,既不准确又麻烦。

下面的是调用百度地图app,同样通过百度拾取 取了两个位置的百度坐标

   //----------------以下都是百度坐标系的坐标------------------//    private static final double LATITUDE_QIDIAN = 28.196744;  //起点纬度    private static final double LONGTITUDE_QIDIAN = 113.037904;  //起点经度    private static final double LATITUDE_ZHONGDIAN = 28.193159;  //终点纬度    private static final double LONGTITUDE_ZHONGDIAN = 113.036427;  //终点经度

第四种情况,使用起点和终点的坐标

    /**     * 注意下面的起终点坐标都是百度坐标,如果使用高德坐标系有很大的误差     */    void setUpBaiduAPPByLoca(){        try {            Intent intent = Intent.getIntent("intent://map/direction?origin=latlng:"+LATITUDE_QIDIAN+","+LONGTITUDE_QIDIAN+"|name:万家丽国际Mall&destination=latlng:"+LATITUDE_ZHONGDIAN+","+LONGTITUDE_ZHONGDIAN+"|name:东郡华城广场|A座&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");            if(isInstallByread("com.baidu.BaiduMap")){                startActivity(intent);                Log.e(TAG, "百度地图客户端已经安装") ;            }else {                Log.e(TAG, "没有安装百度地图客户端") ;            }        } catch (URISyntaxException e) {            e.printStackTrace();        }    }

这里特别要注意,比如项目中使用高德sdk,获取坐标后上面的方法导航会有很大的误差(相对的),毕竟调用百度地图已经进入了app中,在百度地图里面使用高德坐标系应该也应该是有误差的,可以将上面的两个高德坐标系的坐标放上面的方法试一试,话说我开始还想过要不要将高德坐标系的坐标换算成火星坐标 然后在换算成百度坐标 再写入上面的方法……

第五种情况,起点和终点两个名称

/**     * 通过起终点名字使用百度地图     */    void setUpBaiduAPPByName(){        try {            Intent intent = Intent.getIntent("intent://map/direction?origin=万家丽国际Mall&destination=东郡华城广场|A座&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");            if(isInstallByread("com.baidu.BaiduMap")){                startActivity(intent);                Log.e(TAG, "百度地图客户端已经安装") ;            }else {                Log.e(TAG, "没有安装百度地图客户端") ;            }        } catch (URISyntaxException e) {            e.printStackTrace();        }    }

这个url我测试了很多遍才试出来,开始一直搞错了,虽然可以进入百度app但是起点和终点名称总是出错的。

第六种情况,当前位置到终点导航规划路线

   /**     * 我的位置到终点通过百度地图     */    void setUpBaiduAPPByMine(){        try {            Intent intent = Intent.getIntent("intent://map/direction?origin=我的位置&destination=东郡华城广场|A座&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");            if(isInstallByread("com.baidu.BaiduMap")){                startActivity(intent);                Log.e(TAG, "百度地图客户端已经安装") ;            }else {                Log.e(TAG, "没有安装百度地图客户端") ;            }        } catch (URISyntaxException e) {            e.printStackTrace();        }    }

这里和第三种高德一样的,比较好

ok,已经完了可以根据自己的实际情况来选择,或者通过上面url的规律自己拼接。

3.项目源码

https://github.com/GuoZhaoHui628/AppMapNavi

3 0