前言
地图的基本应用,现在对于一个开发者来说,是一个基本的要素,能否熟练的掌握地图的基本使用(以高德地图为例),对我们在工作中有很大的帮助。我们就以高德地图官方Demo(BasicMapActivity)为示例,解析高德地图中经常用到的功能。
那么我们先看效果图:
以上就是不同模式下的基本地图显示
注意事项
- 权限声明
- key及SHA1
- 模式切换
- 个性化地图
权限声明
使用地图SDK之前,需要在 AndroidManifest.xml 文件中进行相关权限设置,确保地图功能可以正常使用。如有不明白的地方,可参考官方地址进行详细了解。
当然,在AndroidManifest.xml清单文件中配置权限完成之后,在页面中加载的时候,也不能忘记在界面中对于地图权定位等相关权限的申请。示例代码如下:
属性:needCheckBackLocation
提示是否需要检测后台定位权限,设置为true时,如果用户没有给予后台定位权限会弹窗提示。
属性:BACK_LOCATION_PERMISSION
如果设置了target > 28,需要增加这个权限,否则不会弹出"始终允许"这个选择框
//是否需要检测后台定位权限,设置为true时,如果用户没有给予后台定位权限会弹窗提示
private boolean needCheckBackLocation = false;
//如果设置了target > 28,需要增加这个权限,否则不会弹出"始终允许"这个选择框
private static String BACK_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
需要声明的权限列表
private void initPermissions() {
if (Build.VERSION.SDK_INT > 28
&& getApplicationContext().getApplicationInfo().targetSdkVersion > 28) {
needPermissions = new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
needCheckBackLocation = true;
}
}
权限检查相关代码
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判断是否需要检测,防止不停的弹框
*/
private boolean isNeedCheck = true;
@Override
protected void onResume() {
try {
super.onResume();
if (Build.VERSION.SDK_INT >= 23) {
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* @param
* @since 2.5.0
*/
@TargetApi(23)
private void checkPermissions(String... permissions) {
try {
if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
try {
String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]);
Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class, int.class});
method.invoke(this, array, 0);
} catch (Throwable e) {
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
* @return
* @since 2.5.0
*/
@TargetApi(23)
private List<String> findDeniedPermissions(String[] permissions) {
try {
List<String> needRequestPermissonList = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) {
for (String perm : permissions) {
if (checkMySelfPermission(perm) != PackageManager.PERMISSION_GRANTED
|| shouldShowMyRequestPermissionRationale(perm)) {
if (!needCheckBackLocation
&& BACK_LOCATION_PERMISSION.equals(perm)) {
continue;
}
needRequestPermissonList.add(perm);
}
}
}
return needRequestPermissonList;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
private int checkMySelfPermission(String perm) {
try {
Method method = getClass().getMethod("checkSelfPermission", new Class[]{String.class});
Integer permissionInt = (Integer) method.invoke(this, perm);
return permissionInt;
} catch (Throwable e) {
}
return -1;
}
private boolean shouldShowMyRequestPermissionRationale(String perm) {
try {
Method method = getClass().getMethod("shouldShowRequestPermissionRationale", new Class[]{String.class});
Boolean permissionInt = (Boolean) method.invoke(this, perm);
return permissionInt;
} catch (Throwable e) {
}
return false;
}
/**
* 检测是否说有的权限都已经授权
*
* @param grantResults
* @return
* @since 2.5.0
*/
private boolean verifyPermissions(int[] grantResults) {
try {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return true;
}
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] paramArrayOfInt) {
try {
if (Build.VERSION.SDK_INT >= 23) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
showMissingPermissionDialog();
isNeedCheck = false;
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 显示提示信息
*
* @since 2.5.0
*/
private void showMissingPermissionDialog() {
try {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("当前应用缺少必要权限。\\n\\n请点击\\\"设置\\\"-\\\"权限\\\"-打开所需权限");
// 拒绝, 退出应用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
finish();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startAppSettings();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setCancelable(false);
builder.show();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 启动应用的设置
*
* @since 2.5.0
*/
private void startAppSettings() {
try {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
} catch (Throwable e) {
e.printStackTrace();
}
}
key及SHA1
key及SHA1中官方文档中有详细说明,不再介绍
点我获取key,在控制台中添加新的应用
点我查看Key注册时必要数据SHA1和包名的获取方法
模式切换
官方文档中 Android 地图 SDK 提供了几种预置的地图图层,包括卫星图、白昼地图(即最常见的黄白色地图)、夜景地图、导航地图、路况图层。
- AMap.MAP_TYPE_NORMAL:矢量地图模式
- AMap.MAP_TYPE_SATELLITE:卫星地图模式
- AMap.MAP_TYPE_NIGHT:夜景地图模式
- AMap.MAP_TYPE_NAVI:导航地图模式
完整示例代码
public class MainActivity extends ListActivity {
/**
* 存储数据
*/
private static class DemoDetails {
private final int titleId;
private final int descriptionId;
private final Class<? extends android.app.Activity> activityClass;
public DemoDetails(int titleId, int descriptionId,
Class<? extends android.app.Activity> activityClass) {
super();
this.titleId = titleId;
this.descriptionId = descriptionId;
this.activityClass = activityClass;
}
}
//是否需要检测后台定位权限,设置为true时,如果用户没有给予后台定位权限会弹窗提示
private boolean needCheckBackLocation = false;
//如果设置了target > 28,需要增加这个权限,否则不会弹出"始终允许"这个选择框
private static String BACK_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
private static class CustomArrayAdapter extends ArrayAdapter<DemoDetails> {
public CustomArrayAdapter(Context context, DemoDetails[] demos) {
super(context, R.layout.feature, R.id.title, demos);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
FeatureView featureView;
if (convertView instanceof FeatureView) {
featureView = (FeatureView) convertView;
} else {
featureView = new FeatureView(getContext());
}
DemoDetails demo = getItem(position);
featureView.setTitleId(demo.titleId, demo.activityClass != null);
return featureView;
}
}
private static final DemoDetails[] demos = {
new DemoDetails(R.string.map_create, R.string.blank, null),
new DemoDetails(R.string.basic_map, R.string.basic_description, BasicMapActivity.class)//显示地图
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initPermissions();
setContentView(R.layout.activity_main);
setTitle("3D地图Demo" + MapsInitializer.getVersion());
ListAdapter adapter = new CustomArrayAdapter(
this.getApplicationContext(), demos);
setListAdapter(adapter);
}
private void initPermissions() {
if (Build.VERSION.SDK_INT > 28
&& getApplicationContext().getApplicationInfo().targetSdkVersion > 28) {
needPermissions = new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
needCheckBackLocation = true;
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
System.exit(0);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
DemoDetails demo = (DemoDetails) getListAdapter().getItem(position);
if (demo.activityClass != null) {
Log.i("MY","demo!=null");
startActivity(new Intent(this.getApplicationContext(), demo.activityClass));
}
}
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判断是否需要检测,防止不停的弹框
*/
private boolean isNeedCheck = true;
@Override
protected void onResume() {
try {
super.onResume();
if (Build.VERSION.SDK_INT >= 23) {
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* @param
* @since 2.5.0
*/
@TargetApi(23)
private void checkPermissions(String... permissions) {
try {
if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
try {
String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]);
Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class, int.class});
method.invoke(this, array, 0);
} catch (Throwable e) {
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
* @return
* @since 2.5.0
*/
@TargetApi(23)
private List<String> findDeniedPermissions(String[] permissions) {
try {
List<String> needRequestPermissonList = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) {
for (String perm : permissions) {
if (checkMySelfPermission(perm) != PackageManager.PERMISSION_GRANTED
|| shouldShowMyRequestPermissionRationale(perm)) {
if (!needCheckBackLocation
&& BACK_LOCATION_PERMISSION.equals(perm)) {
continue;
}
needRequestPermissonList.add(perm);
}
}
}
return needRequestPermissonList;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
private int checkMySelfPermission(String perm) {
try {
Method method = getClass().getMethod("checkSelfPermission", new Class[]{String.class});
Integer permissionInt = (Integer) method.invoke(this, perm);
return permissionInt;
} catch (Throwable e) {
}
return -1;
}
private boolean shouldShowMyRequestPermissionRationale(String perm) {
try {
Method method = getClass().getMethod("shouldShowRequestPermissionRationale", new Class[]{String.class});
Boolean permissionInt = (Boolean) method.invoke(this, perm);
return permissionInt;
} catch (Throwable e) {
}
return false;
}
/**
* 检测是否说有的权限都已经授权
*
* @param grantResults
* @return
* @since 2.5.0
*/
private boolean verifyPermissions(int[] grantResults) {
try {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return true;
}
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] paramArrayOfInt) {
try {
if (Build.VERSION.SDK_INT >= 23) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
showMissingPermissionDialog();
isNeedCheck = false;
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 显示提示信息
*
* @since 2.5.0
*/
private void showMissingPermissionDialog() {
try {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("当前应用缺少必要权限。\\n\\n请点击\\\"设置\\\"-\\\"权限\\\"-打开所需权限");
// 拒绝, 退出应用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
finish();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startAppSettings();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setCancelable(false);
builder.show();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 启动应用的设置
*
* @since 2.5.0
*/
private void startAppSettings() {
try {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
} catch (Throwable e) {
e.printStackTrace();
}
}
}