Android集成高德地图
怀中猫鱼鲸 人气:0最终效果是,本App展示地图,点击地图导航,调转三方实现导航。
1.迈出第一步,去创建自己的应用key https://lbs.amap.com/
1.1创建完应用之后,点击页面的{添加},要求填写自己项目的信息
对于调试获取SHA1的方法是:
1.打开cmd,
2、在弹出的控制台窗口中输入 cd .android 定位到 .android 文件夹:
3、继续在控制台输入命令:
调试版本使用 debug.keystore,命令为:keytool -list -v -keystore debug.keystore
发布版本使用 apk 对应的 keystore,命令为:keytool -list -v -keystore 自己apk的keystore路径(可以找到文件直接拖进来) 如下所示:
4.提示输入密钥库密码,调试版本默认密码是 android,发布版本的密码是为 apk 的 keystore 设置的密码。输入密钥后回车(如果没设置密码,可直接回车),此时可在控制台显示的信息中获取 Sha1 值,如下图所示:
以上完成弹窗填写,最终获取到key了。
2.第二大步,依然是准备工作,要下载高德地图相关的SDK https://lbs.amap.com/api/android-sdk/download
下载完毕之后,导入Android studio,我使用的是libs方式。
记得右键
此时你的bulid .gradle (app)会出现 implementation files('libs\…),同时我们要在android 闭包中加入
sourceSets { main{ jniLibs.srcDirs = ['libs'] } }
3.在清单中加入
<!-- 定位service --> <service android:name="com.amap.api.location.APSService" /> <meta-data android:name="com.amap.api.v2.apikey" android:value="上面第一步生成的key" />
4.准备完成,开敲
导入权限
implementation ‘pub.devrel:easypermissions:3.0.0’
public class MapActivity extends AppCompatActivity implements AMapLocationListener, LocationSource { //请求权限码 private static final int REQUEST_PERMISSIONS = 9527; //声明AMapLocationClient类对象 public AMapLocationClient mLocationClient = null; //声明AMapLocationClientOption对象 public AMapLocationClientOption mLocationOption = null; private MapView mapView; //地图控制器 private AMap aMap = null; //位置更改监听 private LocationSource.OnLocationChangedListener mListener; private FloatingActionButton mNavi; 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"; // 腾讯地图包名 private String mStartAddress; private double mLatitude; private double mLongitude; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map); initLocation(); initMap(savedInstanceState); checkingAndroidVersion(); mNavi = findViewById(R.id.fab_poi); mNavi.setOnClickListener(view -> { Dialog bottomDialog = new Dialog(MapActivity.this, R.style.BottomDialog); View contentView = LayoutInflater.from(MapActivity.this).inflate(R.layout.dialog_content_normal, null); bottomDialog.setContentView(contentView); ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams(); layoutParams.width = getResources().getDisplayMetrics().widthPixels; contentView.setLayoutParams(layoutParams); bottomDialog.getWindow().setGravity(Gravity.BOTTOM); bottomDialog.getWindow().setWindowAnimations(R.style.BottomDialog_Animation); TextView mCancel = contentView.findViewById(R.id.cancel); TextView mBai = contentView.findViewById(R.id.bai); TextView mGao = contentView.findViewById(R.id.gao); mBai.setOnClickListener(view1 -> { if (isGdMapInstalled(PN_BAIDU_MAP)) { /* * slat 起点纬度 * @param slon 起点经度 * @param sname 起点名称 可不填(0,0,null) * @param dlat 终点纬度 * @param dlon 终点经度 * @param dname 终点名称 必填 * */ OpenMap.openBaiDuNavi(MapActivity.this,mLatitude,mLongitude,mStartAddress, 42.904823d,129.513228d, "延边"); Toast.makeText(MapActivity.this, "有", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MapActivity.this, "暂未安装此应用", Toast.LENGTH_SHORT).show(); } }); mGao.setOnClickListener(view12 -> { if (isGdMapInstalled(PN_GAODE_MAP)) { OpenMap.openGaoDeNavi(MapActivity.this,mLatitude,mLongitude,mStartAddress, 42.904823d,129.513228d, "延边"); Toast.makeText(MapActivity.this, "有", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MapActivity.this, "暂未安装此应用", Toast.LENGTH_SHORT).show(); } }); mCancel.setOnClickListener(view13 -> bottomDialog.dismiss()); bottomDialog.show(); }); } /* * 是否安装了该应用 * */ private static boolean isInstallPackage(String packageName) { return new File("/data/data/" + packageName).exists(); } private static boolean isGdMapInstalled(String packageName) { return isInstallPackage(packageName); } /** * 初始化地图 * * @param savedInstanceState */ private void initMap(Bundle savedInstanceState) { mapView = findViewById(R.id.map_view); //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图 mapView.onCreate(savedInstanceState); //初始化地图控制器对象 aMap = mapView.getMap(); // 设置定位监听 aMap.setLocationSource(this); // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false aMap.setMyLocationEnabled(true); } /** * 初始化定位 */ private void initLocation() { //初始化定位 try { //隐私政策合规 ServiceSettings.updatePrivacyShow(this, true, true); ServiceSettings.updatePrivacyAgree(this, true); mLocationClient = new AMapLocationClient(getApplicationContext()); } catch (Exception e) { e.printStackTrace(); } //设置定位回调监听 mLocationClient.setLocationListener(this); //初始化AMapLocationClientOption对象 mLocationOption = new AMapLocationClientOption(); //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); //获取最近3s内精度最高的一次定位结果: //设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。 mLocationOption.setOnceLocationLatest(true); //设置是否返回地址信息(默认返回地址信息) mLocationOption.setNeedAddress(true); //设置定位请求超时时间,单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。 mLocationOption.setHttpTimeOut(20000); //关闭缓存机制,高精度定位会产生缓存。 mLocationOption.setLocationCacheEnable(false); //给定位客户端对象设置定位参数 mLocationClient.setLocationOption(mLocationOption); } /** * 检查Android版本 */ private void checkingAndroidVersion() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //Android6.0及以上先获取权限再定位 requestPermission(); } else { //Android6.0以下直接定位 mLocationClient.startLocation(); } } /** * 动态请求权限 */ @AfterPermissionGranted(REQUEST_PERMISSIONS) private void requestPermission() { String[] permissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; if (EasyPermissions.hasPermissions(this, permissions)) { //true 有权限 开始定位 mLocationClient.startLocation(); } else { //false 无权限 EasyPermissions.requestPermissions(this, "需要权限", REQUEST_PERMISSIONS, permissions); } } /** * 请求权限结果 * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //设置权限请求结果 EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } /** * Toast提示 * * @param msg 提示内容 */ private void showMsg(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } /** * 接收异步返回的定位结果 * * @param aMapLocation */ @Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation != null) { if (aMapLocation.getErrorCode() == 0) { //地址 mStartAddress = aMapLocation.getAddress(); //纬度 mLatitude = aMapLocation.getLatitude(); //经度 mLongitude = aMapLocation.getLongitude(); showMsg(mStartAddress); mLocationClient.stopLocation(); //显示地图定位结果 if (mListener != null) { mListener.onLocationChanged(aMapLocation); } } else { //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。 Log.e("AmapError", "location Error, ErrCode:" + aMapLocation.getErrorCode() + ", errInfo:" + aMapLocation.getErrorInfo()); } } } @Override protected void onDestroy() { super.onDestroy(); //销毁定位客户端,同时销毁本地定位服务。 mLocationClient.onDestroy(); mapView.onDestroy(); } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图 mapView.onResume(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制 mapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态 mapView.onSaveInstanceState(outState); } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener onLocationChangedListener) { mListener = onLocationChangedListener; if (mLocationClient == null) { mLocationClient.startLocation();//启动定位 } } /** * 停止定位 */ @Override public void deactivate() { mListener = null; if (mLocationClient != null) { mLocationClient.stopLocation(); mLocationClient.onDestroy(); } mLocationClient = null; } }
public class OpenMap { 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"; // 腾讯地图包名 /** * 打开腾讯地图 * 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); } /** * 打开百度地图导航功能(默认坐标点是高德地图,需要转换) * * @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); } 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; } }
加载全部内容