본문 바로가기
Android

아고라 플랫폼을 이용한 안드로이드 라이브스트리밍(RTSP) - 3

by 일용직 코딩노동자 2022. 5. 12.
728x90
반응형

이제 메인을 작성할게요.

 

우선 화면부터 간단하게 구성해보겠습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:layout_marginLeft="10dp"
        android:text="채널입력"
        android:textColor="#000000"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </TextView>

    <EditText
        android:id="@+id/channel"
        android:layout_width="wrap_content"
        android:layout_marginLeft="50dp"
        android:layout_height="50dp"
        android:textColor="#000000"
        android:hint="channel name"
        app:layout_constraintBottom_toBottomOf="@+id/textView"
        app:layout_constraintStart_toEndOf="@+id/textView"
        app:layout_constraintTop_toTopOf="@+id/textView">
    </EditText>

    <Button
        android:id="@+id/start"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:text="시작"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/nickName"></Button>

    <TextView
        android:id="@+id/textview2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="채팅 닉네임"
        android:textColor="#000000"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView"></TextView>

    <EditText
        android:id="@+id/nickName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="닉네임을 입력해주세요."
        app:layout_constraintBottom_toBottomOf="@+id/textview2"
        app:layout_constraintStart_toStartOf="@+id/channel"
        app:layout_constraintTop_toTopOf="@+id/textview2"></EditText>

</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends BaseActivity {

    private String[] PERMISSIONS = {
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    private Button start;
    private EditText channel;
    private EditText nickName;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        start = findViewById(R.id.start);
        channel = findViewById(R.id.channel);
        nickName = findViewById(R.id.nickName);

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(channel.getText().toString().length() > 0 && nickName.getText().toString().length() > 0){
                    String room = channel.getText().toString();
                    config().setChannelName(room); //아고라 엔진 초기화
                    config().setNicklName(nickName.getText().toString()); //채팅 닉네임 설정

                    Intent intent = new Intent(getApplicationContext(), RoleActivity.class); //방송자인지 시청자인지 구분하는 페이지로 이동
                    startActivity(intent);
                }
                else{
                    Toast.makeText(getApplicationContext(),"채널이름 또는 닉네임을 설정해주세요.",Toast.LENGTH_SHORT).show();
                }
            }
        });
        CheckPermission();
    }

    private void CheckPermission(){
        TedPermission.with(getApplicationContext())
        .setPermissions(PERMISSIONS)
        .setDeniedMessage("권한이 거부되었습니다.\n권한을 허용해주세요.")
        .setPermissionListener(new PermissionListener() {
            @Override
            public void onPermissionGranted() {
                // TODO 퍼미션이 정상적으로 승인 되어있을때 동작
            }

            @Override
            public void onPermissionDenied(List<String> deniedPermissions) {
                // TODO 퍼미션이 거부되었을때 동작
            }
        })
        .check();
    }
}

메인에서는 아고라 엔진의 초기화 작업과 퍼미션 처리를 해주는 역할만 해줍니다.

엔진 초기화 시 채팅 할때의 닉네임과 채널이름을 지정합니다.

 

그다음으로 넘어가기전에 채팅관련 셋팅 하고 가겠습니다.

 

public class ChatManager {
    private static final String TAG = ChatManager.class.getSimpleName();

    private Context mContext;
    private RtmClient mRtmClient;
    private SendMessageOptions mSendMsgOptions;
    private List<RtmClientListener> mListenerList = new ArrayList<>();
    private RtmMessagePool mMessagePool = new RtmMessagePool();

    public ChatManager(Context context) {
        mContext = context;
    }

