当前位置:   article > 正文

实现Android应用调用第三方(高德、百度、腾讯)地图应用导航(仿微信调用第三方地图)_android仿微信调用第三方地图导航

android仿微信调用第三方地图导航

在Android开发工作中,遇到一需求,需要在公司项目的应用中点击地图上的位置,弹出导航并选择跳转到一个第三方地图应用(高德地图、百度地图、腾讯地图)。

于是搜索了下,找到很多有用信息,在此把个人总结的分享出来^ . ^ 

首先来看下UI图,这里没有使用弹出的形式,这只是个演示……

 

这里的经纬度是高德腾讯地图的经纬度,可以在这个在线地图经度纬度查询获取地理位置的经纬度信息

下面是布局文件:activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:layout_margin="5dp">
  7. <LinearLayout
  8. android:layout_width="wrap_content"
  9. android:layout_height="match_parent"
  10. android:orientation="vertical">
  11. <TextView
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:textSize="18sp"
  15. android:text="目的地:北京天安门"/>
  16. <TextView
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:textSize="18sp"
  20. android:text="经度:116.3980007172"/>
  21. <TextView
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:textSize="18sp"
  25. android:text="纬度:39.9037448095"/>
  26. </LinearLayout>
  27. <TextView
  28. android:layout_width="wrap_content"
  29. android:layout_height="wrap_content"
  30. android:layout_centerHorizontal="true"
  31. android:layout_above="@id/gaode_map"
  32. android:text="请选择第三方地图导航!"/>
  33. <Button
  34. android:id="@+id/gaode_map"
  35. android:layout_width="match_parent"
  36. android:layout_height="wrap_content"
  37. android:layout_above="@id/baidu_map"
  38. android:text="高德地图"/>
  39. <Button
  40. android:id="@+id/baidu_map"
  41. android:layout_width="match_parent"
  42. android:layout_height="wrap_content"
  43. android:layout_above="@id/tencent_map"
  44. android:text="百度地图"/>
  45. <Button
  46. android:id="@+id/tencent_map"
  47. android:layout_width="match_parent"
  48. android:layout_height="wrap_content"
  49. android:layout_alignParentBottom="true"
  50. android:text="腾讯地图"/>
  51. </RelativeLayout>

接着就是最重要的,也就是调用第三方地图应用的工具类啦

