地圖的相關操作步驟根據百度地圖的操作文檔進行,就可以在項目中進行百度地圖的訪問(地圖SDK地址:http://lbsyun.baidu.com/index.php?title=androidsdk),
總結一下地圖的幾個操作步驟:
1.註冊和獲取祕鑰(百度地圖 SDK開發密鑰的申請地址爲:http://lbsyun.baidu.com/apiconsole/key)
2.獲取安全碼
3.copy相關開發包
4.實現地圖功能,以及相關配置信息
定位功能參考相關文檔可以進行功能實現
地圖權限分爲兩塊,一塊是網絡訪問權限,一塊是GPS定位
1、定位問題:
定位需要在項目中添加添加定位權限,定位參考demo地址:http://lbsyun.baidu.com/index.php?title=android-locsdk
<!-- 這個權限用於進行網絡定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 這個權限用於訪問GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
由於目前的android版本升級,6.0以上需要動態申請權限,所以在某些手機上面必須要動態申請權限
XXPermissions.with(getActivity())
//請求獲取拍照權限
.permission(Permission.CAMERA)
.request(new OnPermission() {
@Override
public void hasPermission(List<String> granted, boolean isAll) {
if (isAll) {
//掃碼
Intent intent = new Intent(getActivity(), CaptureActivity.class);
intent.putExtra("fragmentName", "AbnormalFragment");
startActivityForResult(intent, Contacts.REQUESTCODE_ABNORMAL_FRAGMENT_CAPTURE);
} else {
Toast.makeText(getActivity(), "獲取權限成功,部分權限未正常授予", Toast.LENGTH_SHORT).show();
}
}
@Override
public void noPermission(List<String> denied, boolean quick) {
if (quick) {
Toast.makeText(getActivity(), "被永久拒絕授權,請手動授予權限", Toast.LENGTH_SHORT).show();
//如果是被永久拒絕就跳轉到應用權限系統設置頁面
XXPermissions.gotoPermissionSettings(getActivity());
} else {
Toast.makeText(getActivity(), "獲取權限失敗", Toast.LENGTH_SHORT).show();
}
}
});
需要動態請求的權限目錄如下:
public static final String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES"; // 8.0及以上應用安裝權限
public static final String SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW"; // 6.0及以上懸浮窗權限
public static final String READ_CALENDAR = "android.permission.READ_CALENDAR"; // 讀取日程提醒
public static final String WRITE_CALENDAR = "android.permission.WRITE_CALENDAR"; // 寫入日程提醒
public static final String CAMERA = "android.permission.CAMERA"; // 拍照權限
public static final String READ_CONTACTS = "android.permission.READ_CONTACTS"; // 讀取聯繫人
public static final String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS"; // 寫入聯繫人
public static final String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"; // 訪問賬戶列表
public static final String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION"; // 獲取精確位置
public static final String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION"; // 獲取粗略位置
public static final String RECORD_AUDIO = "android.permission.RECORD_AUDIO"; // 錄音權限
public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; // 讀取電話狀態
public static final String CALL_PHONE = "android.permission.CALL_PHONE"; // 撥打電話
public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG"; // 讀取通話記錄
public static final String WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG"; // 寫入通話記錄
public static final String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL"; // 添加語音郵件
public static final String USE_SIP = "android.permission.USE_SIP"; // 使用SIP視頻
public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS"; // 處理撥出電話
public static final String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";// 8.0危險權限:允許您的應用通過編程方式接聽呼入電話。要在您的應用中處理呼入電話,您可以使用 acceptRingingCall() 函數
public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";// 8.0危險權限:權限允許您的應用讀取設備中存儲的電話號碼
public static final String BODY_SENSORS = "android.permission.BODY_SENSORS"; // 傳感器
public static final String SEND_SMS = "android.permission.SEND_SMS"; // 發送短信
public static final String RECEIVE_SMS = "android.permission.RECEIVE_SMS"; // 接收短信
public static final String READ_SMS = "android.permission.READ_SMS"; // 讀取短信
public static final String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH"; // 接收WAP PUSH信息
public static final String RECEIVE_MMS = "android.permission.RECEIVE_MMS"; // 接收彩信
public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"; // 讀取外部存儲
public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; // 寫入外部存儲
2、地圖的網絡權限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
//獲取設備網絡狀態,禁用後無法獲取網絡狀態
<uses-permission android:name="android.permission.INTERNET"/>
//網絡權限,當禁用後,無法進行檢索等相關業務
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
//讀取設備硬件信息,統計數據
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
//讀取系統信息,包含系統版本等信息,用作統計
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
//獲取設備的網絡狀態,鑑權所需網絡代理
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//允許sd卡寫權限,需寫入地圖數據,禁用後無法顯示地圖
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
//獲取統計數據
<uses-permission android:name="android.permission.CAMERA" />
//使用步行AR導航,配置Camera權限
3、 地圖的BUG
在實現的過程中 遇到一種狀況,在進入界面中正常顯示了當前定位之後,在手機上把網絡或者GPS定位關閉了,之後,點擊定位,程序崩潰的問題
處理方式:在MyLocationListener 中實現onLocDiagnosticMessage方法,該方法用於處理異常定位情況
衍生問題由於onLocDiagnosticMessage是優先於定位處理異常情況,所以在定位onReceiveLocation方法中需要處理返回的異常信息不再顯示的問題
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//得到當前的地址
adfState.setMapAddress(location.getAddrStr());
Log.e("是否是國外:", "" + (location.getLocationWhere() != BDLocation.LOCATION_WHERE_IN_CN));
//BDLocation.getLocationWhere()方法可獲得當前定位點是否是國內,它的取值及含義如下:
//BDLocation.LOCATION_WHERE_IN_CN:當前定位點在國內;
//BDLocation.LOCATION_WHERE_OUT_CN:當前定位點在海外;
if (location.getLocationWhere() != BDLocation.LOCATION_WHERE_IN_CN) {
//定位失敗會優先調用onLocDiagnosticMessage方法,該方法已經提示了錯誤信息了,所以就不用再提示
if (adfState.isShowMapError()) {
Toast.makeText(mActivity, "定位失敗,請打開定位服務", Toast.LENGTH_SHORT).show();
}
mLocationClient.stop();
bdLocation = null;
} else {
bdLocation = location;
setMapAddress();
}
}
@Override
public void onLocDiagnosticMessage(int result, int type, String s) {
super.onLocDiagnosticMessage(result, type, s);
MapErrorUtil.showMapError(getActivity(), result, type);
//由於該方法是先於定位執行,所以在彈出提示之後就禁止在彈出錯誤信息
adfState.setShowMapError(false);
}
}
4、 關於地圖上,顯示的定位圖標偏移,不是垂直顯示的問題
解決辦法:在設置MyLocationData參數的時候,有個設置偏移度的方法direction(XX),XX代表偏移的度數,範圍是(0-360),設置的度數不同,圖標就會偏移相同的度數
要垂直顯示,直接設置XX爲0 就可以解決了
5、 地圖 經緯度轉地址,地址轉經緯度
解決方法: 在初始化地圖時候實現GeoCoder這個類的setOnGetGeoCodeResultListener方法,就可以了
GeoCoder geoCoder;//定義一個變量
geoCoder = GeoCoder.newInstance();
//設置地址或經緯度反編譯後的監聽,這裏有兩個回調方法,
geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
//經緯度轉換成地址
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MapActivity.this, "找不到該地址!", Toast.LENGTH_SHORT).show();
}
LogUtils.e("地址:" + result.getAddress());
mapAddress = result.getAddress();
}
//把地址轉換成經緯度
@Override
public void onGetGeoCodeResult(GeoCodeResult result) {
}
});
在地圖定位的BaiduMap.OnMapClickListener 的onMapClick中註冊該方法
BaiduMap.OnMapClickListener listene1 = new BaiduMap.OnMapClickListener() {
/**
* 地圖單擊事件回調函數
* @param point 點擊的地理座標
*/
@Override
public void onMapClick(LatLng point) {
//.... 其他的代碼
// 設置反地理經緯度座標,請求位置時,需要一個經緯度
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(point));
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi) {
return false;
}
};