各自官网注册开发者,建立应用,获取对应的key,下载高德、百度、腾讯jar包引入项目 AndroidManifest.xml引入

<!-- 百度地图 -->
<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="key" />

<service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote" /> 
<!-- 百度地图 -->
<!-- 高德地图 -->
<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="key" /> 
<service android:name="com.amap.api.location.APSService" /> 
<!-- 高德地图 -->

新建WindowDialogView.class类,底部弹框选择需要导航的类型

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
/**
 * 需要增加回调或者导航地图在map_nav中自己新增,windowDialogListener中新增点击回调
 */
public class WindowDialogView {

    public static void WindowDialogView(Activity activity, windowDialogListener listener) {
        // 参数2:设置BottomSheetDialog的主题样式;将背景设置为transparent,这样我们写的shape_bottom_sheet_dialog.xml才会起作用
        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(activity, R.style.BottomSheetDialog);
        //不传第二个参数
        //BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);

        // 底部弹出的布局
        View bottomView = LayoutInflater.from(activity).inflate(R.layout.map_nav, null);


        TextView gdMap = bottomView.findViewById(R.id.gdMap);
        TextView bdMap = bottomView.findViewById(R.id.bdMap);
        TextView cancel = bottomView.findViewById(R.id.cancel);

        bottomSheetDialog.setContentView(bottomView);
        //设置点击dialog外部不消失
        //bottomSheetDialog.setCanceledOnTouchOutside(false);
        bottomSheetDialog.show();

        gdMap.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onGDNav();
            }
        });
        bdMap.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onBDNav();
            }
        });
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.cencel();
                bottomSheetDialog.dismiss();
            }
        });
    }

    public interface windowDialogListener {
        /**
         * 高德导航
         */
        void onGDNav();

        /**
         * 百度导航
         */
        void onBDNav();

        void cencel();

    }
}

新建map_nav.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff"
    android:orientation="vertical">

    <TextView
        android:id="@+id/gdMap"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="高德地图"
        android:textColor="#191919"
        android:textSize="15sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#F5F5F5" />

    <TextView
        android:id="@+id/bdMap"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="百度地图"
        android:textColor="#191919"
        android:textSize="15sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#F5F5F5" />

    <TextView
        android:id="@+id/cancel"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="取消"
        android:textColor="#191919"
        android:textSize="15sp" />

</LinearLayout>

传入参数导航

/**
 * @param collectPoint 导航到collectPoint点,导航显示的名字
 * @param name
 */
public void navigation(Point collectPoint, String name) {
   
    //导航名
    String finalName = name;
    WindowDialogView.WindowDialogView(getView().getSelfActivity(), new WindowDialogView.windowDialogListener() {

        @Override
        public void onGDNav() {
            /**
             * 打开高德地图导航功能
             *
             * @param context
             * @param lat    终点纬度
             * @param lng    终点经度
             * @param end   终点名称 必填
             */
            Point point = new Point(collectPoint.getX(), collectPoint.getY(), SpatialReference.create(4326));
            double[] doubles = GDCoordTransform.transformWGS84ToGCJ02(point.getX(), point.getY());

            //高德地图导航
            NavigationUtils.openGaoDeNavi(getView().getSelfActivity(), 0, 0, null, doubles[1], doubles[0], finalName);
        }

        @Override
        public void onBDNav() {
            /**
             * 打开百度地图导航功能
             *
             * @param context
             * @param lat    终点纬度
             * @param lng    终点经度
             * @param end   终点名称 必填
             */
            double[] doubles = GDCoordTransform.transformWGS84ToBD09(collectPoint.getX(), collectPoint.getY());
            double lat = doubles[1];
            double lng = doubles[0];
            //百度地图导航
            NavigationUtils.gotoBaiduMap(getView().getSelfActivity(), lat, lng, finalName);
        }

        @Override
        public void cencel() {
                /**
                 * 取消导航,逻辑自己写
                 */
        }
    });
}

新建NavigationUtils.class文件

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;

import com.baidu.mapapi.model.LatLng;

