Androidアプリ開発

【Android】ChatMessageViewというライブラリを使った Firestoreチャットページ作成

前回のSwiftで作ったチャットページのAndroid版。

public class MessengerActivity extends AppCompatActivity {

    private Activity activity = this;
    private ChatView mChatView;
    private FirebaseFirestore db;
    private String collectionName;
    private String myId;
    private Bitmap myIcon;
    private String myName;
    private User me;
    private String inputText;
    private int chatCnt = 50;
    private final int REQUEST_CODE = 777;
    private Set blockUser = new HashSet();
    private Toolbar toolbar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);
        // チャットネーム初期処理
        this.initChatName();
        // ブロックユーザー情報読み込み
        this.blockUser = PrefUtility.readBlockUserNames(getApplicationContext());
        // Firebase初期設定
        this.setupFirebase();
        // ユーザー情報初期処理
        this.initChatSetting();
        // チャットページ作成
        this.initView();
        // ツールバー設定
        this.initToolbar();
    }

    /**
     * チャットネームを確認し未登録なら登録画面へ
     */
    private void initChatName() {
        // チャットネーム取得
        this.myName= PrefUtility.getPrefChatName(this);
        // 未登録なら登録画面へ
        if(Utility.isNull(this.myName)){
            startActivityForResult(new Intent(activity, ChatNameSetting.class), REQUEST_CODE);
        }
    }

    private void setupFirebase() {

        this.db = FirebaseFirestore.getInstance();

        this.collectionName = PrefUtility.getLangSetting(getApplicationContext()).equals("ja") ?
                getString(R.string.collection_name) : getString(R.string.collection_name_en);

        // DBが変更されるとリスト更新
        this.db.collection(this.collectionName).orderBy("timestamp", Query.Direction.DESCENDING).limit(this.chatCnt)
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(QuerySnapshot snapshot, FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.w("chat", "Listen failed.", e);
                            return;
                        }

                        for (DocumentChange dc : snapshot.getDocumentChanges()) {
                            // ブロックユーザーチェック
                            String name = dc.getDocument().getString("name");
                            if(blockUser.contains(name)){
                                continue;
                            }
                            switch (dc.getType()) {
                                case ADDED:
                                    User u = new User(UUID.randomUUID().toString(), name, null);
                                    if(name.equals(myName)){
                                        // 自分のチャット
                                        Message m = setUpMineMsg(u, dc.getDocument());
                                        mChatView.receive(m);
                                    } else {
                                        // 他人のチャット
                                        Message m = setUpYourMsg(u, dc.getDocument());
                                        mChatView.receive(m);
                                    }
                                    break;
                                case MODIFIED:
                                    Log.d("chat", "Modified city: " + dc.getDocument().getData());
                                    break;
                                case REMOVED:
                                    Log.d("chat", "Removed city: " + dc.getDocument().getData());
                                    break;
                            }
                        }
                    }
                });
    }

    private void initChatSetting() {
        this.myId = Utility.getUUID(this);
        this.myIcon = null;
        this.me = new User(myId, myName, myIcon);
    }

    private void initView() {

        mChatView = findViewById(R.id.chat_view);

        // Optionボタン非表示
        mChatView.findViewById(R.id.optionButton).setVisibility(View.GONE);

        //Set UI parameters if you need
        mChatView.setRightBubbleColor(ContextCompat.getColor(this, R.color.bubble_color));
        mChatView.setLeftBubbleColor(ContextCompat.getColor(this, R.color.bubble_color));
        mChatView.setBackgroundColor(ContextCompat.getColor(this, R.color.white));
        mChatView.setSendButtonColor(ContextCompat.getColor(this, R.color.bubble_color));
        mChatView.setSendIcon(R.drawable.ic_action_send);
        mChatView.setRightMessageTextColor(Color.WHITE);
        mChatView.setLeftMessageTextColor(Color.WHITE);
        mChatView.setUsernameTextColor(Color.BLACK);
        mChatView.setSendTimeTextColor(Color.BLACK);
        mChatView.setDateSeparatorColor(Color.BLACK);
        mChatView.setOptionButtonColor(ContextCompat.getColor(this, R.color.bubble_color));
        mChatView.setInputTextHint("new message...");
        mChatView.setMessageMarginTop(5);
        mChatView.setMessageMarginBottom(5);
        mChatView.setMessageFontSize(40);
        mChatView.setUsernameFontSize(38);
        mChatView.setTimeLabelFontSize(35);
        mChatView.setDateSeparatorFontSize(35);

        //Click Send Button
        mChatView.setOnClickSendButtonListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 入力メッセージを保持
                inputText = mChatView.getInputText();
                if(inputText.length() != 0){
                    //Reset edit text
                    mChatView.setInputText("");
                    // Firestoreへ保存
                    saveData();
                }
            }
        });
    }

    private void saveData() {

        // Create a new user with a first and last name
        Map<String, Object> user = new HashMap<>();

        user.put("name", this.myName);
        user.put("text", this.inputText);
        user.put("timestamp", new Date());

        // Add a new document with a generated ID
        this.db.collection(collectionName)
                .add(user)
                .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                    @Override
                    public void onSuccess(DocumentReference documentReference) {
                        Log.d("chat","DocumentSnapshot added with ID: " + documentReference.getId());
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.w("chat", "Error adding document", e);
                    }
                });
    }

    private Message setUpMineMsg(User u, QueryDocumentSnapshot q) {
        Message message = new Message.Builder()
                .setUser(u)
                .setRight(true)
                .setText(q.getString("text"))
                .setSendTime(this.getCalendar(q.getDate("timestamp")))
                .hideIcon(true)
                .build();
        return message;
    }

    private Message setUpYourMsg(User u, QueryDocumentSnapshot q) {
        Message message = new Message.Builder()
                .setUser(u)
                .setRight(false)
                .setText(q.getString("text"))
                .setSendTime(this.getCalendar(q.getDate("timestamp")))
                .hideIcon(true)
                .build();
        return message;
    }

    private Calendar getCalendar(Date d) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        return cal;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(!Utility.isNull(data)){
            Bundle bundle = data.getExtras();
            switch (requestCode) {
                case (REQUEST_CODE):
                    if (resultCode == RESULT_OK) {
                        // 起動先Activityからチャットネームを取得
                        this.myName = bundle.getString("key.ChatName");
                    }
                    break;
                default:
                    break;
            }
        } else {
            // 未登録の場合、戻る
            finish();
        }
    }

    @SuppressLint("ResourceAsColor")
    private void initToolbar() {
        toolbar = findViewById(R.id.toolBar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        toolbar.setTitle(getString(R.string.tab_name_chat));
        toolbar.setTitleTextColor(R.color.black);
    }
}

 

ライブラリ探しに時間が掛かったが、ChatMessageViewを使ってみた。

最新バージョンはなぜかビルド通らないので、v1.11.0を使用。

実装は前回のSwiftチャットページよりあっさりできた。

 

参考サイト

Android のチャットUIライブラリを作ってみた

Firebase ドキュメント