android开发游记:APP内部调启百度、高德、web地图导航

原创 2016年03月12日 11:05:44

一些地图相关的app一般都需要集成导航的功能方便用户使用,但实际上我们很多时候仅仅只是希望提供这样一个贴心的功能把用户送到目的地,而并不会在导航过程中进行自己的业务的处理,这样把导航的功能完全独立出来了,像这样的需求我们就不用在app里自己去集成导航的功能,而是启调用户手机里已有的导航工具这样不是更好吗,像购物类的应用只需要关心导航的结果把用户送到商城,而不关心其过程。调启用户已安装地图工具来导航用户自然也更加熟悉自己常用的地图工具。这样反而方便了用户也简单了我们的应用。那么如何在自己app内检测安装的地图工具并启调呢:

这里写图片描述 这里写图片描述

这里写图片描述

由于目前提供地图工具的各种三方的启调方法和参数都不一样,所有不能直接使用资源管理器来打开地图工具,只能自己去用户手机里检测地图工具,并更具用户的选择不同而使用不同的启调方式来启调地图工具。

我做了一个demo,可以启调百度和高度地图,由于腾讯地图没有提供启调接口所以并不支持,如果用户手机没有安装地图工具会提示在浏览器中启调百度提供的web导航:

这里写图片描述 这里写图片描述

下面是下载地址:
调启百度、高德地图导航Demo

先说一下在自己工程中的使用方法,在解释实现方法

使用方法:

把下面的所有类和layout下的所有部件文件拷贝到自己工程:

这里写图片描述

然后在需要启调的地方执行下面代码弹出选择启调app的对话框就可以了,该对话框内部会自动检测用户手机应用,决定是打开地图工具还是启用web导航:

    NativeDialog msgDialog = new NativeDialog(this, loc_now, loc_end);
    msgDialog.show();

这样就可以运行了,使用方法很简单,所有逻辑都封装在NativeDialog对话框里处理了。

下面解释主要代码:

功能上主要分成2个部分:

  1. 如何获取手机中的地图工具应用
  2. 如何启调这些应用

首先,获取地图工具app没有直接的方法,尝试了各种通过过滤来筛选的方法都达不到想要的效果,而且并不是每一种地图工具都能支持启调,比如搜狗地图。目前市面主流的就百度和高德支持,至于腾讯地图官网给的说法是即将支持。这样我们就只能获取手机中所有app的信息来进行筛选,我们只筛选高德和百度,那么我们怎么来筛选呢。每个app都有一个唯一的包名,我们通过对比包名来筛选app,首先我们定义一个集合里面存放需要匹配的应用的包名:

public static String[] paks = new String[]{"com.baidu.BaiduMap",        //百度
                                           "com.autonavi.minimap"};     //高德

通过getInstalledPackages方法可以获取到应用所有的app信息:

List<PackageInfo> packageInfos = context.getPackageManager().getInstalledPackages(0);

我们可以先定义一个方法通过包名来筛选app:

    /**
     * 通过包名获取应用信息
     * @param context
     * @param packageName
     * @return
     */
    public static AppInfo getAppInfoByPak(Context context, String packageName){
        PackageManager packageManager = context.getPackageManager();
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        for (PackageInfo packageInfo : packageInfos) {
            if (packageName.equals(packageInfo.packageName)) {
                AppInfo tmpInfo =new AppInfo(); 
                tmpInfo.setAppName(packageInfo.applicationInfo
                        .loadLabel(packageManager).toString()); 
                tmpInfo.setPackageName(packageInfo.packageName); 
                tmpInfo.setVersionName(packageInfo.versionName); 
                tmpInfo.setVersionCode(packageInfo.versionCode); 
                tmpInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(packageManager));
                return tmpInfo;
            }
        }
        return null;
    }

然后调用上面的方法把集合中的报名逐个进行匹配:

    /**
     * 返回当前设备上的地图应用集合
     * @param context
     * @return
     */
    public static List<AppInfo> getMapApps(Context context) {
        LinkedList<AppInfo> apps = new LinkedList<AppInfo>();
        for (String pak : paks) {
            AppInfo appinfo = getAppInfoByPak(context,pak);
            if (appinfo!=null) {
                apps.add(appinfo);
            }
        }
        return apps;
    }

然后在初始化对话框的时候根据匹配的结果动态生成布局,给弹出窗设置应用的名称和图标:

for (int i = 0; i < apps.size(); i++) {
    AppInfo app = apps.get(i);
    //定义左右边距15
    LinearLayout.LayoutParams para = new  LinearLayout.LayoutParams(
                            LayoutParams.WRAP_CONTENT, 
                            LayoutParams.WRAP_CONTENT);
    para.setMargins(15, 0, 15, 0); // left,top,right, bottom
    para.gravity = Gravity.CENTER;

    TextView textView = new TextView(context);
    textView.setCompoundDrawablesWithIntrinsicBounds(null,app.getAppIcon(), null, null);    //设置图标
    textView.setText(app.getAppName());                             //设置文字
    textView.setTextAppearance(context, R.style.text_small_dark);   //设置风格
    textView.setLayoutParams(para);                                 //设置边距
    textView.setGravity(Gravity.CENTER_HORIZONTAL);                 //设置图标文字水平居中
    textView.setSingleLine(true);                                   //设置单行显示
    textView.setEllipsize(TruncateAt.END);                          //设置超出长度显示省略…
    textView.setMaxEms(6);                                          //设置最大长度
    textView.setTag(app.getPackageName());                          //设置包名为tag
    textView.setOnClickListener(applistener);                       //设置监听

    views.add(textView);
    ...
}

这样就完成了第一步。现在获取到了应用的信息,那么如何启调呢。
每个三方应用的启调方式都不同,这就要查阅官方文档,然后制订相应的方法来启调它,这里我总结了目前市面上可启调的地图应用,把启调方法都封装在一个工具类里AppUtil,里面给出了百度高德和web浏览器的几种启调方法:

这里写图片描述

