一、概述
在第一章中我們搭建了高德地圖的開發(fā)環(huán)境御吞,接下來我們就來了解一下地圖的定位等基礎(chǔ)操作,Go漓藕。
二陶珠、本章內(nèi)容
--- 顯示定位藍(lán)點(diǎn)
--- 切換地圖圖層
--- 使用自帶的離線地圖UI
1.權(quán)限動(dòng)態(tài)申請(qǐng)
高德地圖在使用的時(shí)候需要用到一定的權(quán)限(主要在6.0以后必須申請(qǐng)權(quán)限),這里我就將要是用的權(quán)限全部動(dòng)態(tài)申請(qǐng)一次享钞,方便后面的操作
private String[] mPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};//要申請(qǐng)的權(quán)限
開始申請(qǐng)權(quán)限
//判斷當(dāng)前Android版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//需要申請(qǐng)權(quán)限,為了方便揍诽,這里我直接將地圖需要的權(quán)限都申請(qǐng)了,已啟動(dòng)就會(huì)提示授權(quán)全部權(quán)限
//大家再用的時(shí)候還是需要權(quán)限的時(shí)候再去申請(qǐng),這樣用戶體驗(yàn)會(huì)好一點(diǎn)
if (checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)
&& checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
&& checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_PHONE_STATE)) {
//已經(jīng)申請(qǐng)直接調(diào)用
myExecute();
} else {
//開啟系統(tǒng)權(quán)限申請(qǐng)
requestPermissions(mPermissions, M_PERMISSION_CODE);
}
} else {
myExecute();//權(quán)限申請(qǐng)完成需要執(zhí)行的操作
}
重寫onRequestPermissionsResult方法栗竖,來監(jiān)聽權(quán)限申請(qǐng)頁(yè)面返回的結(jié)果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case M_PERMISSION_CODE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[3] == PackageManager.PERMISSION_GRANTED
&& grantResults[4] == PackageManager.PERMISSION_GRANTED) {
//權(quán)限申請(qǐng)成功
myExecute();
} else {
//未得到申請(qǐng)權(quán)限的授權(quán)暑脆,不能執(zhí)行
Toast.makeText(this, "請(qǐng)通過全部權(quán)限申請(qǐng),否則無法執(zhí)行下一步操作", Toast.LENGTH_SHORT).show();
}
break;
}
}
2.搞定權(quán)限后狐肢,開始開啟定位添吗。首先創(chuàng)建一個(gè)定位樣式的實(shí)例
MyLocationStyle mls = new MyLocationStyle();
設(shè)置定位模式
只定位一次,顯示當(dāng)前的位置,顯示藍(lán)點(diǎn)份名,藍(lán)點(diǎn)不移動(dòng)碟联,手機(jī)轉(zhuǎn)動(dòng)藍(lán)點(diǎn)也不改變方向,視角不會(huì)移動(dòng)到屏幕中間
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
//定位一次僵腺,視角移動(dòng)到地圖中心點(diǎn)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
//連續(xù)定位玄帕、視角移動(dòng)到地圖中心點(diǎn),定位藍(lán)點(diǎn)跟隨設(shè)備移動(dòng)想邦。(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW);
//連續(xù)定位裤纹、視角移動(dòng)到地圖中心點(diǎn),地圖依照設(shè)備方向旋轉(zhuǎn),定位點(diǎn)會(huì)跟隨設(shè)備移動(dòng)(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
//連續(xù)定位鹰椒、視角移動(dòng)到地圖中心點(diǎn)锡移,定位點(diǎn)依照設(shè)備方向旋轉(zhuǎn),并且會(huì)跟隨設(shè)備移動(dòng)(1秒1次定位)默認(rèn)執(zhí)行此種模式漆际。
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
以下三種模式從SDK5.1.0版本開始提供
//連續(xù)定位淆珊、藍(lán)點(diǎn)不會(huì)移動(dòng)到地圖中心點(diǎn),定位點(diǎn)依照設(shè)備方向旋轉(zhuǎn)奸汇,并且藍(lán)點(diǎn)會(huì)跟隨設(shè)備移動(dòng)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
//連續(xù)定位施符、藍(lán)點(diǎn)不會(huì)移動(dòng)到地圖中心點(diǎn),并且藍(lán)點(diǎn)會(huì)跟隨設(shè)備移動(dòng)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
//連續(xù)定位擂找、藍(lán)點(diǎn)不會(huì)移動(dòng)到地圖中心點(diǎn)戳吝,地圖依照設(shè)備方向旋轉(zhuǎn),并且藍(lán)點(diǎn)會(huì)跟隨設(shè)備移動(dòng)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);
設(shè)置地圖定位的基礎(chǔ)樣式
//高德地圖自動(dòng)定位時(shí)間間隔
mls.interval(2000);
//設(shè)置自定義的定位圖標(biāo)
mls.myLocationIcon(BitmapDescriptorFactory.fromBitmap(locationBm));
//設(shè)置自定的圖標(biāo)錨點(diǎn),這里的參數(shù)含義贯涎,是指描點(diǎn)在圖標(biāo)位置的百分比听哭,
// 例(0.5f,0.4f)意思是以圖標(biāo)寬度的50%,高度的40%為中心點(diǎn)塘雳,旋轉(zhuǎn)
mls.anchor(0.5f, 0.5f);
//設(shè)置精度圈邊框顏色陆盘,不想要設(shè)置為透明色即可
mls.strokeColor(Color.GREEN);
//設(shè)置精度圈邊框?qū)挾?br>
mls.strokeWidth(10);
//設(shè)置精度圈填充顏色,不想要直接設(shè)置為透明色即可
mls.radiusFillColor(Color.TRANSPARENT);
//為Map添加定位
aMap.setMyLocationStyle(mls);
//是否顯示定位按鈕败明,可以不加
aMap.getUiSettings().setMyLocationButtonEnabled(true);
//開啟定位是否顯示藍(lán)點(diǎn)隘马,設(shè)置false則不會(huì)顯示藍(lán)點(diǎn)不會(huì)定位
aMap.setMyLocationEnabled(true);
//顯示3D建筑
aMap.showBuildings(true);
//顯示底圖文字
aMap.showMapText(true);
//顯示室內(nèi)地圖
aMap.showIndoorMap(true);
//顯示實(shí)時(shí)的交通路況
aMap.setTrafficEnabled(true);
3.同時(shí)我們可以監(jiān)聽定位數(shù)據(jù)
aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
//這里獲取經(jīng)緯度等定位信息,注意這里回調(diào)跟你設(shè)置的定位頻率是一樣的妻顶,并且一直調(diào)用
double lat = location.getLatitude();
double lng = location.getLongitude();
Log.e(TAG, "onMyLocationChange: lat=" + lat + "|lng=" + lng);
}
});
4.切換地圖圖層
//正常地圖
//AMap.MAP_TYPE_NORMAL:
//衛(wèi)星地圖
//AMap.MAP_TYPE_SATELLITE:
//夜間地圖
//AMap.MAP_TYPE_NIGHT:
//導(dǎo)航地圖
//AMap.MAP_TYPE_NAVI:
//公交地圖祟霍,不太常用
//AMap.MAP_TYPE_BUS:
aMap.setMapType(AMap.MAP_TYPE_BUS:);
- 啟用自帶的離線地圖UI
startActivity(new Intent(this.getApplicationContext(),com.amap.api.maps.offlinemap.OfflineMapActivity.class));
好了以上就是高德地圖的基礎(chǔ)操作。
代碼:
public class MainActivity extends AppCompatActivity{
private final String TAG = this.getClass().getName();
@BindView(R.id.normal_btn)
Button normalBtn;
@BindView(R.id.sate_btn)
Button sateBtn;
@BindView(R.id.night_btn)
Button nightBtn;
@BindView(R.id.navi_btn)
Button naviBtn;
@BindView(R.id.bus_btn)
Button busBtn;
@BindView(R.id.map_view)
MapView mapView;
@BindView(R.id.traffic_check)
CheckBox trafficCheck;
@BindView(R.id.off_line_btn)
Button offLineBtn;
private AMap aMap;
private MyLocationStyle mls;
private String[] mPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};
private static final int M_PERMISSION_CODE = 1001;
private Bitmap locationBm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mapView.onCreate(savedInstanceState);// 此方法必須重寫
initData();
}
private void initData() {
aMap = mapView.getMap();
locationBm = BitmapFactory.decodeResource(getResources(), R.drawable.location);
//判斷當(dāng)前Android版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//需要申請(qǐng)權(quán)限,為了方便盈包,這里我直接將地圖需要的權(quán)限都申請(qǐng)了,已啟動(dòng)就會(huì)提示授權(quán)全部權(quán)限
//大家再用的時(shí)候還是需要權(quán)限的時(shí)候再去申請(qǐng)沸呐,這樣用戶體驗(yàn)會(huì)好一點(diǎn)
if (checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)
&& checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
&& checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_PHONE_STATE)) {
//已經(jīng)申請(qǐng)直接調(diào)用
myExecute();
} else {
//開啟系統(tǒng)權(quán)限申請(qǐng)
requestPermissions(mPermissions, M_PERMISSION_CODE);
}
} else {
myExecute();
}
aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
//這里獲取經(jīng)緯度等定位信息,注意這里回調(diào)跟你設(shè)置的定位頻率是一樣的呢燥,并且一直調(diào)用
double lat = location.getLatitude();
double lng = location.getLongitude();
Log.e(TAG, "onMyLocationChange: lat=" + lat + "|lng=" + lng);
}
});
trafficCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
aMap.setTrafficEnabled(true);
} else {
aMap.setTrafficEnabled(false);
}
}
});
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case M_PERMISSION_CODE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[3] == PackageManager.PERMISSION_GRANTED
&& grantResults[4] == PackageManager.PERMISSION_GRANTED) {
//權(quán)限申請(qǐng)成功
myExecute();
} else {
//未得到申請(qǐng)權(quán)限的授權(quán)崭添,不能執(zhí)行
Toast.makeText(this, "請(qǐng)通過全部權(quán)限申請(qǐng),否則無法執(zhí)行下一步操作", Toast.LENGTH_SHORT).show();
}
break;
}
}
/**
* 執(zhí)行地圖顯示操作
*/
private void myExecute() {
// startBluePoint();
showIndoorMap();
}
/**
* 開啟地圖藍(lán)點(diǎn)
*/
private void startBluePoint() {
mls = new MyLocationStyle();
int style = 4;
//設(shè)置藍(lán)點(diǎn)模式叛氨,修改上面的style0-7呼渣,就可以看到不同的模式
setLocationStyle(mls, style);
//高德地圖自動(dòng)定位時(shí)間間隔
mls.interval(2000);
//設(shè)置自定義的定位圖標(biāo)
mls.myLocationIcon(BitmapDescriptorFactory.fromBitmap(locationBm));
//設(shè)置自定的圖標(biāo)錨點(diǎn),這里的參數(shù)含義,是指描點(diǎn)在圖標(biāo)位置的百分比寞埠,
// 例(0.5f,0.4f)意思是以圖標(biāo)寬度的50%屁置,高度的40%為中心點(diǎn),旋轉(zhuǎn)
mls.anchor(0.5f, 0.5f);
//設(shè)置精度圈邊框顏色仁连,不想要設(shè)置為透明色即可
mls.strokeColor(Color.GREEN);
//設(shè)置精度圈邊框?qū)挾? mls.strokeWidth(10);
//設(shè)置精度圈填充顏色蓝角,不想要直接設(shè)置為透明色即可
mls.radiusFillColor(Color.TRANSPARENT);
//為Map添加定位
aMap.setMyLocationStyle(mls);
//是否顯示定位按鈕阱穗,可以不加
aMap.getUiSettings().setMyLocationButtonEnabled(true);
//開啟定位是否顯示藍(lán)點(diǎn),設(shè)置false則不會(huì)顯示藍(lán)點(diǎn)不會(huì)定位
aMap.setMyLocationEnabled(true);
//顯示3D建筑
aMap.showBuildings(true);
//顯示底圖文字
aMap.showMapText(true);
}
/**
* 顯示室內(nèi)地圖,注意只有在地圖在放縮級(jí)別>=17之間才看得到室內(nèi)地圖
* 默認(rèn)是不顯示室內(nèi)地圖
*/
private void showIndoorMap() {
aMap.showIndoorMap(true);
}
/**
* 地圖圖層切換
*/
private void changeMapLayer(int layer) {
//正常地圖
//AMap.MAP_TYPE_NORMAL:
//衛(wèi)星地圖
//AMap.MAP_TYPE_SATELLITE:
//夜間地圖
//AMap.MAP_TYPE_NIGHT:
//導(dǎo)航地圖,不太常用
//AMap.MAP_TYPE_NAVI:
//公交地圖使鹅,不太常用
//AMap.MAP_TYPE_BUS:
aMap.setMapType(layer);
}
/**
* 檢查指定權(quán)限是否允許
*/
private boolean checkPermission(String permission) {
if (ActivityCompat.checkSelfPermission(this, permission) == PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void setLocationStyle(MyLocationStyle myLocationStyle, int locationStyle) {
switch (locationStyle) {
case 0:
//只定位一次,顯示當(dāng)前的位置揪阶,顯示藍(lán)點(diǎn),藍(lán)點(diǎn)不移動(dòng)患朱,手機(jī)轉(zhuǎn)動(dòng)藍(lán)點(diǎn)也不改變方向鲁僚,視角不會(huì)移動(dòng)到屏幕中間
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
break;
case 1:
//定位一次,視角移動(dòng)到地圖中心點(diǎn)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
break;
case 2:
//連續(xù)定位裁厅、視角移動(dòng)到地圖中心點(diǎn)冰沙,定位藍(lán)點(diǎn)跟隨設(shè)備移動(dòng)。(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW);
break;
case 3:
//連續(xù)定位执虹、視角移動(dòng)到地圖中心點(diǎn)拓挥,地圖依照設(shè)備方向旋轉(zhuǎn),定位點(diǎn)會(huì)跟隨設(shè)備移動(dòng)(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
break;
case 4:
//連續(xù)定位声畏、視角移動(dòng)到地圖中心點(diǎn),定位點(diǎn)依照設(shè)備方向旋轉(zhuǎn)姻成,并且會(huì)跟隨設(shè)備移動(dòng)(1秒1次定位)默認(rèn)執(zhí)行此種模式插龄。
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
break;
/**
* 以下三種模式從SDK5.1.0版本開始提供
* */
case 5:
//連續(xù)定位、藍(lán)點(diǎn)不會(huì)移動(dòng)到地圖中心點(diǎn)科展,定位點(diǎn)依照設(shè)備方向旋轉(zhuǎn)均牢,并且藍(lán)點(diǎn)會(huì)跟隨設(shè)備移動(dòng)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
break;
case 6:
//連續(xù)定位、藍(lán)點(diǎn)不會(huì)移動(dòng)到地圖中心點(diǎn)才睹,并且藍(lán)點(diǎn)會(huì)跟隨設(shè)備移動(dòng)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
break;
case 7:
//連續(xù)定位徘跪、藍(lán)點(diǎn)不會(huì)移動(dòng)到地圖中心點(diǎn),地圖依照設(shè)備方向旋轉(zhuǎn)琅攘,并且藍(lán)點(diǎn)會(huì)跟隨設(shè)備移動(dòng)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);
break;
default:
break;
}
}
@OnClick({R.id.normal_btn, R.id.sate_btn, R.id.night_btn, R.id.navi_btn, R.id.bus_btn, R.id.off_line_btn})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.normal_btn:
changeMapLayer(AMap.MAP_TYPE_NORMAL);
break;
case R.id.sate_btn:
changeMapLayer(AMap.MAP_TYPE_SATELLITE);
break;
case R.id.night_btn:
changeMapLayer(AMap.MAP_TYPE_NIGHT);
break;
case R.id.navi_btn:
changeMapLayer(AMap.MAP_TYPE_NAVI);
break;
case R.id.bus_btn:
changeMapLayer(AMap.MAP_TYPE_BUS);
break;
case R.id.off_line_btn:
startActivity(new Intent(this.getApplicationContext(),
com.amap.api.maps.offlinemap.OfflineMapActivity.class));
break;
}
}
}
上面的代碼在實(shí)際開發(fā)中垮庐,不建議大家這樣寫,有些啰嗦坞琴,我這樣寫僅僅是為了方便查看
三哨查、總結(jié)
實(shí)際上在高德地圖開發(fā)中SDK已經(jīng)為我們做了很好封裝,用起來已經(jīng)很方便了剧辐。后面還會(huì)繼續(xù)學(xué)習(xí)高德地圖的其他操作寒亥,喜歡的小伙伴可以繼續(xù)關(guān)注。上面用到了第三方庫(kù)的ButterKnife庫(kù)荧关,如有不明白的小伙伴請(qǐng)自行百度溉奕、Google。初次嘗試寫博客忍啤,不喜勿噴加勤,謝謝。