前言
地圖的基本應(yīng)用,現(xiàn)在對于一個開發(fā)者來說,是一個基本的要素乏屯,能否熟練的掌握地圖的基本使用(以高德地圖為例),對我們在工作中有很大的幫助瘦赫。我們就以高德地圖官方Demo(BasicMapActivity)為示例辰晕,解析高德地圖中經(jīng)常用到的功能。
那么我們先看效果圖:
以上就是不同模式下的基本地圖顯示
注意事項
- 權(quán)限聲明
- key及SHA1
- 模式切換
- 個性化地圖
權(quán)限聲明
使用地圖SDK之前确虱,需要在 AndroidManifest.xml 文件中進行相關(guān)權(quán)限設(shè)置含友,確保地圖功能可以正常使用。如有不明白的地方校辩,可參考官方地址進行詳細了解窘问。
當(dāng)然,在AndroidManifest.xml清單文件中配置權(quán)限完成之后宜咒,在頁面中加載的時候惠赫,也不能忘記在界面中對于地圖權(quán)定位等相關(guān)權(quán)限的申請。示例代碼如下:
屬性:needCheckBackLocation
提示是否需要檢測后臺定位權(quán)限故黑,設(shè)置為true時儿咱,如果用戶沒有給予后臺定位權(quán)限會彈窗提示。
屬性:BACK_LOCATION_PERMISSION
如果設(shè)置了target > 28场晶,需要增加這個權(quán)限混埠,否則不會彈出"始終允許"這個選擇框
//是否需要檢測后臺定位權(quán)限,設(shè)置為true時诗轻,如果用戶沒有給予后臺定位權(quán)限會彈窗提示
private boolean needCheckBackLocation = false;
//如果設(shè)置了target > 28钳宪,需要增加這個權(quán)限,否則不會彈出"始終允許"這個選擇框
private static String BACK_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
需要聲明的權(quán)限列表
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;
}
}
權(quán)限檢查相關(guān)代碼
/**
* 需要進行檢測的權(quán)限數(shù)組
*/
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();
}
}
/**
* 獲取權(quán)限集中需要申請權(quán)限的列表
*
* @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;
}
/**
* 檢測是否說有的權(quán)限都已經(jīng)授權(quán)
*
* @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("當(dāng)前應(yīng)用缺少必要權(quán)限吏颖。\\n\\n請點擊\\\"設(shè)置\\\"-\\\"權(quán)限\\\"-打開所需權(quán)限");
// 拒絕, 退出應(yīng)用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
finish();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("設(shè)置",
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();
}
}
/**
* 啟動應(yīng)用的設(shè)置
*
* @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鞠柄,在控制臺中添加新的應(yīng)用
點我查看Key注冊時必要數(shù)據(jù)SHA1和包名的獲取方法
模式切換
官方文檔中 Android 地圖 SDK 提供了幾種預(yù)置的地圖圖層侦高,包括衛(wèi)星圖、白晝地圖(即最常見的黃白色地圖)厌杜、夜景地圖奉呛、導(dǎo)航地圖计螺、路況圖層。
- AMap.MAP_TYPE_NORMAL:矢量地圖模式
- AMap.MAP_TYPE_SATELLITE:衛(wèi)星地圖模式
- AMap.MAP_TYPE_NIGHT:夜景地圖模式
- AMap.MAP_TYPE_NAVI:導(dǎo)航地圖模式
完整示例代碼
public class MainActivity extends ListActivity {
/**
* 存儲數(shù)據(jù)
*/
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;
}
}
//是否需要檢測后臺定位權(quán)限瞧壮,設(shè)置為true時登馒,如果用戶沒有給予后臺定位權(quán)限會彈窗提示
private boolean needCheckBackLocation = false;
//如果設(shè)置了target > 28陈轿,需要增加這個權(quán)限,否則不會彈出"始終允許"這個選擇框
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));
}
}
/**
* 需要進行檢測的權(quán)限數(shù)組
*/
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();
}
}
/**
* 獲取權(quán)限集中需要申請權(quán)限的列表
*
* @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;
}
/**
* 檢測是否說有的權(quán)限都已經(jīng)授權(quán)
*
* @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("當(dāng)前應(yīng)用缺少必要權(quán)限。\\n\\n請點擊\\\"設(shè)置\\\"-\\\"權(quán)限\\\"-打開所需權(quán)限");
// 拒絕, 退出應(yīng)用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
finish();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("設(shè)置",
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();
}
}
/**
* 啟動應(yīng)用的設(shè)置
*
* @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();
}
}
}