这里贴上高德和百度地图的通过Intent启调的方法:

    public static void startNative_Baidu(Context context,Location loc1,Location loc2){
        if (loc1==null || loc2==null) {
            return;
        }
        if (loc1.getAddress()==null || "".equals(loc1.getAddress())) {
            loc1.setAddress("我的位置");
        }
        if (loc2.getAddress()==null || "".equals(loc2.getAddress())) {
            loc2.setAddress("目的地");
        }
        try {
            Intent intent = Intent.getIntent("intent://map/direction?origin=latlng:"+loc1.getStringLatLng()+"|name:"+loc1.getAddress()+"&destination=latlng:"+loc2.getStringLatLng()+"|name:"+loc2.getAddress()+"&mode=driving&src=重庆快易科技|CC房车-车主#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(context, "地址解析错误", Toast.LENGTH_SHORT).show();
        }
    }

    public static void startNative_Gaode(Context context,Location loc){
        if (loc==null) {
            return;
        }
        if (loc.getAddress()==null || "".equals(loc.getAddress())) {
            loc.setAddress("目的地");
        }
        try {
            Intent intent = new Intent("android.intent.action.VIEW",
            android.net.Uri.parse("androidamap://navi?sourceApplication=CC房车-车主&poiname=重庆快易科技&lat="+loc.getLat()+"&lon="+loc.getLng()+"&dev=1&style=2"));
            intent.setPackage("com.autonavi.minimap");
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(context, "地址解析错误", Toast.LENGTH_SHORT).show();
        }
    }

其中传入的参数Location类型是封装坐标的实体类,如下:

public class Location implements Serializable{
    private double lat;         //坐标纬度
    private double lng;         //坐标经度
    private String address;     //地址
    //get&set方法
}

注意高德地图参数只需要终点坐标就可以了,而百度地图启调导航需要一个起始坐标和终点坐标,起始坐标就是你的当前位置你要自行获取。

实际运行后发现,高德地图启调后直接进入导航,而百度地图会先进入路径规划页面,下面有个开始导航的按钮点击后才会开始导航:
这里写图片描述

虽然要多点一下,但事实上用户并不喜欢这样,难度百度地图就不能直接进入导航吗,自行研究发现百度地图也可以启调后直接进入导航,不过要使用SDK提供的方法来进行启调,这就必须在工程中导入百度的SDK,导入后直接使用下面的方法就可以了:

    //######################################
    //通过SDK接口启调地图工具
    //######################################

    public static void startNativeBySDK_Baidu(Context context,Location loc1,Location loc2){
        if (loc1==null || loc2==null) {
            return;
        }
        if (loc1.getAddress()==null || "".equals(loc1.getAddress())) {
            loc1.setAddress("我的位置");
        }
        if (loc2.getAddress()==null || "".equals(loc2.getAddress())) {
            loc2.setAddress("目的地");
        }

        NaviParaOption para = new NaviParaOption().startPoint(MyDistanceUtil.entity2Baidu(loc1))
                                                  .startName(loc1.getAddress())
                                                  .endPoint(MyDistanceUtil.entity2Baidu(loc2))
                                                  .endName(loc2.getAddress());
        try {
            BaiduMapNavigation.openBaiduMapNavi(para, context);
        } catch (BaiduMapAppNotSupportNaviException e) {
            e.printStackTrace();
            Toast.makeText(context, "地址解析错误", Toast.LENGTH_SHORT).show();
        }
    }

使用这种方式就可以直接进入导航,但是麻烦的是必须导入SDK,真是不知道百度这样设计的用意是…

如果用户手机没有装地图工具,那么就启调默认浏览器调用web导航,目前就只有百度提供了在浏览器中的导航支持,同样的也有两种启调方式,一种外部直接调,一种使用SDK调用…

        //###########################################
        //第一种方式:这种方式需要导入百度sdk,才能进行启调,如果没导入会找不到类
        //建议使用这种方式,对浏览器的兼容更好。
        //注释掉这里段代码,取消下面第二种方式的注释可以启用第二种方式
        NaviParaOption para = new NaviParaOption()
                        .startPoint(MyDistanceUtil.entity2Baidu(loc_now))
                        .endPoint(MyDistanceUtil.entity2Baidu(loc_end));
        BaiduMapNavigation.openWebBaiduMapNavi(para, context);
        //###########################################


        //第二种方式:这种方式不需要导入百度sdk,可以直接使用
        //不推建使用这种方式,浏览器兼容问题比较严重,比如qq浏览器会封杀百度的此功能。
        //注释掉这里段代码,取消上面第一种方式的注释可以启用第一种方式
        //###########################################
        //String url = APPUtil.getWebUrl_Baidu(loc_now, loc_end);
        //Intent intent = new Intent(Intent.ACTION_VIEW);
        //intent.setData(Uri.parse(url));
        //context.startActivity(intent);
        //###########################################

上面调用的一个静态方法,用于构建启调Intent的url:

    //######################################
    //通启调web地图
    //######################################

    public static String getWebUrl_Baidu(Location loc1,Location loc2){
        if (loc1==null || loc2==null) {
            return null;
        }
        if (loc1.getAddress()==null || "".equals(loc1.getAddress())) {
            loc1.setAddress("我的位置");
        }
        if (loc2.getAddress()==null || "".equals(loc2.getAddress())) {
            loc2.setAddress("目的地");
        }

        return "http://api.map.baidu.com/direction?origin=latlng:"+loc1.getStringLatLng()+"|name:"+loc1.getAddress()+"&destination=latlng:"+loc2.getStringLatLng()+"|name:"+loc2.getAddress()+"&mode=driving&src=重庆快易科技|CC房车-车主";
    }
版权声明:本文为博主原创文章,未经博主允许不得转载。

Android使用intent调取导航或者地图

关于APP的URL Scheme相关内容这里就不介绍了 大家可以自行去研究研究这里主要介绍地图的相关知识,未来有时间给大家上个demo。 百度地图:http://lbsyun.baidu.com/i...

安卓通过经纬度,实现intent调用百度,高德,Google地图客户端实现驾车导航功能

大家在开发中实现多套地图实现导航功能,导入sdk会增大APK体积,且繁琐,但是在代码可以通过Intent就可以直接调用百度地图客户端、高德地图客户端、Google 地图客户端实现导航功能!话不多说直接...

Android应用中打开百度地图、高德地图、网页版百度地图

1.需求在Android应用中打开百度地图或者高德地图进行路线规划,如果没有安装则打开网页百度地图进行路线规划。2.API2.1 打开百度地图应用地址:http://lbsyun.baidu.com/...

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

1.效果终于有点时间了,将项目中调用外部地图(高德和百度)做个总结吧! 2.干货在做这个需求前首先要知道一些东西。 1. 导航一定有起点和终点,一般起点和终点有两种形式,坐标和名称。 ...

Android之调用高德地图或百度地图原生app

今天做一个路径规划的功能,需要使用到高德地图,或是百度地图,然后想着怎样的实现比较好。刚好也在看前程无忧,它里面就是点击导航的话会先检查本机是否安装了这些地图app,如果有的话,就直接打开使用,没有的...

android 调用百度地图apk应用的导航功能 SDK调用

百度地图Android SDK V2.1.1为广大开发者提供调起百度地图客户端Android版(v5.0及以上版本)导航功能。 第一种方案:直接调用SDK实现跳转到百度应用实现导航 代码: pu...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Android调用第三方高德APP进行导航

首先注意的是手机端必须要装有高德地图APP,可以到高德官网下载:http://www.autonavi.com/ 封装工具类如下: /** * Description * TODO * Aut...

第三方应用调用高德地图

http://www.eoeandroid.com/thread-540298-1-1.html 项目中要直接调用高德地图应用,而不是高德地图API。 点击直接调用高德地进行导航,肯定需要传参...

Android调起百度和高德地图导航(不导入SDK)

Android调起百度和高德地图导航(不导入SDK)    在开发项目的过程中,我们难免会遇到导航的功能,如果我们只需要某一个地方用到此功能,我们就不必去集成地图的SDK,因为我们需要的功能不多,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android开发游记:APP内部调启百度、高德、web地图导航
举报原因:
原因补充:

(最多只允许输入30个字)