前言
公司项目使用的是高德地图,之前一直用的高德地图中的导航,但是发现使用效果很差,在差一点的机型上基本无法使用,于是决定调用第三方地图来实现。在正文开始之前先来一个实现样式图吧。
需要源码的童鞋可以直接点击下载源码
正文
一般来说,项目中用到的就如上图所示的这种效果,获取到当前位置的经纬度和目的地的经纬度,然后获取本机是否安装这些地图应用,获取到之后显示对话框,用户点击之后直接跳转到用户所选应用实现导航。
判断是否存在应用
那就一步一步来吧,首先来获取当前手机是否安装了这些三方地图应用,想要知道手机内是否安装了这些应用,就需要获取到这些应用的报名,这个一百度就能知道,贴一下吧:
private static final String PN_GAODE_MAP = "com.autonavi.minimap";// 高德地图包名 private static final String PN_BAIDU_MAP = "com.baidu.BaiduMap"; // 百度地图包名 private static final String PN_TENCENT_MAP = "com.tencent.map"; // 腾讯地图包名
获取到应用包名之后只需要判断在手机内的"/data/data"文件夹下是否存在对应包名即可判断是否安装了该应用,代码很简单,但还是贴一下吧:
private static boolean isInstallPackage(String packageName) { return new File("/data/data/" + packageName).exists(); }
如果需要判断的话只需调用上面的方法然后传入刚才的包名即可得出结果,调用方式如下:
private static boolean isGdMapInstalled() { return isInstallPackage(PN_GAODE_MAP); }
这里只展示一下调用高德地图的方式,百度和腾讯调用方式一样。
弹出对话框
这个需要弹出底部对话框,和弹出普通对话框基本一样,唯一的区别就是加两行行代码,告诉系统这个Dialog需要从底部弹出,然后即可:
bottomDialog.getWindow().setGravity(Gravity.BOTTOM);
然后给对话框设置弹出动画:
bottomDialog.getWindow().setWindowAnimations(R.style.BottomDialog_Animation);
对了,上面图片中的对话框还是透明的,这就需要给对话框设置一个样式了,将背景颜色设置为透明的:
<!--底部对话框(地图导航)样式--> <style name="BottomDialog" parent="@style/Base.V7.Theme.AppCompat.Light.Dialog"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> </style>
写好样式之后设置一下:
Dialog bottomDialog = new Dialog(context, R.style.BottomDialog);
跳转三方地图应用
跳转高德地图、百度地图、腾讯地图需要的参数都基本一样,都需要context来启动activity,需要当前位置的经纬度和目的地的经纬度,还有当前位置和目的地的名称,然后就完事了,下面是跳转腾讯地图的代码:
/** * 打开腾讯地图 * params * * @param context * @param slat 起点纬度 * @param slon 起点经度 * @param sname 起点名称 可不填(0,0,null) * @param dlat 终点纬度 * @param dlon 终点经度 * @param dname 终点名称 必填 */ public static void openTencentMap(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) { String uriString = null; StringBuilder builder = new StringBuilder("qqmap://map/routeplan?type=drive&policy=0&referer=zhongshuo"); if (slat != 0) { builder.append("&from=").append(sname) .append("&fromcoord=").append(slat) .append(",") .append(slon); } builder.append("&to=").append(dname) .append("&tocoord=").append(dlat) .append(",") .append(dlon); uriString = builder.toString(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setPackage(PN_TENCENT_MAP); intent.setData(Uri.parse(uriString)); context.startActivity(intent); }
这里我只是简单实现了腾讯地图的导航功能,如果需要更多的条件带过去的话可以去腾讯地图的官方开发文档查看具体参数以及字段的设置。腾讯地图文档:http://lbs.qq.com/uri_v1/guide-route.html
方法已经写好了,接下来就需要调用了,调用很简单,直接传入需要的参数即可,上面方法中已经说明了每个参数的含义:
openTencentMap(context, slat, slon, sname, dlat, dlon, dname);
下面是跳转百度地图导航的代码,跳转百度这里需要着重说明一下,对国内几家地图有所了解的都知道,百度用的坐标系是经过加密的一套,并不是国标、火星坐标系,所以如果需要特别精确的话需要将经纬度进行转换,转换成百度的坐标系,然后再进行传值,但这不是本文的重点,本文直接使用原始坐标传到百度地图进行操作,特此说明。
/** * 打开百度地图导航功能(默认坐标点是高德地图,需要转换) * * @param context * @param slat 起点纬度 * @param slon 起点经度 * @param sname 起点名称 可不填(0,0,null) * @param dlat 终点纬度 * @param dlon 终点经度 * @param dname 终点名称 必填 */ public static void openBaiDuNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) { String uriString = null; //终点坐标转换 需要实现的在此处进行坐标转换 double destination[] = gaoDeToBaidu(dlat, dlon); dlat = destination[0]; dlon = destination[1]; StringBuilder builder = new StringBuilder("baidumap://map/direction?mode=driving&"); if (slat != 0) { //起点坐标转换 double[] origin = gaoDeToBaidu(slat, slon); slat = origin[0]; slon = origin[1]; builder.append("origin=latlng:") .append(slat) .append(",") .append(slon) .append("|name:") .append(sname); } builder.append("&destination=latlng:") .append(dlat) .append(",") .append(dlon) .append("|name:") .append(dname); uriString = builder.toString(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setPackage(PN_BAIDU_MAP); intent.setData(Uri.parse(uriString)); context.startActivity(intent); }
调用方法很简单,和刚才调用腾讯地图的调用参数都一样,这里就不再举例。最后在贴一下高德地图的调用代码:
/** * 打开高德地图导航功能 * * @param context * @param slat 起点纬度 * @param slon 起点经度 * @param sname 起点名称 可不填(0,0,null) * @param dlat 终点纬度 * @param dlon 终点经度 * @param dname 终点名称 必填 */ public static void openGaoDeNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) { String uriString = null; StringBuilder builder = new StringBuilder("amapuri://route/plan?sourceApplication=maxuslife"); if (slat != 0) { builder.append("&sname=").append(sname) .append("&slat=").append(slat) .append("&slon=").append(slon); } builder.append("&dlat=").append(dlat) .append("&dlon=").append(dlon) .append("&dname=").append(dname) .append("&dev=0") .append("&t=0"); uriString = builder.toString(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setPackage(PN_GAODE_MAP); intent.setData(Uri.parse(uriString)); context.startActivity(intent); }
总结
本文其实内容很简单,只是将知识点串了起来,本文中涉及到的所有代码我都放在一个Demo中了,下面是本Demo的截图: