基于高德地图实现融云位置共享功能

基于高德地图实现融云位置共享功能(Android篇)

效果预览:

基于高德地图实现融云位置共享功能_第1张图片
基于高德地图实现融云位置共享功能_第2张图片
基于高德地图实现融云位置共享功能_第3张图片

开发准备:

1: 登录 融云开发者账号,提交 server 平台工单申请开通 实时位置共享功能。工单回复开通成功后、 2 小时生效。

2: 注册高德地图账号、申请成为开发者。获取高德地图相关 key 和 jar 包

这里写图片描述

3: Android 工程当中配置自己获取的 高德地图的 key.
这里写图片描述
注: 此处需要配置自己的 高德地图 key

code:

核心类: RealTimeLocationInputProvider
RealTimeLocationMessageProvider
LocationMapActivity
RealTimeLocationActivity
BasicMapActivity 抽象类

RealTimeLocationActivity 继承自 LocationMapActivity 继承自
BasicMapActivity

此类代码可以在 demo 的 message provider 包下 copy 到
需要注意的是 RealTimeLocationInputProvider, 继承自 LocationInputProvider(此类功用是发送当前位置的静态图给对方)。
如果你没有开通 位置共享功能 的服务 他就通不过第一个 if 判断

RealTimeLocationConstant.RealTimeLocationErrorCode errorCode = RongIMClient.getInstance().getRealTimeLocation(getCurrentConversation().getConversationType(), getCurrentConversation().getTargetId());

        if (errorCode != null && errorCode != RealTimeLocationConstant.RealTimeLocationErrorCode.RC_REAL_TIME_LOCATION_CONVERSATION_NOT_SUPPORT) {//服务端未开通

然后他就会去调用父类的发送位置的方法 ,也就是 LocationInputProvider 。需要注意会话类型,位置共享目前只支持单聊 和 讨论组的会话类型

核心接口:
RongIMClient.RealTimeLocationListener
目前 demo 是在 ConversationActivity 类中实现这个接口

 public interface RealTimeLocationListener {
        void onStatusChange(RealTimeLocationStatus status);

        void onReceiveLocation(double latitude, double longitude, String userId);

        void onParticipantsJoin(String userId);

        void onParticipantsQuit(String userId);

        void onError(RealTimeLocationErrorCode errorCode);
    }

RealTimeLocationActivity 中的

private void addUserInfoToScrollView(final String userId) {


        DemoContext.getInstance().getDemoApi().getUserInfo(userId, new DemoApi.GetUserInfoListener() {

            @Override
            public void onSuccess(final UserInfo userInfo) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        horizontalScrollView.addUserToView(userInfo);
                        setParticipantTextView(-1);
                    }
                });

            }

            @Override
            public void onError(String userId, BaseException e) {

            }
        });
    }

   public void onEventMainThread(final RongEvent.RealTimeLocationReceiveEvent event) {
        String userId = event.getUserId();

        DemoContext.getInstance().getDemoApi().getUserInfo(userId, new DemoApi.GetUserInfoListener() {

            @Override
            public void onSuccess(final UserInfo userInfo) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        moveMarker(new LatLng(event.getLatitude(), event.getLongitude()), userInfo);
                    }
                });
            }

            @Override
            public void onError(String userId, BaseException e) {

            }
        });
    }

请求获取用户信息部分 需要换成自己的 网络请求 或者 缓存信息

经纬度的获取:

LocationMapActivity 中

@Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (amapLocation != null && amapLocation.getAMapException().getErrorCode() == 0) {
            //获取位置信息
            Double geoLat = amapLocation.getLatitude();
            Double geoLng = amapLocation.getLongitude();

            RongIMClient.getInstance().updateRealTimeLocationStatus(conversationType, targetId, geoLat, geoLng);
        }
    }

如果进入界面 一直定位在北京中心 你当在此处监听你的经纬度有没有成功获取到,如果经纬度没有获取到可能是因为高德地图的 appkey 或者 keystore 没有配置 (keystore 很重要 与 高德 appkey 必须是对应的 否则无法获取到 经纬度)

key 的配置: key 的值 从高德地图获取 此处只是 demo 的示例
基于高德地图实现融云位置共享功能_第4张图片

Use:

