赞
踩
在Android开发工作中,遇到一需求,需要在公司项目的应用中点击地图上的位置,弹出导航并选择跳转到一个第三方地图应用(高德地图、百度地图、腾讯地图)。
于是搜索了下,找到很多有用信息,在此把个人总结的分享出来^ . ^
首先来看下UI图,这里没有使用弹出的形式,这只是个演示……
这里的经纬度是高德腾讯地图的经纬度,可以在这个在线地图经度纬度查询获取地理位置的经纬度信息
下面是布局文件:activity_main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="5dp">
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:text="目的地:北京天安门"/>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:text="经度:116.3980007172"/>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:text="纬度:39.9037448095"/>
-
- </LinearLayout>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:layout_above="@id/gaode_map"
- android:text="请选择第三方地图导航!"/>
-
- <Button
- android:id="@+id/gaode_map"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_above="@id/baidu_map"
- android:text="高德地图"/>
-
- <Button
- android:id="@+id/baidu_map"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_above="@id/tencent_map"
- android:text="百度地图"/>
-
- <Button
- android:id="@+id/tencent_map"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:text="腾讯地图"/>
-
- </RelativeLayout>
接着就是最重要的,也就是调用第三方地图应用的工具类啦
MapUtil:
- import android.content.Context;
- import android.content.Intent;
- import android.net.Uri;
-
- import com.baidu.mapapi.model.LatLng;
-
- import java.io.File;
-
- public class MapUtil {
-
- public static final String PN_GAODE_MAP = "com.autonavi.minimap";// 高德地图包名
- public static final String PN_BAIDU_MAP = "com.baidu.BaiduMap"; // 百度地图包名
- public static final String PN_TENCENT_MAP = "com.tencent.map"; // 腾讯地图包名
-
- /**
- * 检查地图应用是否安装
- * @return
- */
- public static boolean isGdMapInstalled(){
- return isInstallPackage(PN_GAODE_MAP);
- }
-
- public static boolean isBaiduMapInstalled(){
- return isInstallPackage(PN_BAIDU_MAP);
- }
-
- public static boolean isTencentMapInstalled(){
- return isInstallPackage(PN_TENCENT_MAP);
- }
-
- private static boolean isInstallPackage(String packageName) {
- return new File("/data/data/" + packageName).exists();
- }
-
- /**
- * 百度转高德
- * @param bd_lat
- * @param bd_lon
- * @return
- */
- public static double[] bdToGaoDe(double bd_lat, double bd_lon) {
- double[] gd_lat_lon = new double[2];
- double PI = 3.14159265358979324 * 3000.0 / 180.0;
- double x = bd_lon - 0.0065, y = bd_lat - 0.006;
- double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * PI);
- double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * PI);
- gd_lat_lon[0] = z * Math.cos(theta);
- gd_lat_lon[1] = z * Math.sin(theta);
- return gd_lat_lon;
- }
-
- /**
- * 高德、腾讯转百度
- * @param gd_lon
- * @param gd_lat
- * @return
- */
- private static double[] gaoDeToBaidu(double gd_lon, double gd_lat) {
- double[] bd_lat_lon = new double[2];
- double PI = 3.14159265358979324 * 3000.0 / 180.0;
- double x = gd_lon, y = gd_lat;
- double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * PI);
- double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * PI);
- bd_lat_lon[0] = z * Math.cos(theta) + 0.0065;
- bd_lat_lon[1] = z * Math.sin(theta) + 0.006;
- return bd_lat_lon;
- }
-
- /**
- * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
- * 即 百度 转 谷歌、高德
- *
- * @param latLng
- * @returns
- *
- * 使用此方法需要下载导入百度地图的BaiduLBS_Android.jar包
- */
- public static LatLng BD09ToGCJ02(LatLng latLng) {
- double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
- double x = latLng.longitude - 0.0065;
- double y = latLng.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);
- double gg_lat = z * Math.sin(theta);
- double gg_lng = z * Math.cos(theta);
- return new LatLng(gg_lat, gg_lng);
- }
-
- /**
- * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
- * 即谷歌、高德 转 百度
- *
- * @param latLng
- * @returns
- *
- * 需要百度地图的BaiduLBS_Android.jar包
- */
- public static LatLng GCJ02ToBD09(LatLng latLng) {
- double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
- double z = Math.sqrt(latLng.longitude * latLng.longitude + latLng.latitude * latLng.latitude) + 0.00002 * Math.sin(latLng.latitude * x_pi);
- double theta = Math.atan2(latLng.latitude, latLng.longitude) + 0.000003 * Math.cos(latLng.longitude * x_pi);
- double bd_lat = z * Math.sin(theta) + 0.006;
- double bd_lng = z * Math.cos(theta) + 0.0065;
- return new LatLng(bd_lat, bd_lng);
- }
-
- /**
- * 打开高德地图导航功能
- * @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);
- }
-
- /**
- * 打开腾讯地图
- * params 参考http://lbs.qq.com/uri_v1/guide-route.html
- *
- * @param context
- * @param slat 起点纬度
- * @param slon 起点经度
- * @param sname 起点名称 可不填(0,0,null)
- * @param dlat 终点纬度
- * @param dlon 终点经度
- * @param dname 终点名称 必填
- * 驾车:type=drive,policy有以下取值
- 0:较快捷
- 1:无高速
- 2:距离
- policy的取值缺省为0
- * &from=" + dqAddress + "&fromcoord=" + dqLatitude + "," + dqLongitude + "
- */
- 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);
- }
-
- /**
- * 打开百度地图导航功能(默认坐标点是高德地图,需要转换)
- * @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;
- //终点坐标转换
- // 此方法需要百度地图的BaiduLBS_Android.jar包
- // LatLng destination = new LatLng(dlat,dlon);
- // LatLng destinationLatLng = GCJ02ToBD09(destination);
- // dlat = destinationLatLng.latitude;
- // dlon = destinationLatLng.longitude;
-
- double destination[] = gaoDeToBaidu(dlat, dlon);
- dlat = destination[0];
- dlon = destination[1];
-
- StringBuilder builder = new StringBuilder("baidumap://map/direction?mode=driving&");
- if (slat != 0){
- //起点坐标转换
-
- // LatLng origin = new LatLng(slat,slon);
- // LatLng originLatLng = GCJ02ToBD09(origin);
- // slat = originLatLng.latitude;
- // slon = originLatLng.longitude;
-
- 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);
- }
- }
该工具类中,如果要使用
BD09ToGCJ02(LatLng latLng) {}
GCJ02ToBD09(LatLng latLng) {}
这两个百度和高德、腾讯互转方法的话,就要导入百度地图的BaiduLBS_Android.jar包;
其中调用腾讯地图参考了Web端功能参数表 如图:
MainActivity:
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
-
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
-
- private Button gaode_map, baidu_map, tencent_map;
-
- //这里的经纬度是直接获取的,在实际开发中从应用的地图中获取经纬度;
- private double latx = 39.9037448095;
- private double laty = 116.3980007172;
- private String mAddress = "北京天安门";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- gaode_map = (Button) findViewById(R.id.gaode_map);
- baidu_map = (Button) findViewById(R.id.baidu_map);
- tencent_map = (Button) findViewById(R.id.tencent_map);
- gaode_map.setOnClickListener(this);
- baidu_map.setOnClickListener(this);
- tencent_map.setOnClickListener(this);
- }
-
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.gaode_map:
- if (MapUtil.isGdMapInstalled()) {
- MapUtil.openGaoDeNavi(MainActivity.this, 0, 0, null, latx, laty, mAddress);
- } else {
- //这里必须要写逻辑,不然如果手机没安装该应用,程序会闪退,这里可以实现下载安装该地图应用
- Toast.makeText(MainActivity.this, "尚未安装高德地图", Toast.LENGTH_SHORT).show();
- }
- break;
- case R.id.baidu_map:
- if (MapUtil.isBaiduMapInstalled()){
- MapUtil.openBaiDuNavi(MainActivity.this, 0, 0, null, latx, laty, mAddress);
- } else {
- Toast.makeText(MainActivity.this, "尚未安装百度地图", Toast.LENGTH_SHORT).show();
- }
- break;
- case R.id.tencent_map:
- if (MapUtil.isTencentMapInstalled()){
- MapUtil.openTencentMap(MainActivity.this, 0, 0, null, latx, laty, mAddress);
- } else {
- Toast.makeText(MainActivity.this, "尚未安装腾讯地图", Toast.LENGTH_SHORT).show();
- }
- break;
- default:
- break;
- }
- }
- }
点击事件的处理根据项目的实际需要编写,这里就直接写在了MainActivity里了,项目中大都像下图所示的方式使用:
哈哈。为了试验以上代码,不惜在手机上下载了三个地图导航,结果怎么样呢……
你们把上面的代码写个demo就知道啦。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。