MapUtil:

  1. import android.content.Context;
  2. import android.content.Intent;
  3. import android.net.Uri;
  4. import com.baidu.mapapi.model.LatLng;
  5. import java.io.File;
  6. public class MapUtil {
  7. public static final String PN_GAODE_MAP = "com.autonavi.minimap";// 高德地图包名
  8. public static final String PN_BAIDU_MAP = "com.baidu.BaiduMap"; // 百度地图包名
  9. public static final String PN_TENCENT_MAP = "com.tencent.map"; // 腾讯地图包名
  10. /**
  11. * 检查地图应用是否安装
  12. * @return
  13. */
  14. public static boolean isGdMapInstalled(){
  15. return isInstallPackage(PN_GAODE_MAP);
  16. }
  17. public static boolean isBaiduMapInstalled(){
  18. return isInstallPackage(PN_BAIDU_MAP);
  19. }
  20. public static boolean isTencentMapInstalled(){
  21. return isInstallPackage(PN_TENCENT_MAP);
  22. }
  23. private static boolean isInstallPackage(String packageName) {
  24. return new File("/data/data/" + packageName).exists();
  25. }
  26. /**
  27. * 百度转高德
  28. * @param bd_lat
  29. * @param bd_lon
  30. * @return
  31. */
  32. public static double[] bdToGaoDe(double bd_lat, double bd_lon) {
  33. double[] gd_lat_lon = new double[2];
  34. double PI = 3.14159265358979324 * 3000.0 / 180.0;
  35. double x = bd_lon - 0.0065, y = bd_lat - 0.006;
  36. double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * PI);
  37. double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * PI);
  38. gd_lat_lon[0] = z * Math.cos(theta);
  39. gd_lat_lon[1] = z * Math.sin(theta);
  40. return gd_lat_lon;
  41. }
  42. /**
  43. * 高德、腾讯转百度
  44. * @param gd_lon
  45. * @param gd_lat
  46. * @return
  47. */
  48. private static double[] gaoDeToBaidu(double gd_lon, double gd_lat) {
  49. double[] bd_lat_lon = new double[2];
  50. double PI = 3.14159265358979324 * 3000.0 / 180.0;
  51. double x = gd_lon, y = gd_lat;
  52. double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * PI);
  53. double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * PI);
  54. bd_lat_lon[0] = z * Math.cos(theta) + 0.0065;
  55. bd_lat_lon[1] = z * Math.sin(theta) + 0.006;
  56. return bd_lat_lon;
  57. }
  58. /**
  59. * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
  60. * 即 百度 转 谷歌、高德
  61. *
  62. * @param latLng
  63. * @returns
  64. *
  65. * 使用此方法需要下载导入百度地图的BaiduLBS_Android.jar包
  66. */
  67. public static LatLng BD09ToGCJ02(LatLng latLng) {
  68. double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  69. double x = latLng.longitude - 0.0065;
  70. double y = latLng.latitude - 0.006;
  71. double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
  72. double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
  73. double gg_lat = z * Math.sin(theta);
  74. double gg_lng = z * Math.cos(theta);
  75. return new LatLng(gg_lat, gg_lng);
  76. }
  77. /**
  78. * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
  79. * 即谷歌、高德 转 百度
  80. *
  81. * @param latLng
  82. * @returns
  83. *
  84. * 需要百度地图的BaiduLBS_Android.jar包
  85. */
  86. public static LatLng GCJ02ToBD09(LatLng latLng) {
  87. double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  88. double z = Math.sqrt(latLng.longitude * latLng.longitude + latLng.latitude * latLng.latitude) + 0.00002 * Math.sin(latLng.latitude * x_pi);
  89. double theta = Math.atan2(latLng.latitude, latLng.longitude) + 0.000003 * Math.cos(latLng.longitude * x_pi);
  90. double bd_lat = z * Math.sin(theta) + 0.006;
  91. double bd_lng = z * Math.cos(theta) + 0.0065;
  92. return new LatLng(bd_lat, bd_lng);
  93. }
  94. /**
  95. * 打开高德地图导航功能
  96. * @param context
  97. * @param slat 起点纬度
  98. * @param slon 起点经度
  99. * @param sname 起点名称 可不填(0,0,null)
  100. * @param dlat 终点纬度
  101. * @param dlon 终点经度
  102. * @param dname 终点名称 必填
  103. */
  104. public static void openGaoDeNavi(Context context,double slat, double slon, String sname, double dlat, double dlon, String dname){
  105. String uriString = null;
  106. StringBuilder builder = new StringBuilder("amapuri://route/plan?sourceApplication=maxuslife");
  107. if (slat != 0) {
  108. builder.append("&sname=").append(sname)
  109. .append("&slat=").append(slat)
  110. .append("&slon=").append(slon);
  111. }
  112. builder.append("&dlat=").append(dlat)
  113. .append("&dlon=").append(dlon)
  114. .append("&dname=").append(dname)
  115. .append("&dev=0")
  116. .append("&t=0");
  117. uriString = builder.toString();
  118. Intent intent = new Intent(Intent.ACTION_VIEW);
  119. intent.setPackage(PN_GAODE_MAP);
  120. intent.setData(Uri.parse(uriString));
  121. context.startActivity(intent);
  122. }
  123. /**
  124. * 打开腾讯地图
  125. * params 参考http://lbs.qq.com/uri_v1/guide-route.html
  126. *
  127. * @param context
  128. * @param slat 起点纬度
  129. * @param slon 起点经度
  130. * @param sname 起点名称 可不填(0,0,null)
  131. * @param dlat 终点纬度
  132. * @param dlon 终点经度
  133. * @param dname 终点名称 必填
  134. * 驾车:type=drive,policy有以下取值
  135. 0:较快捷
  136. 1:无高速
  137. 2:距离
  138. policy的取值缺省为0
  139. * &from=" + dqAddress + "&fromcoord=" + dqLatitude + "," + dqLongitude + "
  140. */
  141. public static void openTencentMap(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
  142. String uriString = null;
  143. StringBuilder builder = new StringBuilder("qqmap://map/routeplan?type=drive&policy=0&referer=zhongshuo");
  144. if (slat != 0) {
  145. builder.append("&from=").append(sname)
  146. .append("&fromcoord=").append(slat)
  147. .append(",")
  148. .append(slon);
  149. }
  150. builder.append("&to=").append(dname)
  151. .append("&tocoord=").append(dlat)
  152. .append(",")
  153. .append(dlon);
  154. uriString = builder.toString();
  155. Intent intent = new Intent(Intent.ACTION_VIEW);
  156. intent.setPackage(PN_TENCENT_MAP);
  157. intent.setData(Uri.parse(uriString));
  158. context.startActivity(intent);
  159. }
  160. /**
  161. * 打开百度地图导航功能(默认坐标点是高德地图,需要转换)
  162. * @param context
  163. * @param slat 起点纬度
  164. * @param slon 起点经度
  165. * @param sname 起点名称 可不填(0,0,null)
  166. * @param dlat 终点纬度
  167. * @param dlon 终点经度
  168. * @param dname 终点名称 必填
  169. */
  170. public static void openBaiDuNavi(Context context,double slat, double slon, String sname, double dlat, double dlon, String dname){
  171. String uriString = null;
  172. //终点坐标转换
  173. // 此方法需要百度地图的BaiduLBS_Android.jar包
  174. // LatLng destination = new LatLng(dlat,dlon);
  175. // LatLng destinationLatLng = GCJ02ToBD09(destination);
  176. // dlat = destinationLatLng.latitude;
  177. // dlon = destinationLatLng.longitude;
  178. double destination[] = gaoDeToBaidu(dlat, dlon);
  179. dlat = destination[0];
  180. dlon = destination[1];
  181. StringBuilder builder = new StringBuilder("baidumap://map/direction?mode=driving&");
  182. if (slat != 0){
  183. //起点坐标转换
  184. // LatLng origin = new LatLng(slat,slon);
  185. // LatLng originLatLng = GCJ02ToBD09(origin);
  186. // slat = originLatLng.latitude;
  187. // slon = originLatLng.longitude;
  188. double[] origin = gaoDeToBaidu(slat, slon);
  189. slat = origin[0];
  190. slon = origin[1];
  191. builder.append("origin=latlng:")
  192. .append(slat)
  193. .append(",")
  194. .append(slon)
  195. .append("|name:")
  196. .append(sname);
  197. }
  198. builder.append("&destination=latlng:")
  199. .append(dlat)
  200. .append(",")
  201. .append(dlon)
  202. .append("|name:")
  203. .append(dname);
  204. uriString = builder.toString();
  205. Intent intent = new Intent(Intent.ACTION_VIEW);
  206. intent.setPackage(PN_BAIDU_MAP);
  207. intent.setData(Uri.parse(uriString));
  208. context.startActivity(intent);
  209. }
  210. }