import java.math.BigDecimal;

/**
 * 导航工具类
 */
public class NavigationUtils {

    public static final String PN_GAODE_MAP = "com.autonavi.minimap";// 高德地图包名

    /**
     * 启动高德App进行导航
     */
    public static void gotoGaodeMap(Activity context, double lat, double lng, String end) {
        try {
            LatLng latLng = baidu_to_gaode(new LatLng(lat, lng));
            Uri uri = Uri.parse("amapuri://route/plan/?dlat=" + latLng.latitude + "&dlon=" + latLng.longitude + "&dname=" + end + "&dev=0&t=0");
            Intent intent = new Intent("android.intent.action.VIEW", uri);
            intent.addCategory("android.intent.category.DEFAULT");
            context.startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(context, "请安装高德地图", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 打开百度地图导航客户端
     */
    public static void gotoBaiduMap(Activity context, double lat, double lng, String end) {
        try {
            Uri uri = Uri.parse("baidumap://map/direction?destination=latlng:" + lat + "," + lng + "|name:" + end + "&mode=driving");
            context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
        } catch (Exception e) {
            Toast.makeText(context, "请安装百度地图", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 打开腾讯地图导航客户端
     */
    public static void gotoTengxunMap(Activity context, double lat, double lng, String end) {
        try {
            LatLng latLng = baidu_to_gaode(new LatLng(lat, lng));
            Uri uri = Uri.parse("qqmap://map/routeplan?"
                    + "type=drive"
                    + "&to=" + end//终点的显示名称 必要参数
                    + "&tocoord=" + latLng.latitude + "," + latLng.longitude//终点的经纬度
                    + "&referer=test");

            Intent intent = new Intent();
            intent.setData(uri);
            context.startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(context, "请安装腾讯地图", Toast.LENGTH_LONG).show();
        }


    }


    /**
     * 将百度坐标转变成火星坐标
     *
     * @param lngLat_bd 百度坐标(百度地图坐标)
     * @return 火星坐标(高德 、 腾讯地图等)
     */

    public static LatLng baidu_to_gaode(LatLng lngLat_bd) {
        double x_pi = Math.PI * 3000.0 / 180.0;
        double x = lngLat_bd.longitude - 0.0065, y = lngLat_bd.latitude - 0.006;

        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);

        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);

        return new LatLng(dataDigit(6, z * Math.sin(theta)), dataDigit(6, z * Math.cos(theta)));

    }

    /**
     * 对double类型数据保留小数点后多少位
     * <p>
     * 高德地图转码返回的就是 小数点后6位,为了统一封装一下
     *
     * @param digit 位数
     * @param in    输入
     * @return 保留小数位后的数
     */

    static double dataDigit(int digit, double in) {

        return new BigDecimal(in).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();

    }


    public static void openGaoDeNavi(Activity context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
        try {
            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);
        } catch (Exception exception) {
            Toast.makeText(context, "请安装高德地图", Toast.LENGTH_LONG).show();
        }
    }

}

新建坐标转换类GDCoordTransform.class,网上找会有一堆的

/**
 * 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
 */
public class GDCoordTransform {


    private static final double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
    private static final double PI = 3.1415926535897932384626;
    private static final double a = 6378245.0;
    private static final double ee = 0.00669342162296594323;

    /**
     * 百度坐标(BD09)转 GCJ02
     *
     * @param lng 百度经度
     * @param lat 百度纬度
     * @return GCJ02 坐标:[经度,纬度]
     */
    public static double[] transformBD09ToGCJ02(double lng, double lat) {
        double x = lng - 0.0065;
        double y = lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
        double gcj_lng = z * Math.cos(theta);
        double gcj_lat = z * Math.sin(theta);
        return new double[]{gcj_lng, gcj_lat};
    }

    /**
     * GCJ02 转百度坐标
     *
     * @param lng GCJ02 经度
     * @param lat GCJ02 纬度
     * @return 百度坐标:[经度,纬度]
     */
    public static double[] transformGCJ02ToBD09(double lng, double lat) {
        double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
        double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
        double bd_lng = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new double[]{bd_lng, bd_lat};
    }

    /**
     * GCJ02 转 WGS84
     *
     * @param lng 经度
     * @param lat 纬度
     * @return WGS84坐标:[经度,纬度]
     */
    public static double[] transformGCJ02ToWGS84(double lng, double lat) {
        if (outOfChina(lng, lat)) {
            return new double[]{lng, lat};
        } else {
            double dLat = transformLat(lng - 105.0, lat - 35.0);
            double dLng = transformLng(lng - 105.0, lat - 35.0);
            double radLat = lat / 180.0 * PI;
            double magic = Math.sin(radLat);
            magic = 1 - ee * magic * magic;
            double sqrtMagic = Math.sqrt(magic);
            dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
            dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
            double mgLat = lat + dLat;
            double mgLng = lng + dLng;
            return new double[]{lng * 2 - mgLng, lat * 2 - mgLat};
        }
    }

    /**
     * WGS84 坐标 转 GCJ02
     *
     * @param lng 经度
     * @param lat 纬度
     * @return GCJ02 坐标:[经度,纬度]
     */
    public static double[] transformWGS84ToGCJ02(double lng, double lat) {
        if (outOfChina(lng, lat)) {
            return new double[]{lng, lat};
        } else {
            double dLat = transformLat(lng - 105.0, lat - 35.0);
            double dLng = transformLng(lng - 105.0, lat - 35.0);
            double redLat = lat / 180.0 * PI;
            double magic = Math.sin(redLat);
            magic = 1 - ee * magic * magic;
            double sqrtMagic = Math.sqrt(magic);
            dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
            dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(redLat) * PI);
            double mgLat = lat + dLat;
            double mgLng = lng + dLng;
            return new double[]{mgLng, mgLat};
        }
    }

    /**
     * 百度坐标BD09 转 WGS84
     *
     * @param lng 经度
     * @param lat 纬度
     * @return WGS84 坐标:[经度,纬度]
     */
    public static double[] transformBD09ToWGS84(double lng, double lat) {
        double[] lngLat = transformBD09ToGCJ02(lng, lat);

        return transformGCJ02ToWGS84(lngLat[0], lngLat[1]);
    }

    /**
     * WGS84 转 百度坐标BD09
     *
     * @param lng 经度
     * @param lat 纬度
     * @return BD09 坐标:[经度,纬度]
     */
    public static double[] transformWGS84ToBD09(double lng, double lat) {
        double[] lngLat = transformWGS84ToGCJ02(lng, lat);

        return transformGCJ02ToBD09(lngLat[0], lngLat[1]);
    }


    /**
     * 经纬度转墨卡托
     *
     * @param lng 经度
     * @param lat 纬度
     * @return wgs墨卡托[经度,纬度]
     */
    public static double[] transformLonLatToMecator(double lng, double lat) {
        double earthRad = 6378137.0;
        double x = lng * Math.PI / 180 * earthRad;
        double a = lat * Math.PI / 180;
        double y = earthRad / 2 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
        return new double[]{x, y}; //[12727039.383734727, 3579066.6894065146]

    }

    /**
     * 墨卡托转经纬度
     *
     * @param x
     * @param y
     * @return 经纬度[经度,纬度]
     */
    public static double[] transformMercatorToLngLat(double x, double y) {
        double lng = x / 20037508.34 * 180;
        double lat = y / 20037508.34 * 180;
        lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2);
        return new double[]{lng, lat}; //[12727039.383734727, 3579066.6894065146]

    }


    private static double transformLat(double lng, double lat) {
        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
        return ret;
    }



    private static double transformLng(double lng, double lat) {
        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
        return ret;
    }



    /**
     * 判断坐标是否不在国内
     *
     * @param lng 经度
     * @param lat 纬度
     * @return 坐标是否在国内
     */
    public static boolean outOfChina(double lng, double lat) {
        return (lng < 72.004 || lng > 137.8347) || (lat < 0.8293 || lat > 55.8271);
    }

}

至此完成