百度地图API使用

最近项目要接入地图定位,选择位置的功能,乙方用了百度地图,记录一下使用过程。

功能:

可以拖动marker改变定位位置;

点击POI列表对象,mark移动到相应位置;

点击定位回到当前位置。

ps: 搜索功能暂时没需要就没加,也比较简单。

目录

一、开发者平台使用

一、申请ak

二、添加相应jar包和so文件

二、定位代码实现

一、xml布局

二、recyc

目录

一、开发者平台使用

一、申请ak

二、添加相应jar包和so文件

二、定位代码实现

一、xml布局

二、activity实现

三、recycleadapter


leadapter

三、activity实现


一、开发者平台使用

一、申请ak

注册个百度地图开放平台的账号,创建一个应用 http://lbsyun.baidu.com/

SHA1值的生成,参考这个百度地图论坛置顶的帖子:

http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=106461&highlight=230

 

二、添加相应jar包和so文件

去开发者平台上下载需要的包,复制到AS里面:

我选了定位,地图和搜索的3个包,引入搜索包是因为,BaiduMap对象的点击事件监听接口的数据是经纬度对象,

用百度地图提供的GeoCoder类,可以根据经纬度查找返回地址,POI,经纬度等信息。

复制到项目里面:

把jar包作为项目依赖添加:

File --> Project Structure -->选中app 的dependence,点击 + 号,选中BaiduLBS_Android.jar 包,即可把此jar包添加为项目依赖,上图里面jar文件也出现三角号,可以点开查看了。

把libs 文件添加进依赖:

repositories {
    flatDir {
        dirs 'libs'
    }
}

 

二、定位代码实现

一、xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/search_list">

        <com.baidu.mapapi.map.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"/>

        <! 显示当前定位位置>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:background="@drawable/bg_location_name"
            android:orientation="vertical"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:visibility="visible">

            <TextView
                android:id="@+id/tv_addr"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="坐标更新"
                android:textColor="@color/white"
                android:textSize="14sp"/>
        </LinearLayout>


        <! 点击回到当前位置>
        <LinearLayout
            android:id="@+id/my_location"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:clickable="true"
            android:focusable="true"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="40dp"
            android:layout_marginLeft="16dp"
            android:layout_marginStart="16dp"
            android:background="@drawable/bg_location">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/location"/>
        </LinearLayout>

    </RelativeLayout>


    <! 显示附近POI信息>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/search_list"
        android:layout_width="match_parent"
        android:layout_height="230dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

    </android.support.v7.widget.RecyclerView>


</RelativeLayout>

 

二、activity实现

我用MVP模式写的,其实不是标准的mvp,逻辑和数据处理放在presenter里面了,没有用model进行数据处理。

1、contract类:

/**
 * 百度地图定位 contract
 */

public interface MapViewContract {

    interface View extends BusinessView<Presenter> {
        void showAddr(ReverseGeoCodeResult result);
    }

    abstract class Presenter extends BusinessPresenter<View> {
        public Presenter(BusinessActivity activity, View view) {
            super(activity, view);
        }
        //将mapView对象传过来,用来实例化BaiduMap对象
        public abstract void getAddr(MapView mMapView);
        public abstract void backToCurrentLocation();//回到当前位置
        public abstract void setMarkLocation(LatLng latLng);//设置marker位置

    }


}

2、activity

/**
 * 可拖动 marker 定位
 */

public class MapViewActivity extends BusinessActivity<MapViewContract.Presenter> implements MapViewContract.View, View.OnClickListener, LocationItemAdapter.onItemClickListener {

    private MapView mMapView;
    private TextView tvAddr;
    private String locationAdrr = "";
    private LinearLayout myLocation;
    private RecyclerView searchListRecycle;
    private LocationItemAdapter adapter;
    private List<PoiInfo> poiInfoList = new ArrayList<>();

