用百度API高仿微信定位demo

来源:互联网 发布:java协程 编辑:程序博客网 时间:2024/06/08 18:57

前言

demo使用Android 地图 SDK v4.1.1。
解决android6.0以上定位失败的问题(定位到非洲或者大海的问题)。

先放个效果:
定位页面.png

搜索页面.png

配置

  • 首先要在百度地图,先下载需要的包:基础定位、基础地图和检索功能。下载
  • 然后按照官方介绍如何使用百度地图API。
    android地图SDK
    android定位SDK
    里面介绍的很详细,需要仔细观看每一行介绍。
    申请密钥,配置环境和发布后,就可以使用百度地图的定位、地图和检索功能了。
    需要注意的是,由于android6.0以上新增了运行时权限动态检测。下面这三个权限需要特殊处理。
ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATIONREAD_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();                }            }        }    }

基础地图和定位功能

  1. 设置百度地图的缩放比例 (500 米)

    MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);mBaiduMap.setMapStatus(msu);
  2. 地图动画效果

    //参数latLng是指百度的经纬度类MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);mBaiduMap.animateMapStatus(u);
  3. 百度地图有两个编码方式:正向编码和反向编码。代码中,我们使用反向编码。
    正向地理编码:指的是由地址信息转换为坐标点的过程;
    反向地理编码:指的是由坐标点转换成地址信息的过程;

    调用反向地理编码

    mSearch.reverseGeoCode((new ReverseGeoCodeOption()).location(latLng));

    处理反向地理编码后的结果

    @Overridepublic 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());    }}
  4. 百度定位

    /** * 定位 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) {    }}

搜索

  1. 微信定位的搜索部分,我用了百度地图的建议查询。百度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();        }    }};
  2. listview的item点击时,需要将LatLng返回到微信定位页面,再通过反向编码获取位置信息。

    @Overridepublic 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

1 0