    public void init() {
        try {
            mRtmClient = RtmClient.createInstance(mContext, "앱 아이디", new RtmClientListener() {
                @Override
                public void onConnectionStateChanged(int state, int reason) {
                    for (RtmClientListener listener : mListenerList) {
                        listener.onConnectionStateChanged(state, reason);
                    }
                }

                @Override
                public void onMessageReceived(RtmMessage rtmMessage, String peerId) {
                    if (mListenerList.isEmpty()) {
                        // If currently there is no callback to handle this
                        // message, this message is unread yet. Here we also
                        // take it as an offline message.
                        mMessagePool.insertOfflineMessage(rtmMessage, peerId);
                    } else {
                        for (RtmClientListener listener : mListenerList) {
                            listener.onMessageReceived(rtmMessage, peerId);
                        }
                    }
                }

                @Override
                public void onImageMessageReceivedFromPeer(final RtmImageMessage rtmImageMessage, final String peerId) {
                    if (mListenerList.isEmpty()) {
                        // If currently there is no callback to handle this
                        // message, this message is unread yet. Here we also
                        // take it as an offline message.
                        mMessagePool.insertOfflineMessage(rtmImageMessage, peerId);
                    } else {
                        for (RtmClientListener listener : mListenerList) {
                            listener.onImageMessageReceivedFromPeer(rtmImageMessage, peerId);
                        }
                    }
                }

                @Override
                public void onFileMessageReceivedFromPeer(RtmFileMessage rtmFileMessage, String s) {

                }

                @Override
                public void onMediaUploadingProgress(RtmMediaOperationProgress rtmMediaOperationProgress, long l) {

                }

                @Override
                public void onMediaDownloadingProgress(RtmMediaOperationProgress rtmMediaOperationProgress, long l) {

                }

                @Override
                public void onTokenExpired() {

                }

                @Override
                public void onPeersOnlineStatusChanged(Map<String, Integer> status) {

                }
            });

            if (BuildConfig.DEBUG) {
                mRtmClient.setParameters("{\"rtm.log_filter\": 65535}");
            }
        } catch (Exception e) {
            Log.e(TAG, Log.getStackTraceString(e));
            throw new RuntimeException("NEED TO check rtm sdk init fatal error\n" + Log.getStackTraceString(e));
        }

        // Global option, mainly used to determine whether
        // to support offline messages now.
        mSendMsgOptions = new SendMessageOptions();
    }

    public RtmClient getRtmClient() {
        return mRtmClient;
    }

    public void registerListener(RtmClientListener listener) {
        mListenerList.add(listener);
    }

    public void unregisterListener(RtmClientListener listener) {
        mListenerList.remove(listener);
    }

    public void enableOfflineMessage(boolean enabled) {
        mSendMsgOptions.enableOfflineMessaging = enabled;
    }

    public boolean isOfflineMessageEnabled() {
        return mSendMsgOptions.enableOfflineMessaging;
    }

    public SendMessageOptions getSendMessageOptions() {
        return mSendMsgOptions;
    }

    public List<RtmMessage> getAllOfflineMessages(String peerId) {
        return mMessagePool.getAllOfflineMessages(peerId);
    }

    public void removeAllOfflineMessages(String peerId) {
        mMessagePool.removeAllOfflineMessages(peerId);
    }
}

----------------------------------------------------------------------------------------------------------------------

 

public class MessageBean {
    private String account;
    private RtmMessage message;
    private String cacheFile;
    private int background;
    private boolean beSelf;

    public MessageBean(String account, RtmMessage message, boolean beSelf) {
        this.account = account;
        this.message = message;
        this.beSelf = beSelf;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public RtmMessage getMessage() {
        return message;
    }

    public void setMessage(RtmMessage message) {
        this.message = message;
    }

    public String getCacheFile() {
        return cacheFile;
    }

    public void setCacheFile(String cacheFile) {
        this.cacheFile = cacheFile;
    }

    public int getBackground() {
        return background;
    }

    public void setBackground(int background) {
        this.background = background;
    }

    public boolean isBeSelf() {
        return beSelf;
    }

    public void setBeSelf(boolean beSelf) {
        this.beSelf = beSelf;
    }
}

----------------------------------------------------------------------------------------------------------------------

public class MessageListBean {
    private String accountOther;
    private List<MessageBean> messageBeanList;

    public MessageListBean(String account, List<MessageBean> messageBeanList) {
        this.accountOther = account;
        this.messageBeanList = messageBeanList;
    }

    /**
     * Create message list bean from offline messages
     *
     * @param account     peer user id to find offline messages from
     * @param chatManager chat manager that managers offline message pool
     */
    public MessageListBean(String account, ChatManager chatManager) {
        accountOther = account;
        messageBeanList = new ArrayList<>();

        List<RtmMessage> messageList = chatManager.getAllOfflineMessages(account);
        for (RtmMessage m : messageList) {
            // All offline messages are from peer users
            MessageBean bean = new MessageBean(account, m, false);
            messageBeanList.add(bean);
        }
    }

    public String getAccountOther() {
        return accountOther;
    }

    public void setAccountOther(String accountOther) {
        this.accountOther = accountOther;
    }

    public List<MessageBean> getMessageBeanList() {
        return messageBeanList;
    }

    public void setMessageBeanList(List<MessageBean> messageBeanList) {
        this.messageBeanList = messageBeanList;
    }
}

----------------------------------------------------------------------------------------------------------------------

public class MessageUtil {
    public static final int MAX_INPUT_NAME_LENGTH = 64;

    public static final int ACTIVITY_RESULT_CONN_ABORTED = 1;

    public static final String INTENT_EXTRA_IS_PEER_MODE = "chatMode";
    public static final String INTENT_EXTRA_USER_ID = "userId";
    public static final String INTENT_EXTRA_TARGET_NAME = "targetName";

    public static Random RANDOM = new Random();

    public static final int[] COLOR_ARRAY = new int[]{
//            R.drawable.shape_circle_black,
//            R.drawable.shape_circle_blue,
//            R.drawable.shape_circle_pink,
//            R.drawable.shape_circle_pink_dark,
//            R.drawable.shape_circle_yellow,
//            R.drawable.shape_circle_red
    };

    private static List<MessageListBean> messageListBeanList = new ArrayList<>();

    public static void addMessageListBeanList(MessageListBean messageListBean) {
        messageListBeanList.add(messageListBean);
    }

    // clean up list on logout
    public static void cleanMessageListBeanList() {
        messageListBeanList.clear();
    }

    public static MessageListBean getExistMessageListBean(String accountOther) {
        int ret = existMessageListBean(accountOther);
        if (ret > -1) {
            return messageListBeanList.remove(ret);
        }
        return null;
    }

    // return existing list position
    private static int existMessageListBean(String userId) {
        int size = messageListBeanList.size();
        for (int i = 0; i < size; i++) {
            if (messageListBeanList.get(i).getAccountOther().equals(userId)) {
                return i;
            }
        }
        return -1;
    }

    public static void addMessageBean(String account, RtmMessage msg) {
        MessageBean messageBean = new MessageBean(account, msg, false);
        int ret = existMessageListBean(account);
        if (ret == -1) {
            // account not exist new messagelistbean
            messageBean.setBackground(MessageUtil.COLOR_ARRAY[RANDOM.nextInt(MessageUtil.COLOR_ARRAY.length)]);
            List<MessageBean> messageBeanList = new ArrayList<>();
            messageBeanList.add(messageBean);
            messageListBeanList.add(new MessageListBean(account, messageBeanList));

        } else {
            // account exist get messagelistbean
            MessageListBean bean = messageListBeanList.remove(ret);
            List<MessageBean> messageBeanList = bean.getMessageBeanList();
            if (messageBeanList.size() > 0) {
                messageBean.setBackground(messageBeanList.get(0).getBackground());
            } else {
                messageBean.setBackground(MessageUtil.COLOR_ARRAY[RANDOM.nextInt(MessageUtil.COLOR_ARRAY.length)]);
            }
            messageBeanList.add(messageBean);
            bean.setMessageBeanList(messageBeanList);
            messageListBeanList.add(bean);
        }
    }
}

----------------------------------------------------------------------------------------------------------------------

public class RtmMessagePool {
    private Map<String, List<RtmMessage>> mOfflineMessageMap = new HashMap<>();

    void insertOfflineMessage(RtmMessage rtmMessage, String peerId) {
        boolean contains = mOfflineMessageMap.containsKey(peerId);
        List<RtmMessage> list = contains ? mOfflineMessageMap.get(peerId) : new ArrayList<>();

        if (list != null) {
            list.add(rtmMessage);
        }

        if (!contains) {
            mOfflineMessageMap.put(peerId, list);
        }
    }

    List<RtmMessage> getAllOfflineMessages(String peerId) {
        return mOfflineMessageMap.containsKey(peerId) ?
                mOfflineMessageMap.get(peerId) : new ArrayList<>();
    }

    void removeAllOfflineMessages(String peerId) {
        mOfflineMessageMap.remove(peerId);
    }
}

----------------------------------------------------------------------------------------------------------------------

여기까지 라이브 채팅관련 기본 셋팅이였구요

메인 다음화면부터 다음 게시글로 보겠습니당

 

ㄱ ㅏ   ㄱ  푸시

ㅗ o    ㅗ  푸시 :D

728x90
반응형

댓글