    private double longitude;
    private double latitude;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_view);
        new MapViewPresenter(this, this);
        setTitle("选择位置");
        showAheadLayout();
        getAheadTextView().setText("确定");
        initView();
    }

    private void initView() {
        mMapView = (MapView) findViewById(R.id.mapView);
        tvAddr = (TextView) findViewById(R.id.tv_addr);
        getPresenter().getAddr(mMapView);
        myLocation = (LinearLayout) findViewById(R.id.my_location);
        myLocation.setOnClickListener(this);
        searchListRecycle = (RecyclerView) findViewById(R.id.search_list);

        adapter = new LocationItemAdapter();
        adapter.setItemList(poiInfoList);
        adapter.setListener(this);
        searchListRecycle.setLayoutManager(new LinearLayoutManager(this));
        searchListRecycle.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        searchListRecycle.setAdapter(adapter);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.my_location:
                //marker回到当前位置
                getPresenter().backToCurrentLocation();
                break;
        }
    }


    //点击确定,返回定位的结果
    @Override
    public void onBarItemClick(ToolBarButton id) {
        if (id == ToolBarButton.AHEAD) {
            Intent intent = new Intent();
            intent.putExtra(KeyName.ADDR_NAME, locationAdrr);
            intent.putExtra(KeyName.ADDR_NAME_longitude,longitude);
            intent.putExtra(KeyName.ADDR_NAME_latitude,latitude);
            setResult(IntentCode.RESULT_ADDR_NAME, intent);
            finish();
        }
        super.onBarItemClick(id);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    protected void onDestroy() {
        mMapView.onDestroy();
        mMapView = null;
        super.onDestroy();

    }

    //获取到定位信息和周围POI,返回结果,view展示数据
    @Override
    public void showAddr(ReverseGeoCodeResult result) {
        tvAddr.setText(result.getAddress());
        locationAdrr = result.getAddress();
        longitude = result.getLocation().longitude;
        latitude = result.getLocation().latitude;
        this.poiInfoList = result.getPoiList();
        adapter.setItemList(poiInfoList);
        adapter.notifyDataSetChanged();
    }

    //点击POI列表的对象,更新数据,设置marker位置
    @Override
    public void onItemClick(PoiInfo data, int position) {
        if (null != data) {
            tvAddr.setText(data.address);
            locationAdrr = data.address;
            longitude = data.location.longitude;
            latitude = data.location.latitude;
            getPresenter().setMarkLocation(data.location);
        }
    }
}

3、presenter类

/**
 * 百度地图定位 presenter
 */

public class MapViewPresenter extends MapViewContract.Presenter implements OnGetGeoCoderResultListener, OnGetPoiSearchResultListener {
    private BaiduMap mBaiduMap = null;
    private MyLocationData locData; //定位数据包
    private Marker marker;//位置标志
    boolean isFirstLoc = true; // 是否首次定位
    LocationClient mLocClient;
    GeoCoder mSearch = null; // 搜索模块,根据经纬度获取位置信息,也可去掉地图模块独立使用
    PoiSearch mPoiSearch;//搜索附近POI,可用于根据关键字搜索位置

    public MapViewPresenter(BusinessActivity activity, MapViewContract.View view) {
        super(activity, view);
    }

