用百度API高仿微信定位demo
阿新 • • 發佈:2019-01-03
前言
demo使用Android 地圖 SDK v4.1.1。
解決android6.0以上定位失敗的問題(定位到非洲或者大海的問題)。
先放個效果:
配置
- 首先要在百度地圖,先下載需要的包:基礎定位、基礎地圖和檢索功能。下載
- 然後按照官方介紹如何使用百度地圖API。
android地圖SDK
android定位SDK
裡面介紹的很詳細,需要仔細觀看每一行介紹。
申請金鑰,配置環境和釋出後,就可以使用百度地圖的定位、地圖和檢索功能了。
需要注意的是,由於android6.0以上新增了執行時許可權動態檢測。下面這三個許可權需要特殊處理。
ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION READ_PHONE_STATE
我將許可權的判斷和使用放在歡迎頁面。
/** * 仿微信歡迎頁面,在此處處理 android6.0 許可權 * * @author chenjunxu * @date 16/12/26 */ public class WelcomeActivity extends Activity { /** * 需要 android6.0 以上處理的許可權 */ private String[] PERMISSIONS = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_welcome); // android 系統大於等於 6.0 時需要處理時許可權 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestNeedPermission(); } else { goToMain(); } } /** * 進入首頁面 */ private void goToMain() { new Handler().postDelayed(new Runnable() { @Override public void run() { Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); startActivity(intent); WelcomeActivity.this.finish(); } }, 1200); } /** * 判斷是否需要進行許可權的請求 */ private void requestNeedPermission() { boolean temp = false; for (String permission : PERMISSIONS) { if (!hasPermissionGranted(permission)) { temp = true; break; } } // 需要許可權則請求許可權 if (temp) { ActivityCompat.requestPermissions(this, PERMISSIONS, 0); } else { goToMain(); } } /** * 判斷該許可權是否已經授權 * * @param permission * @return */ private boolean hasPermissionGranted(String permission) { return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED; } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 0) { boolean temp = false; for (int i = 0; i < grantResults.length; i++) { if (grantResults[i] == PackageManager.PERMISSION_DENIED) { Toast.makeText(WelcomeActivity.this, " 拒絕 " + grantResults[i] + " 許可權會導致定位失敗!", Toast.LENGTH_LONG).show(); temp = true; break; } } // 再次請求許可權 if (temp) { requestNeedPermission(); } else { goToMain(); } } } }
基礎地圖和定位功能
設定百度地圖的縮放比例 (500 米)
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f); mBaiduMap.setMapStatus(msu);
地圖動畫效果
//引數latLng是指百度的經緯度類 MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng); mBaiduMap.animateMapStatus(u);
百度地圖有兩個編碼方式:正向編碼和反向編碼。程式碼中,我們使用反向編碼。
正向地理編碼:指的是由地址資訊轉換為座標點的過程;
反向地理編碼:指的是由座標點轉換成地址資訊的過程;呼叫反向地理編碼
mSearch.reverseGeoCode((new ReverseGeoCodeOption()).location(latLng));
處理反向地理編碼後的結果
@Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { return; } // 獲取反向地理編碼結果 PoiInfo mCurrentInfo = new PoiInfo(); mCurrentInfo.address = result.getAddress(); mCurrentInfo.location = result.getLocation(); mCurrentInfo.name = result.getAddress(); // result是定位到當前位置的資訊 if (!TextUtils.isEmpty(mCurrentInfo)) { datas.add(mCurrentInfo); } // result.getPoiList()是當前位置附近的資訊 if (result.getPoiList() != null && result.getPoiList().size() > 0) { datas.addAll(result.getPoiList()); } }
百度定位
/** * 定位 SDK 監聽函式 */ public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { // map view 銷燬後不在處理新接收的位置 if (location == null || bmapView == null) { return; } MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius()) .latitude(location.getLatitude()) .longitude(location.getLongitude()).build(); mBaiduMap.setMyLocationData(locData); Double mLatitude = location.getLatitude(); Double mLongitude = location.getLongitude(); // 是否第一次定位。第一次定位需要移動地圖 if (isFirstLoc) { isFirstLoc = false; LatLng currentLatLng = new LatLng(mLatitude, mLongitude); // 實現動畫跳轉 MapStatusUpdate u = MapStatusUpdateFactory .newLatLng(currentLatLng); mBaiduMap.animateMapStatus(u); // 反向地理編碼 mSearch.reverseGeoCode((new ReverseGeoCodeOption()) .location(currentLatLng)); return; } } public void onReceivePoi(BDLocation poiLocation) { } }
搜尋
微信定位的搜尋部分,我用了百度地圖的建議查詢。百度API用
OnGetSuggestionResultListener
監聽獲取的查詢結果。OnGetSuggestionResultListener mSuggestionResultListener = new OnGetSuggestionResultListener() { // 獲得結果 public void onGetSuggestionResult(SuggestionResult res) { if (res == null || res.getAllSuggestions() == null) { Toast.makeText(mContext, " 沒找到結果 ", Toast.LENGTH_LONG).show(); return; } // 獲取線上建議檢索結果 if (datas != null) { datas.clear(); for (SuggestionResult.SuggestionInfo suggestionInfos : res.getAllSuggestions()) { datas.add(suggestionInfos); } locatorAdapter.notifyDataSetChanged(); } } };
listview的item點選時,需要將LatLng返回到微信定位頁面,再通過反向編碼獲取位置資訊。
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(); // 設定座標 intent.putExtra("LatLng", datas.get(position).pt); setResult(RESULT_OK, intent); SearchPositionActivity.this.finish(); }
結尾
還有很多細節問題沒有在此處介紹,需要的朋友請在git上拉下來檢視。
程式碼已經上傳到git上: