这是本文档旧的修订版!


环信红包接入文档


新开商户可免费发送累计5000元总额的红包,超过5000元后,红包功能自动关闭,直到商户付费购买增值服务“红包功能”后,该功能重新开启,购买增值服务请咨询环信商务经理。

集成概述
  • 红包SDK分为两个版本,即钱包版红包SDK与支付宝版红包SDK。
  • 使用钱包版红包SDK的用户,可以使用银行卡支付或支付宝支付等第三方支付来发红包;收到的红包金额会进入到钱包余额,并支持提现到绑定的银行卡。
  • 使用支付宝版红包SDK的用户,发红包仅支持支付宝支付;收到的红包金额即时入账至绑定的支付宝账号。
  • 请选择希望接入的版本并下载对应的SDK进行集成,钱包版红包SDK与支付宝版红包SDK集成方式相同。
  • 需要注意的是如果已经集成了钱包版红包SDK,暂不支持切换到支付宝版红包SDK(两个版本不支持互通)。
  • 环信Demo中使用redPacketlibrary模块集成了红包SDK相关红能。
redPacketlibrary介绍
  • redPacketlibrary是在环信Demo中集成红包功能的模块,开发者可参考该模块中的方法集成红包功能。建议开发者以模块的形式集成红包功能,便于项目的更新和维护。
  • libs :包含了集成红包功能所依赖的jar包。(红包使用了glide库做图片加载,由于已经依赖了easeui这里不重复添加)
  • res :包含了聊天页面中的资源文件(例如红包消息卡片,回执消息的UI等)。
  • utils包 : 封装了收、发红包的相关方法。
  • widget包:聊天界面中的红包消息、红包回执消息的ChatRow。(开发者可自定义红包消息及回执消息的UI)

注意: RedPacketUtil类中使用了环信SDK中相关方法,以及红包chatrow继承自EaseChatRow,redpacketlibrary依赖了easeui,如不使用上诉相关代码可不依赖easeui。

* 以支付宝版红包SDK为例,修改com.hyphenate.redpacket:redpacket-alipay:1.1.2中的1.1.2为已发布的更高版本(例如1.1.3),同步之后即可完成红包SDK的更新。

1.添加对红包工程的依赖

  • ChatDemo的build.gradle中
//添加远程仓库地址
    allprojects {
        repositories {
            jcenter()
            maven {  url "https://raw.githubusercontent.com/HyphenateInc/Hyphenate-SDK-Android/master/repository" }
        }
    }

     dependencies {
        compile project(':redpacketlibrary')
        compile project(':EaseUI')
        compile fileTree(dir: 'libs', include: '*.jar', exclude: 'android-support-multidex.jar')
     }
 
  • ChatDemo的setting.gradle中
include ':EaseUI', ':redpacketlibrary'

2.ChatDemo清单文件中注册红包相关组件

<uses-sdk
            android:minSdkVersion="9"
            android:targetSdkVersion="19"
            tools:overrideLibrary="com.easemob.redpacketui"
        />
        
    <!--支付宝版 start-->

<!--发红包页面-->
<activity
   android:name="com.easemob.redpacketui.ui.activity.RPRedPacketActivity"
   android:screenOrientation="portrait"
   android:windowSoftInputMode="adjustPan|stateVisible"/>
<!--红包详情页面-->
<activity
   android:name="com.easemob.redpacketui.ui.activity.RPDetailActivity"
   android:screenOrientation="portrait"
   android:windowSoftInputMode="adjustPan"/>
<!--红包记录页面-->
<activity
   android:name="com.easemob.redpacketui.ui.activity.RPRecordActivity"
   android:screenOrientation="portrait"
   android:windowSoftInputMode="adjustPan"/>
<!--群成员列表页面-->
<activity
   android:name="com.easemob.redpacketui.ui.activity.RPGroupMemberActivity"
   android:screenOrientation="portrait"
   android:windowSoftInputMode="adjustPan|stateHidden"/>
<!--支付宝H5支付页面-->
<activity
   android:name="com.alipay.sdk.app.H5PayActivity"
   android:configChanges="orientation|keyboardHidden|navigation|screenSize"
   android:exported="false"
   android:screenOrientation="behind"
   android:windowSoftInputMode="adjustResize|stateHidden" />
<!--支付宝H5授权页面-->
<activity
   android:name="com.alipay.sdk.app.H5AuthActivity"
   android:configChanges="orientation|keyboardHidden|navigation|screenSize"
   android:exported="false"
   android:screenOrientation="behind"
   android:windowSoftInputMode="adjustResize|stateHidden"/>

<!--支付宝版 end-->

<!--钱包版需在此基础上额外添加以下activity的声明-->

<!--WebView相关页面-->  
<activity
  android:name="com.easemob.redpacketui.ui.activity.RPWebViewActivity"
  android:screenOrientation="portrait"
  android:windowSoftInputMode="adjustResize|stateHidden" />
<!--零钱页面-->    
<activity
  android:name="com.easemob.redpacketui.ui.activity.RPChangeActivity"
  android:configChanges="orientation|keyboardHidden|screenSize"
  android:screenOrientation="portrait"
  android:windowSoftInputMode="adjustResize|stateHidden" />
<!--银行卡页面-->    
<activity
  android:name="com.easemob.redpacketui.ui.activity.RPBankCardActivity"
  android:screenOrientation="portrait"
  android:windowSoftInputMode="adjustPan|stateHidden" />
<!--转账页面-->  
<activity
  android:name="com.easemob.redpacketui.ui.activity.RPTransferActivity"
  android:screenOrientation="portrait"
  android:windowSoftInputMode="adjustPan|stateVisible"/>
<!--转账详情页面-->          
<activity
  android:name="com.easemob.redpacketui.ui.activity.RPTransferDetailActivity"
  android:screenOrientation="portrait"
  android:windowSoftInputMode="adjustPan|stateHidden"/>

<!-- 配置权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 钱包版需额外添加如下权限,支付宝版不需要该权限 -->
<uses-permission android:name="android.permission.CAMERA"/>  
 

3.DemoApplication初始化红包上下文

@Override
public void onCreate() {
    super.onCreate();
    //初始化红包SDK,开启日志输出开关
    RedPacket.getInstance().initRedPacket(applicationContext, RPConstant.AUTH_METHOD_EASEMOB, new RPInitRedPacketCallback() {
        @Override
	    public void initTokenData(RPValueCallback<TokenData> callback) {
		    TokenData tokenData = new TokenData();
		    tokenData.imUserId = EMClient.getInstance().getCurrentUser();
			//此处使用环信id代替了appUserId 开发者可传入App的appUserId
			tokenData.appUserId = EMClient.getInstance().getCurrentUser();
			tokenData.imToken = EMClient.getInstance().getAccessToken();
			//同步或异步获取TokenData 获取成功后回调onSuccess()方法
			callback.onSuccess(tokenData);
		}
		@Override
		public RedPacketInfo initCurrentUserSync() {
			//这里需要同步设置当前用户id、昵称和头像url
			String fromAvatarUrl = "";
			String fromNickname = EMClient.getInstance().getCurrentUser();
			EaseUser easeUser = EaseUserUtils.getUserInfo(fromNickname);
			if (easeUser != null) {
				fromAvatarUrl = TextUtils.isEmpty(easeUser.getAvatar()) ? "none" : easeUser.getAvatar();
				fromNickname = TextUtils.isEmpty(easeUser.getNick()) ? easeUser.getUsername() : easeUser.getNick();
			}
			RedPacketInfo redPacketInfo = new RedPacketInfo();
			redPacketInfo.fromUserId = EMClient.getInstance().getCurrentUser();
			redPacketInfo.fromAvatarUrl = fromAvatarUrl;
			redPacketInfo.fromNickName = fromNickname;
			return redPacketInfo;
		}
	});
    //打开Log开关 正式发布时请关闭
    RedPacket.getInstance().setDebugMode(true);
}
    

4. 发红包

进入发红包页面

@Override
public boolean onExtendMenuItemClick(int itemId, View view) {
        switch (itemId) {
        ...
        case ITEM_RED_PACKET://进入红包页面
            //注意:不再支持原有的startActivityForResult进入红包相关页面
            int itemType;
            if (chatType == EaseConstant.CHATTYPE_SINGLE) {
                itemType = RPConstant.RP_ITEM_TYPE_SINGLE;
                //小额随机红包
                //itemType = RPConstant.RP_ITEM_TYPE_RANDOM;
            } else {
                itemType = RPConstant.RP_ITEM_TYPE_GROUP;
            }
            RedPacketUtil.startRedPacket(getActivity(), itemType, toChatUsername, new RPSendPacketCallback() {
               @Override
                public void onGenerateRedPacketId(String redPacketId) {

                }
                @Override
                public void onSendPacketSuccess(RedPacketInfo redPacketInfo) {
                    //发送红包消息到聊天页面
                    sendMessage(RedPacketUtil.createRPMessage(getActivity(), redPacketInfo, toChatUsername));
                }
            });
            break;
        }
        //不覆盖已有的点击事件
        return false;
}        

进入转账页面(仅支持钱包版)

RedPacketUtil.startRedPacket(getActivity(), RPConstant.RP_ITEM_TYPE_TRANSFER, toChatUsername, new RPSendPacketCallback() {
                @Override
                public void onGenerateRedPacketId(String redPacketId) {

                }
                @Override
                public void onSendPacketSuccess(RedPacketInfo redPacketInfo) {
                    sendMessage(RedPacketUtil.createTRMessage(getActivity(), redPacketInfo, toChatUsername));
                }
});

5.拆红包

拆单聊、群聊、小额随机红包的方法

调用示例

@Override
public boolean onMessageBubbleClick(EMMessage message) {
   //消息框点击事件,demo这里不做覆盖,如需覆盖,return true
   if (message.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_MESSAGE, false)){
        RedPacketUtil.openRedPacket(getActivity(), chatType, message, toChatUsername, messageList);
       return true;
   }
   return false;
}

拆转账红包方法(仅支持钱包版)

'RPRedPacketUtil.getInstance().openTransferPacket(context, redPacketInfo)'

redPacketInfo传入参数

  • redPacketAmount 转账金额
  • transferTime 转账时间
  • messageDirect 消息的方向

调用示例

RPRedPacketUtil.getInstance().openTransferPacket(context, redPacketInfo)

6.群红包领取回执消息的处理

ChatFragment中的处理

@Override
public void onCmdMessageReceived(List<EMMessage> messages) {
    for (EMMessage message : messages) {
        EMCmdMessageBody cmdMsgBody = (EMCmdMessageBody) message.getBody();
        String action = cmdMsgBody.action();//获取自定义action
        if (action.equals(RPConstant.REFRESH_GROUP_RED_PACKET_ACTION)){
            RedPacketUtils.receiveRedPacketAckMessage(message);
            messageList.refresh();
        }
    }
    super.onCmdMessageReceived(messages);
}

MainActivity中的处理

@Override
public void onCmdMessageReceived(List<EMMessage> messages) {
    for (EMMessage message : messages) {
        EMCmdMessageBody cmdMsgBody = (EMCmdMessageBody) message.getBody();
        String action = cmdMsgBody.action();//获取自定义action
        if (action.equals(RPConstant.REFRESH_GROUP_RED_PACKET_ACTION) ){
            RedPacketUtils.receiveRedPacketAckMessage(message);
        }
    }
    refreshUIWithMessage();
}

全局处理

* DemoHelper中

@Override
public void onCmdMessageReceived(List<EMMessage> messages) {
    for (EMMessage message : messages) {
        //获取消息body
        EMCmdMessageBody cmdMsgBody = (EMCmdMessageBody) message.getBody();
        final String action = cmdMsgBody.action();//获取自定义action
        if(!easeUI.hasForegroundActivies()){
            if (action.equals(RPConstant.REFRESH_GROUP_RED_PACKET_ACTION)){
                RedPacketUtils.receiveRedPacketAckMessage(message);
                broadcastManager.sendBroadcast(new Intent(RPConstant.REFRESH_GROUP_RED_PACKET_ACTION));
            }
        }
    }
}

