demo使用Android 地图 SDK v4.1.1。
解决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上:BaiduWeChatPosition