    @Override
    public void getAddr(MapView mMapView) {
        mBaiduMap = mMapView.getMap();
        //设置类型
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(18f));
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);

        //用application对象初始化LocationClient 对象
        mLocClient = new LocationClient(getActivity().getApplicationContext());
        //设置位置监听器
        mLocClient.registerLocationListener(listener);

        LocationClientOption option = new LocationClientOption();
        option.setIsNeedAddress(true);//是否要地址
        option.setOpenGps(true);
        option.setCoorType("bd09ll"); // 设置坐标类型
        //设置定位模式:高精度,低功耗,仅设备
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的    
        option.setScanSpan(3000);

        mLocClient.setLocOption(option);
        mLocClient.start();


        //对Marker的点击事件
        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                //获取marker中的数据
                searchNearBy(marker.getPosition());
                return false;
            }
        });

        //Map点击事件,点击地图移动marker
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                //设置marker位置,将marker移动到点击地图位置
                marker.setPosition(latLng);

                //反Geo搜索,根据经纬度搜索位置和POI信息
                searchNearBy(marker.getPosition());

            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                //同上
                marker.setPosition(mapPoi.getPosition());
                searchNearBy(marker.getPosition());

                return false;
            }
        });

        //对Marker的拖拽事件
        mBaiduMap.setOnMarkerDragListener(new BaiduMap.OnMarkerDragListener() {
            @Override
            public void onMarkerDrag(Marker marker) {

            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
                //根据经纬度获取位置和POI信息
                searchNearBy(marker.getPosition());
            }

            @Override
            public void onMarkerDragStart(Marker marker) {

            }
        });

        // 初始化搜索模块,注册事件监听
        mSearch = GeoCoder.newInstance();
        mSearch.setOnGetGeoCodeResultListener(this);

        //初始化POI搜索对象,可根据关键字搜索地址,但是此处我没有使用它
        mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(this);
    }

    //点击回到当前位置
    @Override
    public void backToCurrentLocation() {
        mLocClient.start();
    }

    //点击POI列表的item,对应移动marker到相应位置
    @Override
    public void setMarkLocation(LatLng latLng) {
        if (null != marker) {
            marker.setPosition(latLng);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(latLng).zoom(18.0f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }


    /***
     * 定位结果回调,在此方法中处理定位结果
     */
    BDAbstractLocationListener listener = new BDAbstractLocationListener() {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {

            // map view 销毁后不在处理新接收的位置
            if (mLocClient == null || null == bdLocation) {
                return;
            }

            //构造定位数据
            locData = new MyLocationData.Builder()
                    .accuracy(bdLocation.getRadius())
                    .latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude())
                    // 此处设置开发者获取到的方向信息,顺时针0-360
                    .direction(100)
                    .build();

            mBaiduMap.setMyLocationData(locData);
            LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());

            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(18.0f);
            
//更新地图状态
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

            //根据经纬度搜索地址和POI信息
            searchNearBy(ll);

            //只有第一次定位的时候,构造marker对象
            if (isFirstLoc) {

                isFirstLoc = false;

                BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.locationmark);
                // 构建MarkerOption,用于在地图上添加Marker
                OverlayOptions option = new MarkerOptions()
                        .position(ll) //mark出现的位置
                        .icon(bitmap) //mark图标
                        .draggable(true);//mark可拖动
                //在地图上添加Marker并显示
                marker = (Marker) mBaiduMap.addOverlay(option);

            } else {
                //不是第一次定位,设置marker移动到当前定位的位置
                if (null != marker) {
                    marker.setPosition(ll);
                }
            }


            mLocClient.stop();
        }
    };

    //根据经纬度,用GeoCoder 对象反geo编码获取到位置信息
    public void searchNearBy(LatLng latLng) {
        if (null != latLng) {
            mSearch.reverseGeoCode(new ReverseGeoCodeOption()
                    .location(latLng));
        } else {
            ToastUtil.toast("未找到结果");
        }

    }

    //反geo搜索的 OnGetGeoCodeResultListener返回数据接口
    @Override
    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
            ToastUtil.toast("未能找到结果");
            return;
        }
        getView().showAddr(result);
    }

    //geo搜索的 OnGetGeoCodeResultListener返回数据接口,此处用不到
    @Override
    public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //退出时销毁定位
        mLocClient.stop();
        //退出时关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mSearch.destroy();
    }

    /**
     * 通过经纬度 和 关键字 搜索poi,此处没有用到
     *
     * @param latLng
     */
    private void search(LatLng latLng, String name) {
        if (null != name) {
            mPoiSearch.searchNearby(new PoiNearbySearchOption().keyword(name)
                    .location(latLng).radius(500).pageNum(1));
        } else {
            ToastUtil.toast("未找到结果");
            //view 的POI列表显示空
        }
    }

    //mPoiSearch.setOnGetPoiSearchResultListener监听器返回数据接口,此处没用到
    //可用于关键字搜索位置信息和POI信息
    @Override
    public void onGetPoiResult(PoiResult poiResult) {
        if (poiResult == null || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            ToastUtil.toast("未找到结果");
            return;
        }
        if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {
            ToastUtil.toast("poi 数目:" + poiResult.getAllPoi().size());
            return;
        }
    }

    @Override
    public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

    }

    @Override
    public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

    }
}

三、recycleadapter

/**
 * 百度地图定位,显示POI
 */

public class LocationItemAdapter extends RecyclerView.Adapter<LocationItemAdapter.ViewHolder> implements View.OnClickListener {

    private List<PoiInfo> itemList;
    private onItemClickListener listener;
    private int position;

    public void setListener(onItemClickListener listener) {
        this.listener = listener;
    }

    public void setItemList(List<PoiInfo> itemList) {
        this.itemList = itemList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_map_location, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.tvName.setText(itemList.get(position).name);
        holder.tvAddress.setText(itemList.get(position).address);
        holder.itemView.setTag(itemList.get(position));
        this.position = position;
        holder.rootView.setOnClickListener(this);

    }

    @Override
    public int getItemCount() {
        if (null != itemList) {
            return itemList.size();
        }
        return 0;
    }

    @Override
    public void onClick(View v) {
        PoiInfo data = (PoiInfo) v.getTag();
        if (null != data && null != listener) {
            listener.onItemClick(data, position);
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public View rootView;
        public TextView tvName;
        public TextView tvAddress;

        public ViewHolder(View rootView) {
            super(rootView);
            this.rootView = rootView;
            this.tvName = (TextView) rootView.findViewById(R.id.tv_name);
            this.tvAddress = (TextView) rootView.findViewById(R.id.tv_address);
        }

    }

    public interface onItemClickListener {
        void onItemClick(PoiInfo data, int position);
    }
}

注:手势操作管理

UiSettings settings=mBaiduMap.getUiSettings();
settings.setAllGesturesEnabled(false);   //关闭一切手势操作
settings.setZoomGesturesEnabled(false);//是否允许缩放手势

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值