基于百度地图实现融云 sdk 2.8.0+ 发送地理位置

来源:互联网 发布:网络在线教育评价 编辑:程序博客网 时间:2024/05/24 01:17

融云 sdk 2.8.0+ 内置的高德地图的发送位置。但是百度地图在地图市场占有率也是相当高的。为了满足使用百度地图的开发者,本篇文档对如何在 sdk 2.8.0 以上实现百度地图发送地理位置消息做讲解。


效果图

网络下可见
网络下可见
网络下可见

集成前准备

  • 注册百度地图开放平台,可能需要审核开发者身份
  • 创建 Android 应用, 生成 sha1 码获取百度地图 appkey
  • 下载百度地图 SDK、 Demo、 Doc

Code

集成前需要将百度相关的 jar so 文件 以及 manifest 中需要配置的服务 和 appkey 都配置好,还需要在 application 中调用百度地图的初始化方法。

SDKInitializer.initialize(getApplicationContext());

这里写图片描述


集成前建议把 融云 sdk 2.8.0+ Extension 文档 通读,这样对概念理解 和 后面集成都有很大的帮助。

BaiDuLocationPlugin

public class BaiDuLocationPlugin implements IPluginModule {    private Conversation.ConversationType conversationType;    private String targetId;    @Override    public Drawable obtainDrawable(Context context) {        //设置插件 Plugin 图标        return context.getResources().getDrawable(R.drawable.rc_ext_plugin_location_selector);    }    @Override    public String obtainTitle(Context context) {        //设置插件 Plugin 展示文字        return "百度地图";    }    @Override    public void onClick(final Fragment currentFragment, RongExtension extension) {        //示例获取 会话类型、targetId、Context,此处可根据产品需求自定义逻辑,如:开启新的 Activity 等。        conversationType = extension.getConversationType();        targetId = extension.getTargetId();        //只有通过 extension 中的 startActivityForPluginResult 才会返回到本类中的 onActivityResult        extension.startActivityForPluginResult(new Intent(currentFragment.getActivity(),BaiDuLocationActivity.class),5, this);    }    @Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        if (data != null) {            double latitude = data.getDoubleExtra("latitude",0.00);            double longitude = data.getDoubleExtra("longitude",0.00);            String address = data.getStringExtra("address");            String uri = data.getStringExtra("locuri");            LocationMessage locationMessage = LocationMessage.obtain(latitude,longitude,address, Uri.parse(uri));            RongIM.getInstance().sendLocationMessage(Message.obtain(targetId, conversationType, locationMessage), null, null, null);        }    }}

此类是一个关键类,包含了唤起地图定位的 Activity ,和 onActivityResult 返回相关经纬度数据后的发送地理位置消息逻辑,请通读上面类 和 类中的注释。(参考上面 Plugin 实现可以不用理会 融云 sdk 内部接口 地理位置提供者 )

BaiDuLocationActivity

此类是地图展示的 activity 类,展示成什么逻辑由开发者自己定义。但是最少需要获取到给 BaiDuLocationPlugin 的四个参数为: 纬度,经度,地图的 uri,和位置信息的 String。

public class BaiDuLocationActivity extends BaseActivity{    public static final int RESULT_CODE = 6;    MapView mMapView;    BaiduMap baiduMap;    private double longitude;    private double latitude;    LatLng mLoactionLatLng;    private String address;    LocationClient locationClient;    LocationMessage mMsg;    boolean isFirstLoc = true;    Point mCenterPoint;    GeoCoder mGeoCoder;    List<PoiInfo> mInfoList;    PoiInfo mCurentInfo;    ListView Maplistview;    PlaceListAdapter customListAdpter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_map_location);        initview();        getimgxy();    }    private void initview() {      Button mRightButton = getHeadRightButton();        mRightButton.setBackground(getResources().getDrawable(R.drawable.icon1_menu));        Maplistview = (ListView) findViewById(R.id.mymapListView);        setTitle("地理位置");        mRightButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Uri uri = Uri.parse("http://api.map.baidu.com/staticimage?width=300&height=200&center="+ longitude + "," + latitude + "&zoom=17&markers=" + longitude + "," + latitude + "&markerStyles=m,A");                Intent intent = new Intent();                intent.putExtra("latitude", latitude);                intent.putExtra("longitude", longitude);                intent.putExtra("address",address);                intent.putExtra("locuri",uri.toString());                setResult(RESULT_CODE , intent);                finish();            }        });        mMapView = (MapView) findViewById(R.id.bmapView);        mMapView.showZoomControls(false);        baiduMap = mMapView.getMap();        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);        baiduMap.setMapStatus(msu);        //开启定位图层        baiduMap.setMyLocationEnabled(true);        baiduMap.setOnMapTouchListener(touchListener);        try {            if (getIntent().hasExtra("location")) {                mMsg = getIntent().getParcelableExtra("location");            }            if (mMsg != null) {                Maplistview.setVisibility(View.GONE);                locationClient = new LocationClient(getApplicationContext()); // 实例化LocationClient类                MyLocationData locData = new MyLocationData.Builder()                        // 此处设置开发者获取到的方向信息,顺时针0-360                        .direction(100).latitude(mMsg.getLat())                        .longitude(mMsg.getLng()).build();                baiduMap.setMyLocationData(locData);    //设置定位数据                mLoactionLatLng = new LatLng(mMsg.getLat(),                        mMsg.getLng());                MapStatusUpdate u = MapStatusUpdateFactory.newLatLngZoom(mLoactionLatLng, 16);    //设置地图中心点以及缩放级别                baiduMap.animateMapStatus(u);            } else {                locationClient = new LocationClient(getApplicationContext()); // 实例化LocationClient类                locationClient.registerLocationListener(myListener); // 注册监听函数                this.setLocationOption();    //设置定位参数                locationClient.start(); // 开始定位            }        } catch (Exception e) {        }    }    @Override    protected void onDestroy() {        super.onDestroy();        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理        mMapView.onDestroy();    }    @Override    protected void onResume() {        super.onResume();        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理        mMapView.onResume();    }    @Override    protected void onPause() {        super.onPause();        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理        mMapView.onPause();    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            locationClient.stop();            Log.d("stop", "定位关闭");            finish();        }        return false;    }    /**     * 设置定位参数     */    private void setLocationOption() {        LocationClientOption option = new LocationClientOption();        option.setOpenGps(true); // 打开GPS        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);// 设置定位模式        option.setCoorType("bd09ll"); // 返回的定位结果是百度经纬度,默认值gcj02        option.setScanSpan(5000); // 设置发起定位请求的间隔时间为5000ms        option.setIsNeedAddress(true); // 返回的定位结果包含地址信息        option.setNeedDeviceDirect(true); // 返回的定位结果包含手机机头的方向        locationClient.setLocOption(option);    }    public BDLocationListener myListener = new BDLocationListener() {        @Override        public void onReceiveLocation(BDLocation location) {            // map view 销毁后不在处理新接收的位置            if (location == null || mMapView == null)                return;            latitude = location.getLatitude();            longitude = location.getLongitude();            address = location.getAddrStr();            MyLocationData locData = new MyLocationData.Builder()        /*.accuracy(location.getRadius())*/                    // 此处设置开发者获取到的方向信息,顺时针0-360                    .direction(100).latitude(location.getLatitude())                    .longitude(location.getLongitude()).build();            baiduMap.setMyLocationData(locData);    //设置定位数据            if (isFirstLoc) {                isFirstLoc = false;                mLoactionLatLng = new LatLng(location.getLatitude(),                        location.getLongitude());                MapStatusUpdate u = MapStatusUpdateFactory.newLatLngZoom(mLoactionLatLng, 20);//设置地图中心点以及缩放级别                baiduMap.animateMapStatus(u);            }            // 获取当前MapView中心屏幕坐标对应的地理坐标            LatLng currentLatLng;            currentLatLng = baiduMap.getProjection().fromScreenLocation(                    mCenterPoint);            System.out.println("----" + mCenterPoint.x);            System.out.println("----" + currentLatLng.latitude);            // 发起反地理编码检索            mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())                    .location(currentLatLng));        }    };    /**     * 初始化地图物理坐标     */    private void getimgxy() {        // 初始化POI信息列表        mInfoList = new ArrayList<PoiInfo>();        mCenterPoint = baiduMap.getMapStatus().targetScreen;        mLoactionLatLng = baiduMap.getMapStatus().target;// 地理编码        mGeoCoder = GeoCoder.newInstance();        mGeoCoder.setOnGetGeoCodeResultListener(GeoListener);        customListAdpter = new PlaceListAdapter(getLayoutInflater(), mInfoList);        Maplistview.setAdapter(customListAdpter);        Maplistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {                customListAdpter.clearSelection(i);                customListAdpter.notifyDataSetChanged();                locationClient.stop();                baiduMap.clear();                PoiInfo info = (PoiInfo) customListAdpter.getItem(i);                LatLng la = info.location;                latitude = la.latitude;                longitude = la.longitude;                address = info.address;                MyLocationData locData = new MyLocationData.Builder()        /*.accuracy(location.getRadius())*/                        // 此处设置开发者获取到的方向信息,顺时针0-360                        .direction(100).latitude(la.latitude)                        .longitude(la.longitude).build();                baiduMap.setMyLocationData(locData);                //设置定位数据                mLoactionLatLng = new LatLng(la.latitude,                        la.longitude);                MapStatusUpdate u = MapStatusUpdateFactory.newLatLngZoom(mLoactionLatLng, 20);    //设置地图中心点以及缩放级别                baiduMap.animateMapStatus(u);            }        });    }    // 地理编码监听器    OnGetGeoCoderResultListener GeoListener = new OnGetGeoCoderResultListener() {        public void onGetGeoCodeResult(GeoCodeResult result) {            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {                // 没有检索到结果            }            // 获取地理编码结果        }        @Override        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {                // 没有找到检索结果            }            // 获取反向地理编码结果            else {                // 当前位置信息                mCurentInfo = new PoiInfo();                mCurentInfo.address = result.getAddress();                mCurentInfo.location = result.getLocation();                mCurentInfo.name = "[位置]";                mInfoList.clear();                mInfoList.add(mCurentInfo);                // 将周边信息加入表                if (result.getPoiList() != null) {                    mInfoList.addAll(result.getPoiList());                }                // 通知适配数据已改变                customListAdpter.notifyDataSetChanged();       /* mLoadBar.setVisibility(View.GONE);*/            }        }    };    // 地图触摸事件监听器    BaiduMap.OnMapTouchListener touchListener = new BaiduMap.OnMapTouchListener() {        @Override        public void onTouch(MotionEvent event) {            if (event.getAction() == MotionEvent.ACTION_UP) {                if (mCenterPoint == null) {                    return;                }                // 获取当前MapView中心屏幕坐标对应的地理坐标                LatLng currentLatLng;                currentLatLng = baiduMap.getProjection().fromScreenLocation(                        mCenterPoint);                System.out.println("----" + mCenterPoint.x);                System.out.println("----" + currentLatLng.latitude);                // 发起反地理编码检索                mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())                        .location(currentLatLng));            }        }    };}