使用在会话界面 + 号扩展功能中使用:

 InputProvider.ExtendProvider[] singleProvider = {
                new ImageInputProvider(RongContext.getInstance()),
                new CameraInputProvider(RongContext.getInstance()),//相机
                new RealTimeLocationInputProvider(RongContext.getInstance()),//带位置共享的地理位置
//                new VoIPInputProvider(RongContext.getInstance()),// 语音通话
        };

        InputProvider.ExtendProvider[] muiltiProvider = {
                new ImageInputProvider(RongContext.getInstance()),
                new CameraInputProvider(RongContext.getInstance()),//相机
                new LocationInputProvider(RongContext.getInstance()),//地理位置
        };

        RongIM.getInstance().resetInputExtensionProvider(Conversation.ConversationType.PRIVATE, singleProvider);
        RongIM.getInstance().resetInputExtensionProvider(Conversation.ConversationType.DISCUSSION, muiltiProvider);
        RongIM.getInstance().resetInputExtensionProvider(Conversation.ConversationType.CUSTOMER_SERVICE, muiltiProvider);
        RongIM.getInstance().resetInputExtensionProvider(Conversation.ConversationType.GROUP, muiltiProvider);

基于高德地图实现融云位置共享功能_第5张图片

至此 Android Kit 位置共享集成实现完毕

Lib 使用:

kit 开发者无需参考下面文章

如果 lib sdk 开发者也需要使用位置共享,需要自己来实现所有的 UI 界面。lib 提供了 相关的位置共享的实现接口如下


    /** * 获取 RealTimeLocation 实例,每发起一次位置共享业务,就要获取一个实例。 * 如果获取实例失败,返回 error code,对应具体的失败信息。 * 使用时,每次进入会话,获取该会话对应的实例,以此判断位置共享业务是否可用或者正在进行中。 * 如果返回成功,使用者可以设置监听,发起位置共享。 * 如果返回正在进行中,则是对方已发起位置共享,使用者可以设置监听,加入。 * 如果返回其他失败信息,使用者可以据此做出相应的提示。 * * @param conversationType 发起位置共享的所在会话的会话类型。 * @param targetId 发起位置共享的 target id。 * @return 是否获取实例成功。 */
    public RealTimeLocationErrorCode getRealTimeLocation(Conversation.ConversationType conversationType, String targetId) {
        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (mLibHandler == null) {
            return RealTimeLocationErrorCode.RC_REAL_TIME_LOCATION_NOT_INIT;
        }

        if (conversationType == null || targetId == null) {
            RLog.e(this, "getRealTimeLocation", "Type or id is null!");
            return null;
        }

        int code = -1;
        try {
            code = mLibHandler.setupRealTimeLocation(conversationType.getValue(), targetId);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return RealTimeLocationErrorCode.valueOf(code);
    }

    /** * 发起位置共享。 * * @param conversationType 发起位置共享的会话类型。 * @param targetId 发起位置共享的 targetId。 */
    public RealTimeLocationErrorCode startRealTimeLocation(final Conversation.ConversationType conversationType, final String targetId) {
        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (mLibHandler == null) {
            return RealTimeLocationErrorCode.RC_REAL_TIME_LOCATION_NOT_INIT;
        }

        if (conversationType == null || targetId == null) {
            RLog.e(this, "startRealTimeLocation", "Type or id is null!");
            return null;
        }

        int code = -1;
        try {
            code = mLibHandler.startRealTimeLocation(conversationType.getValue(), targetId);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return RealTimeLocationErrorCode.valueOf(code);
    }

    /** * 加入位置共享。 * * @param conversationType 位置共享的会话类型。 * @param targetId 位置共享的 targetId。 */
    public RealTimeLocationErrorCode joinRealTimeLocation(final Conversation.ConversationType conversationType, final String targetId) {
        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (mLibHandler == null) {
            return RealTimeLocationErrorCode.RC_REAL_TIME_LOCATION_NOT_INIT;
        }

        if (conversationType == null || targetId == null) {
            RLog.e(this, "joinRealTimeLocation", "Type or id is null!");
            return null;
        }

        int code = -1;
        try {
            code = mLibHandler.joinRealTimeLocation(conversationType.getValue(), targetId);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return RealTimeLocationErrorCode.valueOf(code);
    }

    /** * 退出位置共享。 * * @param conversationType 位置共享的会话类型。 * @param targetId 位置共享的 targetId。 */
    public void quitRealTimeLocation(final Conversation.ConversationType conversationType, final String targetId) {
        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (conversationType == null || targetId == null) {
            RLog.e(this, "quitRealTimeLocation", "Type or id is null!");
            return;
        }

        mWorkHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mLibHandler == null) {
                    return;
                }
                try {
                    mLibHandler.quitRealTimeLocation(conversationType.getValue(), targetId);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /** * 获取参与该位置共享的所有成员。 * * @param conversationType 位置共享的会话类型。 * @param targetId 位置共享的 targetId。 * @return 参与成员 id 列表。 */
    public List<String> getRealTimeLocationParticipants(Conversation.ConversationType conversationType, String targetId) {
        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (mLibHandler == null) {
            return null;
        }

        if (conversationType == null || targetId == null) {
            RLog.e(this, "getRealTimeLocationParticipants", "Type or id is null!");
            return null;
        }

        List<String> list = null;
        try {
            list = mLibHandler.getRealTimeLocationParticipants(conversationType.getValue(), targetId);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return list;
    }


    /** * 获取位置共享状态。 * * @param conversationType 位置共享的会话类型。 * @param targetId 位置共享的 targetId。 * @return 正在进行的位置共享状态。 */
    public RealTimeLocationStatus getRealTimeLocationCurrentState(Conversation.ConversationType conversationType, String targetId) {
        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (mLibHandler == null) {
            return null;
        }

        if (conversationType == null || targetId == null) {
            RLog.e(this, "getRealTimeLocationCurrentState", "Type or id is null!");
            return null;
        }

        int state = 0;
        try {
            state = mLibHandler.getRealTimeLocationCurrentState(conversationType.getValue(), targetId);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        return RealTimeLocationStatus.valueOf(state);
    }

    /** * 添加位置共享观察者。 * * @param conversationType 位置共享的会话类型。 * @param targetId 位置共享的 targetId。 * @param listener 位置共享监听。 */
    public void addRealTimeLocationListener(final Conversation.ConversationType conversationType, final String targetId, final RealTimeLocationListener listener) {

        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        if (conversationType == null || targetId == null) {
            RLog.e(this, "addRealTimeLocationListener", "Type or id is null!");
            return;
        }

        mWorkHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mLibHandler == null) {
                    return;
                }
                try {
                    mLibHandler.addRealTimeLocationListener(conversationType.getValue(), targetId, new IRealTimeLocationListener.Stub() {
                        @Override
                        public void onStatusChange(final int status) {
                            if (listener != null) {
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        listener.onStatusChange(RealTimeLocationStatus.valueOf(status));
                                    }
                                });
                            }
                        }

                        @Override
                        public void onReceiveLocation(final double latitude, final double longitude, final String userId) {
                            if (listener != null) {
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        listener.onReceiveLocation(latitude, longitude, userId);
                                    }
                                });
                            }
                        }

                        @Override
                        public void onParticipantsJoin(final String userId) {
                            if (listener != null) {
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        listener.onParticipantsJoin(userId);
                                    }
                                });
                            }
                        }

                        @Override
                        public void onParticipantsQuit(final String userId) {
                            if (listener != null) {
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        listener.onParticipantsQuit(userId);
                                    }
                                });
                            }
                        }

                        @Override
                        public void onError(final int errorCode) {
                            if (listener != null) {
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        listener.onError(RealTimeLocationErrorCode.valueOf(errorCode));
                                    }
                                });
                            }
                        }
                    });
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /** * 使用者调用此方法更新坐标位置。 * * @param conversationType 位置共享的会话类型。 * @param targetId 位置共享的会话 targetId。 * @param latitude 维度 * @param longitude 经度 */
    public void updateRealTimeLocationStatus(Conversation.ConversationType conversationType,
                                             String targetId,
                                             double latitude,
                                             double longitude) {

        if (sS == null)
            throw new RuntimeException("RongIMClient 尚未初始化!");

        RLog.d(this, "updateRealTimeLocationStatus", "latitude=" + latitude);
        if (conversationType == null || targetId == null) {
            RLog.e(this, "updateRealTimeLocationStatus", "Type or id is null!");
            return;
        }

        if (mLibHandler != null) {
            try {
                mLibHandler.updateRealTimeLocationStatus(conversationType.getValue(), targetId, latitude, longitude);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /** * 实时位置共享监听。 */
    public interface RealTimeLocationListener {
        /** * 位置共享状态发生改变。 * * @param status 空闲、加入、退出、建立连接等状态 */
        void onStatusChange(RealTimeLocationStatus status);

        /** * 接收到位置共享信息。 * * @param latitude 维度 * @param longitude 经度 * @param userId 发送者 id */
        void onReceiveLocation(double latitude, double longitude, String userId);

        /** * 对方加入位置共享。 * * @param userId 加入者 id */
        void onParticipantsJoin(String userId);

        /** * 对方退出位置共享 * * @param userId 退出者 id */
        void onParticipantsQuit(String userId);

        /** * 位置共享过程出现错误。 * * @param errorCode 错误码 */
        void onError(RealTimeLocationErrorCode errorCode);
    }

接口的使用方式可以参考 上述文档注释 和 demo 中 kit 层如何调用 lib 层这几个接口

你可能感兴趣的:(android,IM,高德地图,融云)