* MainActivity中

private void registerBroadcastReceiver() {
    broadcastManager = LocalBroadcastManager.getInstance(this);
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(Constant.ACTION_CONTACT_CHANAGED);
    intentFilter.addAction(Constant.ACTION_GROUP_CHANAGED);
    intentFilter.addAction(RPConstant.REFRESH_GROUP_RED_PACKET_ACTION);
    broadcastReceiver = new BroadcastReceiver() {
     
        @Override
        public void onReceive(Context context, Intent intent) {
        ...
        if (action.equals(RPConstant.REFRESH_GROUP_RED_PACKET_ACTION)){
            if (conversationListFragment != null){
                conversationListFragment.refresh();
                }
            }
        }
    };
    broadcastManager.registerReceiver(broadcastReceiver, intentFilter);
}

* 会话列表中红包回执消息的处理

@Override
protected void setUpView() {
    super.setUpView();
    ...    
    //red packet code : 红包回执消息在会话列表最后一条消息的展示
    conversationListView.setConversationListHelper(new EaseConversationListHelper() {
        @Override
        public String onSetItemSecondaryText(EMMessage lastMessage) {
          if (lastMessage.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_ACK_MESSAGE, false)) {
                    String sendNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_SENDER_NAME, "");
                    String receiveNick = lastMessage.getStringAttribute(RPConstant.EXTRA_RED_PACKET_RECEIVER_NAME, "");
                    String msg;
                    if (lastMessage.direct() == EMMessage.Direct.RECEIVE) {
                        msg = String.format(getResources().getString(R.string.msg_someone_take_red_packet), receiveNick);
                    } else {
                        if (sendNick.equals(receiveNick)) {
                            msg = getResources().getString(R.string.msg_take_red_packet);
                        } else {
                            msg = String.format(getResources().getString(R.string.msg_take_someone_red_packet), sendNick);
                        }
                    }
                    return msg;
                }
                return null;
            }
        });
        super.setUpView();
        //end of red packet code
    }

7.屏蔽红包消息的转发和撤回功能

* ContextMenuActivity的onCreate方法

if (type == EMMessage.Type.TXT.ordinal()) {
    if(message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false) ||
       message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false) || 
       //屏蔽红包消息的转发功能
       message.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_MESSAGE, false)){
         setContentView(R.layout.em_context_menu_for_location);
    }
}
if (isChatroom
		 //屏蔽红包消息的撤回功能
		 || message.getBooleanAttribute(RPConstant.MESSAGE_ATTR_IS_RED_PACKET_MESSAGE, false)) {
			View v = (View) findViewById(R.id.forward);
	        if (v != null) {
	            v.setVisibility(View.GONE);
	        }
		}

8.进入零钱页方法(仅支持钱包版)

'RPRedPacketUtil.getInstance().startChangeActivity(context)'

* 获取零钱余额接口(仅支持钱包版)

RPRedPacketUtil.getInstance().getChangeBalance(new RPValueCallback<String>() {
        @Override
        public void onSuccess(String changeBalance) {

        }

        @Override
        public void onError(String errorCode, String errorMsg) {

        }
});

9.进入红包记录页面方法(仅支持支付宝版)

* RPRedPacketUtil.getInstance().startRecordActivity(context)

detachView接口

* RPRedPacketUtil.getInstance().detachView() * 在拆红包方法所在页面销毁时调用,可防止内存泄漏。 * 调用示例(以ChatFragment为例)

@Override
public void onDestroy() {
    super.onDestroy();
    RPRedPacketUtil.getInstance().detachView();
}

10.拆红包音效

* 在assets目录下添加open_packet_sound.mp3或者open_packet_sound.wav文件即可(文件大小不要超过1M)。