开发者可参考上面代码,但是由于里面基本全是百度地图的 API 和 接口,如有遇到地图相关问题。本人和本篇 blog 对百度地图不做解释

调用代码

调用代码是演示如何把写好的百度地图的 Plugin 展示在 +号扩展区域中

public class SampleExtensionModule extends DefaultExtensionModule {    private EditText mEditText;    @Override    public List<IPluginModule> getPluginModules(Conversation.ConversationType conversationType) {//        super.getPluginModules(conversationType);  如果需要对红包进行排序可从父类中的 getPluginModules 集合中过滤取出 JrmfExtensionModule        List<IPluginModule> pluginModuleList = new ArrayList<>();        pluginModuleList.add(new BaiDuLocationPlugin());        pluginModuleList.add(new ImagePlugin());        // 此时扩展区域的展示顺序应该为 : 百度地图、图片、红包        return pluginModuleList;    }    @Override    public void onAttachedToExtension(RongExtension extension) {        mEditText = extension.getInputEditText();    }    @Override    public void onDetachedFromExtension() {        mEditText = null;    }    @Override    public List<IEmoticonTab> getEmoticonTabs() {        return super.getEmoticonTabs();    }}
       List<IExtensionModule> moduleList = RongExtensionManager.getInstance().getExtensionModules();        IExtensionModule defaultModule = null;        if (moduleList != null) {            for (IExtensionModule module : moduleList) {                if (module instanceof DefaultExtensionModule) {                    defaultModule = module;                    break;                }            }            if (defaultModule != null) {                RongExtensionManager.getInstance().unregisterExtensionModule(defaultModule);//                RongExtensionManager.getInstance().registerExtensionModule(new SealExtensionModule());                RongExtensionManager.getInstance().registerExtensionModule(new SampleExtensionModule());            }        }

参考资料

http://blog.csdn.net/qq_19986309/article/details/53302350
https://github.com/AnOneTable/CanonHouse

0 0
原创粉丝点击