该工具类中,如果要使用

BD09ToGCJ02(LatLng latLng) {} 

GCJ02ToBD09(LatLng latLng) {}

这两个百度和高德、腾讯互转方法的话,就要导入百度地图的BaiduLBS_Android.jar包;

其中调用腾讯地图参考了Web端功能参数表 如图:

 

MainActivity:

  1. import android.support.v7.app.AppCompatActivity;
  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.widget.Button;
  5. import android.widget.Toast;
  6. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  7. private Button gaode_map, baidu_map, tencent_map;
  8. //这里的经纬度是直接获取的,在实际开发中从应用的地图中获取经纬度;
  9. private double latx = 39.9037448095;
  10. private double laty = 116.3980007172;
  11. private String mAddress = "北京天安门";
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.activity_main);
  16. gaode_map = (Button) findViewById(R.id.gaode_map);
  17. baidu_map = (Button) findViewById(R.id.baidu_map);
  18. tencent_map = (Button) findViewById(R.id.tencent_map);
  19. gaode_map.setOnClickListener(this);
  20. baidu_map.setOnClickListener(this);
  21. tencent_map.setOnClickListener(this);
  22. }
  23. @Override
  24. public void onClick(View view) {
  25. switch (view.getId()) {
  26. case R.id.gaode_map:
  27. if (MapUtil.isGdMapInstalled()) {
  28. MapUtil.openGaoDeNavi(MainActivity.this, 0, 0, null, latx, laty, mAddress);
  29. } else {
  30. //这里必须要写逻辑,不然如果手机没安装该应用,程序会闪退,这里可以实现下载安装该地图应用
  31. Toast.makeText(MainActivity.this, "尚未安装高德地图", Toast.LENGTH_SHORT).show();
  32. }
  33. break;
  34. case R.id.baidu_map:
  35. if (MapUtil.isBaiduMapInstalled()){
  36. MapUtil.openBaiDuNavi(MainActivity.this, 0, 0, null, latx, laty, mAddress);
  37. } else {
  38. Toast.makeText(MainActivity.this, "尚未安装百度地图", Toast.LENGTH_SHORT).show();
  39. }
  40. break;
  41. case R.id.tencent_map:
  42. if (MapUtil.isTencentMapInstalled()){
  43. MapUtil.openTencentMap(MainActivity.this, 0, 0, null, latx, laty, mAddress);
  44. } else {
  45. Toast.makeText(MainActivity.this, "尚未安装腾讯地图", Toast.LENGTH_SHORT).show();
  46. }
  47. break;
  48. default:
  49. break;
  50. }
  51. }
  52. }

点击事件的处理根据项目的实际需要编写,这里就直接写在了MainActivity里了,项目中大都像下图所示的方式使用:

哈哈。为了试验以上代码,不惜在手机上下载了三个地图导航,结果怎么样呢……

你们把上面的代码写个demo就知道啦。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/297577
推荐阅读
相关标签
  

闽ICP备14008679号