From 48b30868f4f02aa6fe746b717d50fae2b97a3302 Mon Sep 17 00:00:00 2001 From: zlzw <583819556@qq.com> Date: Mon, 6 Nov 2023 18:24:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5ios=E6=8E=A5=E5=90=AC?= =?UTF-8?q?=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OneToOne/build.gradle | 3 +- .../activity/DiamondExchangeActivity.java | 11 +- .../activity/ExchangeRecordActivity.java | 2 +- .../message/ChatMessageFragment.java | 8 +- .../message/MessageInteractiveFragment.java | 2 +- .../fragments/message/MsgMessageFragment.java | 2 +- .../activity/message/CallAudioActivity.java | 6 +- .../activity/message/CallVideoActivity.java | 5 +- .../activity/message/ChatActivity.java | 5 + .../MsgMessageRecyclerViewAdapter.java | 3 + .../shayu/onetoone/bean/ExchangeModel.java | 11 + .../com/shayu/onetoone/dialog/GiftDialog.java | 5 +- .../com/shayu/onetoone/dialog/TipsDialog.java | 5 +- .../provider/CustomConversationProvider.java | 6 +- .../com/shayu/onetoone/utils/UserManager.java | 2 + .../onetoone/view/MsgInputPanelForGift.java | 5 +- .../res/layout/activity_diamond_exchange.xml | 1 + .../src/main/res/layout/activity_msg_chat.xml | 4 +- .../main/res/layout/fragment_interaction.xml | 2 +- .../src/main/res/layout/fragment_notice.xml | 2 +- .../src/main/res/values-zh-rHK/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + OneToOne/src/main/res/values/strings.xml | 1 + callkit/.gitignore | 1 + callkit/README.md | 43 + callkit/build.gradle | 26 + callkit/proguard-rules.pro | 17 + callkit/src/main/AndroidManifest.xml | 95 + .../java/io/rong/callkit/AudioPlugin.java | 201 ++ .../io/rong/callkit/BaseCallActivity.java | 862 ++++++++ .../rong/callkit/BaseNoActionBarActivity.java | 14 + .../callkit/CallEndMessageItemProvider.java | 248 +++ .../io/rong/callkit/CallFloatBoxView.java | 1216 +++++++++++ .../rong/callkit/CallForegroundService.java | 124 ++ .../java/io/rong/callkit/CallOptionMenu.java | 72 + .../io/rong/callkit/CallPromptDialog.java | 177 ++ .../callkit/CallSelectMemberActivity.java | 820 +++++++ .../io/rong/callkit/CallUserGridView.java | 264 +++ .../java/io/rong/callkit/ContainerLayout.java | 111 + .../rong/callkit/GlideCallKitImageEngine.java | 28 + .../rong/callkit/MultiAudioCallActivity.java | 989 +++++++++ .../callkit/MultiCallEndMessageProvider.java | 103 + .../rong/callkit/MultiVideoCallActivity.java | 1943 +++++++++++++++++ .../java/io/rong/callkit/PickupDetector.java | 62 + .../java/io/rong/callkit/RongCallAction.java | 25 + .../RongCallCustomerHandlerListener.java | 25 + .../java/io/rong/callkit/RongCallKit.java | 379 ++++ .../java/io/rong/callkit/RongCallModule.java | 485 ++++ .../java/io/rong/callkit/RongCallProxy.java | 422 ++++ .../rong/callkit/RongIncomingCallService.java | 317 +++ .../java/io/rong/callkit/RongVoIPIntent.java | 19 + .../io/rong/callkit/SingleCallActivity.java | 1336 ++++++++++++ .../java/io/rong/callkit/VideoPlugin.java | 189 ++ .../rong/callkit/VoIPBroadcastReceiver.java | 526 +++++ .../callkit/util/ActivityStartCheckUtils.java | 156 ++ .../io/rong/callkit/util/BluetoothUtil.java | 305 +++ .../io/rong/callkit/util/BlurBitmapUtil.java | 59 + .../util/CallKitSearchBarListener.java | 16 + .../callkit/util/CallKitSearchBarView.java | 153 ++ .../io/rong/callkit/util/CallKitUtils.java | 270 +++ .../io/rong/callkit/util/CallRingingUtil.java | 427 ++++ .../util/CallSelectMemberSerializable.java | 20 + .../callkit/util/CallVerticalScrollView.java | 259 +++ .../rong/callkit/util/DefaultPushConfig.java | 157 ++ .../rong/callkit/util/GlideBlurformation.java | 26 + .../callkit/util/GlideRoundTransform.java | 54 + .../java/io/rong/callkit/util/GlideUtils.java | 54 + .../io/rong/callkit/util/HeadsetInfo.java | 45 + .../io/rong/callkit/util/ICallScrollView.java | 35 + .../util/IncomingCallExtraHandleUtil.java | 54 + .../callkit/util/RTCPhoneStateReceiver.java | 76 + .../io/rong/callkit/util/RingingMode.java | 13 + .../callkit/util/RongCallPermissionUtil.java | 358 +++ .../java/io/rong/callkit/util/SPUtils.java | 175 ++ .../callkit/util/UserProfileOrderManager.java | 106 + .../util/permission/DeviceAdapter.java | 263 +++ .../rong/callkit/util/permission/OSUtils.java | 119 + .../util/permission/PermissionShowDetail.java | 58 + .../util/permission/PermissionType.java | 267 +++ .../callkit_ic_nav_back_x.png | Bin 0 -> 634 bytes .../drawable-xhdpi/callkit_ic_nav_back_x.png | Bin 0 -> 652 bytes .../res/drawable-xhdpi/callkit_ic_search.png | Bin 0 -> 1256 bytes .../callkit_ic_search_delete_x.png | Bin 0 -> 473 bytes .../callkit_ic_search_focused_x.png | Bin 0 -> 1354 bytes .../drawable-xhdpi/callkit_ic_search_x.png | Bin 0 -> 1256 bytes .../callkit_mult_video_user_clo_camera.png | Bin 0 -> 2579 bytes .../callkit_mult_video_user_mute.png | Bin 0 -> 2833 bytes .../callkit_mult_video_user_status.png | Bin 0 -> 886 bytes .../callkit_mute_unavailable.png | Bin 0 -> 5831 bytes .../callkit_select_ic_nav_back_x.png | Bin 0 -> 652 bytes .../res/drawable-xhdpi/rc_ic_phone_normal.png | Bin 0 -> 525 bytes .../drawable-xhdpi/rc_ic_phone_pressed.png | Bin 0 -> 4633 bytes .../main/res/drawable-xhdpi/rc_voip_add.png | Bin 0 -> 848 bytes .../drawable-xhdpi/rc_voip_audio_answer.png | Bin 0 -> 4161 bytes .../rc_voip_audio_answer_hover.png | Bin 0 -> 4184 bytes .../rc_voip_audio_left_cancel.png | Bin 0 -> 623 bytes .../rc_voip_audio_left_connected.png | Bin 0 -> 912 bytes .../rc_voip_audio_right_cancel.png | Bin 0 -> 679 bytes .../rc_voip_audio_right_connected.png | Bin 0 -> 982 bytes .../res/drawable-xhdpi/rc_voip_camera.png | Bin 0 -> 4710 bytes .../drawable-xhdpi/rc_voip_camera_hover.png | Bin 0 -> 3842 bytes .../drawable-xhdpi/rc_voip_disable_camera.png | Bin 0 -> 5043 bytes .../rc_voip_disable_camera_hover.png | Bin 0 -> 4609 bytes .../drawable-xhdpi/rc_voip_float_audio.png | Bin 0 -> 2393 bytes .../drawable-xhdpi/rc_voip_float_video.png | Bin 0 -> 1567 bytes .../res/drawable-xhdpi/rc_voip_handfree.png | Bin 0 -> 4543 bytes .../drawable-xhdpi/rc_voip_handfree_hover.png | Bin 0 -> 3995 bytes .../res/drawable-xhdpi/rc_voip_handup.png | Bin 0 -> 1035 bytes .../res/drawable-xhdpi/rc_voip_hang_up.png | Bin 0 -> 4194 bytes .../drawable-xhdpi/rc_voip_hang_up_hover.png | Bin 0 -> 4477 bytes .../res/drawable-xhdpi/rc_voip_icon_add.png | Bin 0 -> 1823 bytes .../drawable-xhdpi/rc_voip_icon_camera.png | Bin 0 -> 3171 bytes .../rc_voip_icon_checkbox_checked.png | Bin 0 -> 1172 bytes .../rc_voip_icon_checkbox_hover.png | Bin 0 -> 2090 bytes .../rc_voip_icon_checkbox_normal.png | Bin 0 -> 985 bytes .../rc_voip_icon_input_video.png | Bin 0 -> 540 bytes .../rc_voip_icon_input_video_pressed.png | Bin 0 -> 411 bytes .../res/drawable-xhdpi/rc_voip_iphone.png | Bin 0 -> 5483 bytes .../drawable-xhdpi/rc_voip_iphone_hover.png | Bin 0 -> 4022 bytes .../res/drawable-xhdpi/rc_voip_menu_bg.9.png | Bin 0 -> 1971 bytes .../res/drawable-xhdpi/rc_voip_minimize.png | Bin 0 -> 2773 bytes .../main/res/drawable-xhdpi/rc_voip_more.png | Bin 0 -> 939 bytes .../main/res/drawable-xhdpi/rc_voip_mute.png | Bin 0 -> 4913 bytes .../res/drawable-xhdpi/rc_voip_mute_hover.png | Bin 0 -> 4177 bytes .../rc_voip_notification_answer.png | Bin 0 -> 1633 bytes .../rc_voip_notification_hangup.png | Bin 0 -> 1577 bytes .../main/res/drawable-xhdpi/rc_voip_phone.png | Bin 0 -> 3060 bytes .../res/drawable-xhdpi/rc_voip_signal_1.png | Bin 0 -> 659 bytes .../res/drawable-xhdpi/rc_voip_signal_2.png | Bin 0 -> 731 bytes .../res/drawable-xhdpi/rc_voip_signal_3.png | Bin 0 -> 763 bytes .../res/drawable-xhdpi/rc_voip_signal_4.png | Bin 0 -> 737 bytes .../res/drawable-xhdpi/rc_voip_signal_5.png | Bin 0 -> 693 bytes .../res/drawable-xhdpi/rc_voip_signal_6.png | Bin 0 -> 598 bytes .../rc_voip_single_audio_answer.png | Bin 0 -> 4959 bytes .../rc_voip_single_audio_answer_hover.png | Bin 0 -> 4990 bytes .../drawable-xhdpi/rc_voip_switch_camera.png | Bin 0 -> 2778 bytes .../drawable-xhdpi/rc_voip_video_answer.png | Bin 0 -> 3491 bytes .../rc_voip_video_answer_hover.png | Bin 0 -> 3494 bytes .../rc_voip_video_answer_hover_new.png | Bin 0 -> 5111 bytes .../rc_voip_video_answer_new.png | Bin 0 -> 5071 bytes .../res/drawable-xhdpi/rc_voip_video_left.png | Bin 0 -> 573 bytes .../drawable-xhdpi/rc_voip_video_right.png | Bin 0 -> 624 bytes .../res/drawable-xhdpi/rc_voip_whiteboard.png | Bin 0 -> 534 bytes callkit/src/main/res/drawable/bg_search.xml | 11 + .../callkit_multiaudiouesrinfocontners.xml | 12 + .../drawable/callkit_selector_icon_search.xml | 5 + .../main/res/drawable/callkit_voip_iphone.xml | 5 + .../res/drawable/rc_ic_phone_selector.xml | 5 + .../res/drawable/rc_ic_video_selector.xml | 5 + .../rc_voip_audio_answer_selector.xml | 10 + .../rc_voip_audio_answer_selector_new.xml | 10 + .../res/drawable/rc_voip_camera_selector.xml | 5 + .../main/res/drawable/rc_voip_checkbox.xml | 5 + .../main/res/drawable/rc_voip_dialog_bg.xml | 5 + .../rc_voip_disable_camera_selector.xml | 5 + .../main/res/drawable/rc_voip_float_bg.xml | 12 + .../res/drawable/rc_voip_hangup_selector.xml | 10 + .../res/drawable/rc_voip_item_selector.xml | 5 + .../res/drawable/rc_voip_mute_selector.xml | 5 + .../res/drawable/rc_voip_speaker_selector.xml | 5 + .../rc_voip_vedio_answer_selector.xml | 10 + .../rc_voip_vedio_answer_selector_new.xml | 10 + .../layout/activity_call_select_member2.xml | 57 + .../callkit_actionbar_option_text_layout.xml | 79 + .../callkit_conference_search_top_layout.xml | 32 + .../callkit_multivideo_gaussianblur.xml | 14 + ...callkit_rc_voip_activity_select_member.xml | 84 + ..._rc_voip_activity_select_member_layout.xml | 91 + .../layout/callkit_view_search_bar_layout.xml | 53 + .../main/res/layout/rc_voip_ac_muti_audio.xml | 10 + .../layout/rc_voip_activity_select_member.xml | 59 + .../layout/rc_voip_activity_single_call.xml | 89 + .../layout/rc_voip_audio_call_user_info.xml | 104 + .../rc_voip_audio_call_user_info_incoming.xml | 79 + ...ip_call_bottom_connected_button_layout.xml | 107 + ...oip_call_bottom_incoming_button_layout.xml | 57 + .../rc_voip_call_user_info_incoming.xml | 56 + .../res/layout/rc_voip_contact_container.xml | 14 + .../layout/rc_voip_dialog_popup_prompt.xml | 86 + .../src/main/res/layout/rc_voip_float_box.xml | 26 + .../layout/rc_voip_item_incoming_maudio.xml | 87 + .../layout/rc_voip_item_outgoing_maudio.xml | 130 ++ .../layout/rc_voip_listitem_select_member.xml | 39 + .../res/layout/rc_voip_msg_multi_call_end.xml | 10 + .../res/layout/rc_voip_multi_video_call.xml | 164 ++ ...c_voip_multi_video_calling_bottom_view.xml | 109 + ...ip_multi_video_calling_bottom_view_rtl.xml | 109 + .../layout/rc_voip_multi_video_top_view.xml | 89 + .../main/res/layout/rc_voip_observer_hint.xml | 18 + .../src/main/res/layout/rc_voip_pop_menu.xml | 84 + .../src/main/res/layout/rc_voip_user_info.xml | 44 + .../layout/rc_voip_user_info_mutlaudio.xml | 51 + .../main/res/layout/rc_voip_user_portrait.xml | 14 + .../layout/rc_voip_video_call_user_info.xml | 51 + .../layout/rc_voip_viewlet_remote_user.xml | 55 + .../src/main/res/raw/voip_incoming_ring.mp3 | Bin 0 -> 432295 bytes .../main/res/raw/voip_network_error_sound.wav | Bin 0 -> 72082 bytes .../src/main/res/raw/voip_outgoing_ring.mp3 | Bin 0 -> 115547 bytes .../src/main/res/values-ar-rIL/strings.xml | 96 + callkit/src/main/res/values-en/colors.xml | 4 + callkit/src/main/res/values-en/dimens.xml | 8 + .../main/res/values-en/rc_voipkit_string.xml | 97 + .../values/callkit_callUserGridViewStyle.xml | 7 + callkit/src/main/res/values/colors.xml | 6 + callkit/src/main/res/values/dimens.xml | 16 + .../src/main/res/values/rc_voipkit_color.xml | 38 + .../src/main/res/values/rc_voipkit_ids.xml | 5 + .../src/main/res/values/rc_voipkit_string.xml | 97 + .../src/main/res/values/rc_voipkit_style.xml | 29 + callkit/src/main/res/values/strings.xml | 3 + .../common/activity/MyWalletActivity.java | 6 +- settings.gradle | 1 + 212 files changed, 17437 insertions(+), 24 deletions(-) create mode 100644 callkit/.gitignore create mode 100644 callkit/README.md create mode 100644 callkit/build.gradle create mode 100644 callkit/proguard-rules.pro create mode 100644 callkit/src/main/AndroidManifest.xml create mode 100644 callkit/src/main/java/io/rong/callkit/AudioPlugin.java create mode 100644 callkit/src/main/java/io/rong/callkit/BaseCallActivity.java create mode 100644 callkit/src/main/java/io/rong/callkit/BaseNoActionBarActivity.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallEndMessageItemProvider.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallFloatBoxView.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallForegroundService.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallOptionMenu.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallPromptDialog.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallSelectMemberActivity.java create mode 100644 callkit/src/main/java/io/rong/callkit/CallUserGridView.java create mode 100644 callkit/src/main/java/io/rong/callkit/ContainerLayout.java create mode 100644 callkit/src/main/java/io/rong/callkit/GlideCallKitImageEngine.java create mode 100644 callkit/src/main/java/io/rong/callkit/MultiAudioCallActivity.java create mode 100644 callkit/src/main/java/io/rong/callkit/MultiCallEndMessageProvider.java create mode 100644 callkit/src/main/java/io/rong/callkit/MultiVideoCallActivity.java create mode 100644 callkit/src/main/java/io/rong/callkit/PickupDetector.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongCallAction.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongCallCustomerHandlerListener.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongCallKit.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongCallModule.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongCallProxy.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongIncomingCallService.java create mode 100644 callkit/src/main/java/io/rong/callkit/RongVoIPIntent.java create mode 100644 callkit/src/main/java/io/rong/callkit/SingleCallActivity.java create mode 100644 callkit/src/main/java/io/rong/callkit/VideoPlugin.java create mode 100644 callkit/src/main/java/io/rong/callkit/VoIPBroadcastReceiver.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/ActivityStartCheckUtils.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/BluetoothUtil.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/BlurBitmapUtil.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarListener.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarView.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/CallKitUtils.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/CallRingingUtil.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/CallSelectMemberSerializable.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/CallVerticalScrollView.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/DefaultPushConfig.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/GlideBlurformation.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/GlideRoundTransform.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/GlideUtils.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/HeadsetInfo.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/ICallScrollView.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/IncomingCallExtraHandleUtil.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/RTCPhoneStateReceiver.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/RingingMode.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/RongCallPermissionUtil.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/SPUtils.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/UserProfileOrderManager.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/permission/DeviceAdapter.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/permission/OSUtils.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/permission/PermissionShowDetail.java create mode 100644 callkit/src/main/java/io/rong/callkit/util/permission/PermissionType.java create mode 100644 callkit/src/main/res/drawable-ldrtl-xhdpi/callkit_ic_nav_back_x.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_ic_nav_back_x.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_ic_search.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_ic_search_delete_x.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_ic_search_focused_x.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_ic_search_x.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_clo_camera.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_mute.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_status.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_mute_unavailable.png create mode 100644 callkit/src/main/res/drawable-xhdpi/callkit_select_ic_nav_back_x.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_ic_phone_normal.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_ic_phone_pressed.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_add.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_audio_answer.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_audio_answer_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_audio_left_cancel.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_audio_left_connected.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_audio_right_cancel.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_audio_right_connected.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_camera.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_camera_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_disable_camera.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_disable_camera_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_float_audio.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_float_video.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_handfree.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_handfree_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_handup.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_hang_up.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_hang_up_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_add.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_camera.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_checked.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_normal.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_input_video.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_icon_input_video_pressed.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_iphone.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_iphone_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_menu_bg.9.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_minimize.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_more.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_mute.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_mute_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_notification_answer.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_notification_hangup.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_phone.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_signal_1.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_signal_2.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_signal_3.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_signal_4.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_signal_5.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_signal_6.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_single_audio_answer.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_single_audio_answer_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_switch_camera.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer_hover.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer_hover_new.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer_new.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_video_left.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_video_right.png create mode 100644 callkit/src/main/res/drawable-xhdpi/rc_voip_whiteboard.png create mode 100644 callkit/src/main/res/drawable/bg_search.xml create mode 100644 callkit/src/main/res/drawable/callkit_multiaudiouesrinfocontners.xml create mode 100644 callkit/src/main/res/drawable/callkit_selector_icon_search.xml create mode 100644 callkit/src/main/res/drawable/callkit_voip_iphone.xml create mode 100644 callkit/src/main/res/drawable/rc_ic_phone_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_ic_video_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_audio_answer_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_audio_answer_selector_new.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_camera_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_checkbox.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_dialog_bg.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_disable_camera_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_float_bg.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_hangup_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_item_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_mute_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_speaker_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_vedio_answer_selector.xml create mode 100644 callkit/src/main/res/drawable/rc_voip_vedio_answer_selector_new.xml create mode 100644 callkit/src/main/res/layout/activity_call_select_member2.xml create mode 100644 callkit/src/main/res/layout/callkit_actionbar_option_text_layout.xml create mode 100644 callkit/src/main/res/layout/callkit_conference_search_top_layout.xml create mode 100644 callkit/src/main/res/layout/callkit_multivideo_gaussianblur.xml create mode 100644 callkit/src/main/res/layout/callkit_rc_voip_activity_select_member.xml create mode 100644 callkit/src/main/res/layout/callkit_rc_voip_activity_select_member_layout.xml create mode 100644 callkit/src/main/res/layout/callkit_view_search_bar_layout.xml create mode 100644 callkit/src/main/res/layout/rc_voip_ac_muti_audio.xml create mode 100644 callkit/src/main/res/layout/rc_voip_activity_select_member.xml create mode 100644 callkit/src/main/res/layout/rc_voip_activity_single_call.xml create mode 100644 callkit/src/main/res/layout/rc_voip_audio_call_user_info.xml create mode 100644 callkit/src/main/res/layout/rc_voip_audio_call_user_info_incoming.xml create mode 100644 callkit/src/main/res/layout/rc_voip_call_bottom_connected_button_layout.xml create mode 100644 callkit/src/main/res/layout/rc_voip_call_bottom_incoming_button_layout.xml create mode 100644 callkit/src/main/res/layout/rc_voip_call_user_info_incoming.xml create mode 100644 callkit/src/main/res/layout/rc_voip_contact_container.xml create mode 100644 callkit/src/main/res/layout/rc_voip_dialog_popup_prompt.xml create mode 100644 callkit/src/main/res/layout/rc_voip_float_box.xml create mode 100644 callkit/src/main/res/layout/rc_voip_item_incoming_maudio.xml create mode 100644 callkit/src/main/res/layout/rc_voip_item_outgoing_maudio.xml create mode 100644 callkit/src/main/res/layout/rc_voip_listitem_select_member.xml create mode 100644 callkit/src/main/res/layout/rc_voip_msg_multi_call_end.xml create mode 100644 callkit/src/main/res/layout/rc_voip_multi_video_call.xml create mode 100644 callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view.xml create mode 100644 callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view_rtl.xml create mode 100644 callkit/src/main/res/layout/rc_voip_multi_video_top_view.xml create mode 100644 callkit/src/main/res/layout/rc_voip_observer_hint.xml create mode 100644 callkit/src/main/res/layout/rc_voip_pop_menu.xml create mode 100644 callkit/src/main/res/layout/rc_voip_user_info.xml create mode 100644 callkit/src/main/res/layout/rc_voip_user_info_mutlaudio.xml create mode 100644 callkit/src/main/res/layout/rc_voip_user_portrait.xml create mode 100644 callkit/src/main/res/layout/rc_voip_video_call_user_info.xml create mode 100644 callkit/src/main/res/layout/rc_voip_viewlet_remote_user.xml create mode 100644 callkit/src/main/res/raw/voip_incoming_ring.mp3 create mode 100644 callkit/src/main/res/raw/voip_network_error_sound.wav create mode 100644 callkit/src/main/res/raw/voip_outgoing_ring.mp3 create mode 100644 callkit/src/main/res/values-ar-rIL/strings.xml create mode 100644 callkit/src/main/res/values-en/colors.xml create mode 100644 callkit/src/main/res/values-en/dimens.xml create mode 100644 callkit/src/main/res/values-en/rc_voipkit_string.xml create mode 100644 callkit/src/main/res/values/callkit_callUserGridViewStyle.xml create mode 100644 callkit/src/main/res/values/colors.xml create mode 100644 callkit/src/main/res/values/dimens.xml create mode 100644 callkit/src/main/res/values/rc_voipkit_color.xml create mode 100644 callkit/src/main/res/values/rc_voipkit_ids.xml create mode 100644 callkit/src/main/res/values/rc_voipkit_string.xml create mode 100644 callkit/src/main/res/values/rc_voipkit_style.xml create mode 100644 callkit/src/main/res/values/strings.xml diff --git a/OneToOne/build.gradle b/OneToOne/build.gradle index a2ce2f631..cae71a630 100644 --- a/OneToOne/build.gradle +++ b/OneToOne/build.gradle @@ -174,6 +174,7 @@ dependencies { api project(path:':TabLayout') api project(path:':ViewPager2Delegate') + api project(path:':callkit')//// 音视频通话能力 UI 组件 //implementation 'com.github.angcyo.DslTablayout:TabLayout:3.5.5' //可选 //implementation 'com.github.angcyo.DslTablayout:ViewPager2Delegate:3.5.5' @@ -182,7 +183,7 @@ dependencies { implementation 'com.google.android.exoplayer:exoplayer:2.18.5' implementation 'com.google.android.exoplayer:exoplayer-core:2.18.5@aar' - implementation 'cn.rongcloud.sdk:call_kit:5.5.0' // 音视频通话能力 UI 组件 + // implementation 'cn.rongcloud.sdk:call_kit:5.5.0' // 音视频通话能力 UI 组件 implementation 'com.github.luqiming666:SwipeRecyclerView:1.4.8'//支持侧滑删除 implementation 'com.google.android.material:material:1.6.1' implementation 'com.blankj:utilcode:1.30.0'//獲取uuid diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/DiamondExchangeActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/DiamondExchangeActivity.java index 95c58cd2a..0eb8f4ba9 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/DiamondExchangeActivity.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/DiamondExchangeActivity.java @@ -33,7 +33,7 @@ import java.util.List; public class DiamondExchangeActivity extends AbsOTOActivity { private RecyclerView diamondExchangeList; private DiamondExchangeAdapter exchangeAdapter; - private TextView title, totalConvertibility; + private TextView title, totalConvertibility,totalConvertibilityDes; private String type = "yuanbao"; private EditText diamondExchangeInput; @@ -63,6 +63,7 @@ public class DiamondExchangeActivity extends AbsOTOActivity { title = findViewById(R.id.title); diamondExchangeInput = findViewById(R.id.diamond_exchange_input); totalConvertibility = findViewById(R.id.total_convertibility); + totalConvertibilityDes = findViewById(R.id.total_convertibility_des); diamondExchangeList.addItemDecoration(new ItemDecoration(mContext, Color.parseColor("#ffffff"), 10, 2)); diamondExchangeList.setLayoutManager(new GridLayoutManager(mContext, 3)); exchangeAdapter = new DiamondExchangeAdapter(); @@ -114,15 +115,15 @@ public class DiamondExchangeActivity extends AbsOTOActivity { if (data.size() > 0) { if ((data.size() - 1) > index && index > 0) { data.get(index).setSelect(true); - totalConvertibility.setText(String.valueOf(data.get(0).getNum())); + totalConvertibility.setText(String.valueOf(data.get(0).getSum())); number = data.get(index).getNum(); } else { if (TextUtils.isEmpty(diamondExchangeInput.getText().toString())) { data.get(0).setSelect(true); - totalConvertibility.setText(String.valueOf(data.get(0).getNum())); + totalConvertibility.setText(String.valueOf(data.get(0).getSum())); number = data.get(0).getNum(); } else { - totalConvertibility.setText(String.valueOf(data.get(0).getNum())); + totalConvertibility.setText(String.valueOf(data.get(0).getSum())); for (int i = 0; i < data.size(); i++) { data.get(i).setSelect(false); } @@ -188,7 +189,7 @@ public class DiamondExchangeActivity extends AbsOTOActivity { public void onSuccess(List data) { if (data.size() > 0) { data.get(0).setSelect(true); - totalConvertibility.setText(String.valueOf(data.get(0).getNum())); + totalConvertibility.setText(String.valueOf(data.get(0).getSum())); number = data.get(0).getNum(); exchangeAdapter.addData(data); } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/ExchangeRecordActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/ExchangeRecordActivity.java index b9d2805db..c1d301509 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/ExchangeRecordActivity.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/ExchangeRecordActivity.java @@ -83,7 +83,7 @@ public class ExchangeRecordActivity extends AbsOTOActivity { private void initData() { OTONetManager.getInstance(mContext). - getExchangeRecord(type, "3", "2", page, new HttpCallback>() { + getExchangeRecord("10,11", "3", "2", page, new HttpCallback>() { @Override public void onSuccess(List data) { if (page != 1 && data.isEmpty()) { diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java index 91d659f45..4f85cc12c 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java @@ -552,7 +552,13 @@ public class ChatMessageFragment extends AbsConversationFragment { ViewClicksAntiShake.clicksAntiShake(home, new ViewClicksAntiShake.ViewClicksCallBack() { @Override public void onViewClicks() { - UserManager.toHomePage(targetId); + UserManager.toHomePage(targetId,true); + } + }); + ViewClicksAntiShake.clicksAntiShake(avatar, new ViewClicksAntiShake.ViewClicksCallBack() { + @Override + public void onViewClicks() { + UserManager.toHomePage(targetId,true); } }); follow.setOnClickListener(v -> { diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MessageInteractiveFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MessageInteractiveFragment.java index 83d84e74e..7e510512b 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MessageInteractiveFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MessageInteractiveFragment.java @@ -43,7 +43,7 @@ public class MessageInteractiveFragment extends AbsConversationFragment { @Override public void main() { setTitle(noticeBean.getTitle()); - mList.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, true)); + mList.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false)); initData(); } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MsgMessageFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MsgMessageFragment.java index 3a97e658c..d61d2acc6 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MsgMessageFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/MsgMessageFragment.java @@ -375,8 +375,8 @@ public class MsgMessageFragment extends BaseFragment implements BaseAdapter.OnIt this.mRefreshLayout.setOnRefreshListener(new OnRefreshListener() { public void onRefresh(@NonNull RefreshLayout refreshLayout) { initSystemNotice(); - MsgMessageFragment.this.onConversationListRefresh(refreshLayout); updateUserInfo(); + MsgMessageFragment.this.onConversationListRefresh(refreshLayout); } }); this.mRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java index 5c75fbd41..cd490b71e 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallAudioActivity.java @@ -2,6 +2,7 @@ package com.shayu.onetoone.activity.message; import android.Manifest; import android.app.Dialog; +import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; @@ -42,6 +43,7 @@ import com.shayu.onetoone.manager.OTONetManager; import com.shayu.onetoone.manager.RouteManager; import com.shayu.onetoone.utils.ConversationUtils; import com.shayu.onetoone.utils.HtmlUrlUtils; +import com.yunbao.common.activity.MyWalletActivity; import com.yunbao.common.glide.ImgLoader; import com.yunbao.common.http.base.HttpCallback; import com.yunbao.common.interfaces.OnItemClickListener; @@ -345,8 +347,8 @@ public class CallAudioActivity extends AbsOTOActivity implements View.OnClickLis finish(); if (toPay) { Log.e(TAG, "调起支付界面"); - // RouteManager.forwardWebViewActivity(null, "https://www.baidu.com"); - RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext,false,HtmlUrlUtils.URL_PAY_COIN)); + // RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext,false,HtmlUrlUtils.URL_PAY_COIN)); + mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 1)); } if (toChatView) { ConversationUtils.startConversation(mContext, targetId); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java index 67ab90b9f..eeafaacfb 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/CallVideoActivity.java @@ -3,6 +3,7 @@ package com.shayu.onetoone.activity.message; import android.Manifest; import android.annotation.SuppressLint; import android.app.Dialog; +import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; @@ -44,6 +45,7 @@ import com.shayu.onetoone.manager.OTONetManager; import com.shayu.onetoone.manager.RouteManager; import com.shayu.onetoone.utils.ConversationUtils; import com.shayu.onetoone.utils.HtmlUrlUtils; +import com.yunbao.common.activity.MyWalletActivity; import com.yunbao.common.glide.ImgLoader; import com.yunbao.common.http.base.HttpCallback; import com.yunbao.common.interfaces.OnItemClickListener; @@ -455,7 +457,8 @@ public class CallVideoActivity extends AbsOTOActivity { } }).show(); if (toPay) { - RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + // RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 1)); } if (toChatView) { ConversationUtils.startConversation(mContext, targetId); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/ChatActivity.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/ChatActivity.java index 15627883f..7a6f3eaf5 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/message/ChatActivity.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/message/ChatActivity.java @@ -65,6 +65,11 @@ public class ChatActivity extends AbsOTOActivity { return R.layout.activity_msg_chat; } + @Override + protected boolean onCreate() { + return false; + } + @Override protected void main(Bundle savedInstanceState) { int type = getIntent().getIntExtra("model", 0); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/adapter/MsgMessageRecyclerViewAdapter.java b/OneToOne/src/main/java/com/shayu/onetoone/adapter/MsgMessageRecyclerViewAdapter.java index 595678fa9..79aa714a9 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/adapter/MsgMessageRecyclerViewAdapter.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/adapter/MsgMessageRecyclerViewAdapter.java @@ -5,6 +5,7 @@ import android.text.SpannableString; import com.shayu.onetoone.R; import com.shayu.onetoone.bean.MessageChatAuthContent; import com.shayu.onetoone.bean.MessageChatGiftContent; +import com.shayu.onetoone.bean.MessageChatTipsContent; import com.yanzhenjie.recyclerview.SwipeRecyclerView; import com.yunbao.common.utils.WordUtil; @@ -75,6 +76,8 @@ public class MsgMessageRecyclerViewAdapter extends ConversationListAdapter { datum.mConversationContent = new SpannableString(WordUtil.getNewString(R.string.gift)); } else if (datum.mCore.getLatestMessage() instanceof MessageChatAuthContent) { datum.mConversationContent = new SpannableString(WordUtil.getNewString(R.string.authentication)); + }else if(datum.mCore.getLatestMessage() instanceof MessageChatTipsContent){ + datum.mConversationContent = new SpannableString(WordUtil.getNewString(R.string.system_tips)); } if (datum.mCore.isTop()) { top.add(datum); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/bean/ExchangeModel.java b/OneToOne/src/main/java/com/shayu/onetoone/bean/ExchangeModel.java index a952a364c..2c760fbb0 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/bean/ExchangeModel.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/bean/ExchangeModel.java @@ -13,6 +13,9 @@ public class ExchangeModel extends BaseModel { private String title; @SerializedName("num") private String num; + @SerializedName("sum") + private String sum; + private boolean select = false; public boolean isSelect() { @@ -24,6 +27,14 @@ public class ExchangeModel extends BaseModel { return this; } + public String getSum() { + return sum; + } + + public void setSum(String sum) { + this.sum = sum; + } + public String getTop() { return top; } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/dialog/GiftDialog.java b/OneToOne/src/main/java/com/shayu/onetoone/dialog/GiftDialog.java index b6cc3cecb..b0afcb7e2 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/dialog/GiftDialog.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/dialog/GiftDialog.java @@ -2,6 +2,7 @@ package com.shayu.onetoone.dialog; import android.app.Dialog; import android.content.Context; +import android.content.Intent; import android.widget.Button; import android.widget.TextView; @@ -28,6 +29,7 @@ import com.shayu.onetoone.view.MsgInputPanelForGift; import com.shayu.onetoone.widget.PagerConfig; import com.shayu.onetoone.widget.PagerGridLayoutManager; import com.shayu.onetoone.widget.PagerGridSnapHelper; +import com.yunbao.common.activity.MyWalletActivity; import com.yunbao.common.dialog.AbsDialogPopupWindow; import com.yunbao.common.http.base.HttpCallback; import com.yunbao.common.interfaces.OnItemClickListener; @@ -133,7 +135,8 @@ public class GiftDialog extends AbsDialogPopupWindow { ViewClicksAntiShake.clicksAntiShake(topUpBtn, new ViewClicksAntiShake.ViewClicksCallBack() { @Override public void onViewClicks() { - RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + //RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 1)); } }); } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/dialog/TipsDialog.java b/OneToOne/src/main/java/com/shayu/onetoone/dialog/TipsDialog.java index cc63672dc..6276024ce 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/dialog/TipsDialog.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/dialog/TipsDialog.java @@ -1,6 +1,7 @@ package com.shayu.onetoone.dialog; import android.content.Context; +import android.content.Intent; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -13,6 +14,7 @@ import com.shayu.onetoone.R; import com.shayu.onetoone.listener.OnDialogClickListener; import com.shayu.onetoone.manager.RouteManager; import com.shayu.onetoone.utils.HtmlUrlUtils; +import com.yunbao.common.activity.MyWalletActivity; import com.yunbao.common.dialog.AbsDialogCenterPopupWindow; import com.yunbao.common.utils.StringUtil; import com.yunbao.common.utils.WordUtil; @@ -113,7 +115,8 @@ public class TipsDialog extends AbsDialogCenterPopupWindow { if (!StringUtil.isEmpty(applyText)&&( applyText.equals(WordUtil.getNewString(R.string.money_apply)) || applyText.equals(WordUtil.getNewString(R.string.dialog_to_money_tip)))) { - RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + // RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 1)); } if (onDialogClickListener != null) { onDialogClickListener.onApply(dialog); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/provider/CustomConversationProvider.java b/OneToOne/src/main/java/com/shayu/onetoone/provider/CustomConversationProvider.java index 2159dfd8a..db1d5f959 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/provider/CustomConversationProvider.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/provider/CustomConversationProvider.java @@ -33,10 +33,10 @@ public class CustomConversationProvider extends BaseConversationProvider { try { if (json.getInteger("sex") == -1) { holder.getView(R.id.sex).setVisibility(View.GONE); - } else if (json.getInteger("sex") == 2) { - holder.setImageResource(R.id.sex, R.mipmap.ic_message_tab_woman); - } else { + } else if (json.getInteger("sex") == 1) { holder.setImageResource(R.id.sex, R.mipmap.ic_message_tab_man); + } else { + holder.setImageResource(R.id.sex, R.mipmap.ic_message_tab_woman); } } catch (Exception e) { e.printStackTrace(); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/utils/UserManager.java b/OneToOne/src/main/java/com/shayu/onetoone/utils/UserManager.java index f19faef87..1cf3393fd 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/utils/UserManager.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/utils/UserManager.java @@ -120,6 +120,8 @@ public class UserManager { } public static void toHomePage(int userId) { + } + public static void toHomePage(String userId,boolean isGoto) { toHomePage(userId+""); } public static void toHomePage(String userId) { diff --git a/OneToOne/src/main/java/com/shayu/onetoone/view/MsgInputPanelForGift.java b/OneToOne/src/main/java/com/shayu/onetoone/view/MsgInputPanelForGift.java index 146671a52..14449893c 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/view/MsgInputPanelForGift.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/view/MsgInputPanelForGift.java @@ -1,6 +1,7 @@ package com.shayu.onetoone.view; import android.app.Dialog; +import android.content.Intent; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -27,6 +28,7 @@ import com.shayu.onetoone.utils.UserManager; import com.shayu.onetoone.widget.PagerConfig; import com.shayu.onetoone.widget.PagerGridLayoutManager; import com.shayu.onetoone.widget.PagerGridSnapHelper; +import com.yunbao.common.activity.MyWalletActivity; import com.yunbao.common.http.base.HttpCallback; import com.yunbao.common.interfaces.OnItemClickListener; import com.yunbao.common.manager.IMLoginManager; @@ -117,7 +119,8 @@ public class MsgInputPanelForGift extends AbsInputPanel { ViewClicksAntiShake.clicksAntiShake(topUpBtn, new ViewClicksAntiShake.ViewClicksCallBack() { @Override public void onViewClicks() { - RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + //RouteManager.forwardWebViewActivity(null, HtmlUrlUtils.getPayUrl(mContext, false, HtmlUrlUtils.URL_PAY_COIN)); + mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 1)); } }); } diff --git a/OneToOne/src/main/res/layout/activity_diamond_exchange.xml b/OneToOne/src/main/res/layout/activity_diamond_exchange.xml index fc064d93f..8e4afbf71 100644 --- a/OneToOne/src/main/res/layout/activity_diamond_exchange.xml +++ b/OneToOne/src/main/res/layout/activity_diamond_exchange.xml @@ -84,6 +84,7 @@ android:textSize="22sp" /> + android:background="@color/rc_white_color" + android:layout_height="match_parent"> + android:visibility="gone" /> + android:visibility="gone" /> 前往充值 [禮物] [邀請認證] + [系統提示] 等待對方接受邀請… 連接成功 需要獲取您的權限 diff --git a/OneToOne/src/main/res/values-zh-rTW/strings.xml b/OneToOne/src/main/res/values-zh-rTW/strings.xml index 840783a81..8f071b808 100644 --- a/OneToOne/src/main/res/values-zh-rTW/strings.xml +++ b/OneToOne/src/main/res/values-zh-rTW/strings.xml @@ -97,6 +97,7 @@ 前往充值 [禮物] [邀請認證] + [系統提示] 等待對方接受邀請… 連接成功 需要獲取您的權限 diff --git a/OneToOne/src/main/res/values/strings.xml b/OneToOne/src/main/res/values/strings.xml index 9dda19ecb..24c226d3f 100644 --- a/OneToOne/src/main/res/values/strings.xml +++ b/OneToOne/src/main/res/values/strings.xml @@ -99,6 +99,7 @@ 前往充值 [禮物] [邀請認證] + [系統提示] 等待對方接受邀請… 連接成功 需要獲取您的權限 diff --git a/callkit/.gitignore b/callkit/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/callkit/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/callkit/README.md b/callkit/README.md new file mode 100644 index 000000000..9e305f4bc --- /dev/null +++ b/callkit/README.md @@ -0,0 +1,43 @@ +## callkit-android + +Open-source code of RongCloud VoIP Audio/Video UI. 融云音视频通话功能 UI 界面 SDK 开源代码。 + +## 适用场景 + +融云提供 CallKit 源码,是为方便开发者根据 App 风格对呼叫 UI 做个性化的修改,比如色调搭配,按钮位置等,都可以自由定制。 + +## 集成步骤 + +1. 先按照 Maven 导入或本地手动导入的方式,集成 CallLib、IMKit、IMLib 三个 CallKit 依赖库,并确保都是当时官网的最新版本,如下: + + ```groovy + dependencies { + implementation 'cn.rongcloud.sdk:call_lib:x.y.z' + implementation 'cn.rongcloud.sdk:im_kit:x.y.z' + implementation 'cn.rongcloud.sdk:im_lib:x.y.z' + } + ``` + + > CallKit 源码因为是开源的,融云不提供老版本的下载。用户配合 CallKit 所使用的 CallLib、IMKit、IMLib 版本应该也是官网此时的最新版本。 + +2. 进入工程目录,克隆 CallKit 源码: + + ```shell + cd + git clone https://github.com/rongcloud/callkit-android.git + ``` + +3. 在 `settings.gradle` 文件中,添加引用: + + ```groovy + include ':callkit-android' + ``` + +4. 在应用的 `build.gradle` 中,添加依赖: + + ```groovy + dependencies { + ... + implementation project(':callkit-android') + } + ``` \ No newline at end of file diff --git a/callkit/build.gradle b/callkit/build.gradle new file mode 100644 index 000000000..6a36469dd --- /dev/null +++ b/callkit/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 33 + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 31 + versionName "5.6.5" + } + + sourceSets { + main { + manifest.srcFile 'src/main/AndroidManifest.xml' + jniLibs.srcDirs = ['libs'] + } + } +} + +dependencies { + api fileTree(dir: 'libs', include: ['*.jar']) + api project(path: ':common') + + implementation 'androidx.media:media:1.2.1' + implementation 'com.github.bumptech.glide:glide:4.9.0' +} diff --git a/callkit/proguard-rules.pro b/callkit/proguard-rules.pro new file mode 100644 index 000000000..2b3c220dd --- /dev/null +++ b/callkit/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/jiangecho/apps/adt-bundle-mac-x86_64-20140702/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/callkit/src/main/AndroidManifest.xml b/callkit/src/main/AndroidManifest.xml new file mode 100644 index 000000000..56c5e116c --- /dev/null +++ b/callkit/src/main/AndroidManifest.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/java/io/rong/callkit/AudioPlugin.java b/callkit/src/main/java/io/rong/callkit/AudioPlugin.java new file mode 100644 index 000000000..b45cea7fe --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/AudioPlugin.java @@ -0,0 +1,201 @@ +package io.rong.callkit; + +import static io.rong.callkit.BaseCallActivity.REQUEST_CODE_ADD_MEMBER; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.callkit.util.permission.PermissionType; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.common.RLog; +import io.rong.imkit.conversation.extension.RongExtension; +import io.rong.imkit.conversation.extension.component.plugin.IPluginModule; +import io.rong.imkit.conversation.extension.component.plugin.IPluginRequestPermissionResultCallback; +import io.rong.imlib.IRongCoreCallback; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.discussion.base.RongDiscussionClient; +import io.rong.imlib.discussion.model.Discussion; +import io.rong.imlib.model.Conversation; +import java.util.ArrayList; + +/** Created by weiqinxiao on 16/8/16. */ +public class AudioPlugin implements IPluginModule, IPluginRequestPermissionResultCallback { + private static final String TAG = "AudioPlugin"; + private ArrayList allMembers; + private Context context; + private static final int REQEUST_CODE_RECORD_AUDIO_PERMISSION = 101; + + private Conversation.ConversationType conversationType; + private String targetId; + + @Override + public Drawable obtainDrawable(Context context) { + return context.getResources().getDrawable(R.drawable.rc_ic_phone_selector); + } + + @Override + public String obtainTitle(Context context) { + return context.getString(R.string.rc_voip_audio); + } + + @Override + public void onClick(Fragment currentFragment, RongExtension extension, int index) { + context = currentFragment.getActivity().getApplicationContext(); + conversationType = extension.getConversationType(); + targetId = extension.getTargetId(); + Log.i(TAG, "---- targetId==" + targetId); + + PermissionType[] audioCallPermissions = + RongCallPermissionUtil.getAudioCallPermissions(context); + String[] permissions = new String[audioCallPermissions.length]; + for (int i = 0; i < audioCallPermissions.length; i++) { + permissions[i] = audioCallPermissions[i].getPermissionName(); + } + + if (RongCallPermissionUtil.checkPermissions(currentFragment.getActivity(), permissions)) { + Log.i(TAG, "---- startAudioActivity ----"); + startAudioActivity(currentFragment, extension); + } else { + Log.i(TAG, "---- requestPermissionForPluginResult ----"); + extension.requestPermissionForPluginResult( + permissions, REQEUST_CODE_RECORD_AUDIO_PERMISSION, this); + } + } + + private void startAudioActivity(Fragment currentFragment, final RongExtension extension) { + if (context == null) { + return; + } + RongCallSession profile = RongCallClient.getInstance().getCallSession(); + if (profile != null && profile.getStartTime() > 0) { + Toast.makeText( + context, + profile.getMediaType() == RongCallCommon.CallMediaType.AUDIO + ? currentFragment.getString( + R.string.rc_voip_call_audio_start_fail) + : currentFragment.getString( + R.string.rc_voip_call_video_start_fail), + Toast.LENGTH_SHORT) + .show(); + return; + } + if (!CallKitUtils.isNetworkAvailable(context)) { + Toast.makeText( + context, + currentFragment.getString(R.string.rc_voip_call_network_error), + Toast.LENGTH_SHORT) + .show(); + return; + } + + if (conversationType.equals(Conversation.ConversationType.PRIVATE)) { + Intent intent = new Intent(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO); + intent.putExtra("conversationType", conversationType.getName().toLowerCase()); + Log.i( + TAG, + "---- conversationType.getName().toLowerCase() =-" + + conversationType.getName().toLowerCase()); + intent.putExtra("targetId", targetId); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + Log.i(TAG, "---- callAction=" + RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Log.i(TAG, "getPackageName===" + context.getPackageName()); + intent.setPackage(context.getPackageName()); + context.startActivity(intent); + } else if (conversationType.equals(Conversation.ConversationType.DISCUSSION)) { + RongDiscussionClient.getInstance() + .getDiscussion( + targetId, + new IRongCoreCallback.ResultCallback() { + @Override + public void onSuccess(Discussion discussion) { + Intent intent = + new Intent(context, CallSelectMemberActivity.class); + allMembers = (ArrayList) discussion.getMemberIdList(); + intent.putStringArrayListExtra("allMembers", allMembers); + intent.putExtra( + "conversationType", conversationType.getValue()); + String myId = RongIMClient.getInstance().getCurrentUserId(); + ArrayList invited = new ArrayList<>(); + invited.add(myId); + intent.putStringArrayListExtra("invitedMembers", invited); + intent.putExtra( + "mediaType", + RongCallCommon.CallMediaType.AUDIO.getValue()); + extension.startActivityForPluginResult( + intent, 110, AudioPlugin.this); + } + + @Override + public void onError(IRongCoreEnum.CoreErrorCode e) { + RLog.d(TAG, "get discussion errorCode = " + e.getValue()); + } + }); + } else if (conversationType.equals(Conversation.ConversationType.GROUP)) { + Intent intent = new Intent(context, CallSelectMemberActivity.class); + String myId = RongIMClient.getInstance().getCurrentUserId(); + ArrayList invited = new ArrayList<>(); + invited.add(myId); + intent.putStringArrayListExtra("invitedMembers", invited); + intent.putExtra("conversationType", conversationType.getValue()); + intent.putExtra("groupId", targetId); + intent.putExtra("mediaType", RongCallCommon.CallMediaType.AUDIO.getValue()); + extension.startActivityForPluginResult(intent, 110, this); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode != Activity.RESULT_OK) { + return; + } + + if (requestCode == REQUEST_CODE_ADD_MEMBER) { + if (resultCode == Activity.RESULT_OK) { + if (data.getBooleanExtra("remote_hangup", false)) { + RLog.d(TAG, "Remote exit, end the call."); + return; + } + } + } + Intent intent = new Intent(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO); + ArrayList userIds = data.getStringArrayListExtra("invited"); + ArrayList observers = data.getStringArrayListExtra("observers"); + userIds.add(RongIMClient.getInstance().getCurrentUserId()); + intent.putExtra("conversationType", conversationType.getName().toLowerCase()); + intent.putExtra("targetId", targetId); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.putStringArrayListExtra("invitedUsers", userIds); + intent.putStringArrayListExtra("observers", observers); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + context.startActivity(intent); + } + + @Override + public boolean onRequestPermissionResult( + Fragment fragment, + RongExtension extension, + int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + Context context = fragment.getContext(); + if (RongCallPermissionUtil.checkPermissions(context, permissions)) { + startAudioActivity(fragment, extension); + } else { + RongCallPermissionUtil.showRequestPermissionFailedAlter( + context, permissions, grantResults); + } + return true; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/BaseCallActivity.java b/callkit/src/main/java/io/rong/callkit/BaseCallActivity.java new file mode 100644 index 000000000..ae881831f --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/BaseCallActivity.java @@ -0,0 +1,862 @@ +package io.rong.callkit; + +import static io.rong.callkit.CallFloatBoxView.showFB; +import static io.rong.callkit.util.CallKitUtils.isDial; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadset; +import android.bluetooth.BluetoothProfile; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.media.AudioManager; +import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.os.Handler; +import android.os.PowerManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.NonNull; +import cn.rongcloud.rtc.api.RCRTCAudioRouteManager; +import cn.rongcloud.rtc.api.callback.IRCRTCAudioRouteListener; +import cn.rongcloud.rtc.api.stream.RCRTCVideoStreamConfig.Builder; +import cn.rongcloud.rtc.audioroute.RCAudioRouteType; +import cn.rongcloud.rtc.base.RCRTCParamsType.RCRTCVideoFps; +import cn.rongcloud.rtc.base.RCRTCParamsType.RCRTCVideoResolution; +import cn.rongcloud.rtc.utils.FinLog; +import io.rong.callkit.util.BluetoothUtil; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.CallRingingUtil; +import io.rong.callkit.util.HeadsetInfo; +import io.rong.callkit.util.RingingMode; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.calllib.IRongCallListener; +import io.rong.calllib.PublishCallBack; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallCommon.CallMediaType; +import io.rong.calllib.RongCallSession; +import io.rong.common.RLog; +import io.rong.imkit.manager.AudioPlayManager; +import io.rong.imkit.manager.AudioRecordManager; +import io.rong.imkit.notification.NotificationUtil; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imkit.userinfo.model.GroupUserInfo; +import io.rong.imlib.model.Group; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; + +/** Created by weiqinxiao on 16/3/9. */ +public class BaseCallActivity extends BaseNoActionBarActivity + implements IRongCallListener, + PickupDetector.PickupDetectListener, + RongUserInfoManager.UserDataObserver { + + private static final String TAG = "BaseCallActivity"; + private static final String MEDIAPLAYERTAG = "MEDIAPLAYERTAG"; + private static final long DELAY_TIME = 1000; + static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 100; + static final int REQUEST_CODE_ADD_MEMBER = 110; + public final int REQUEST_CODE_ADD_MEMBER_NONE = 120; + static final int VOIP_MAX_NORMAL_COUNT = 6; + + private long time = 0; + private Runnable updateTimeRunnable; + + private boolean shouldRestoreFloat; + // 是否是请求开启悬浮窗权限的过程中 + private boolean checkingOverlaysPermission; + private boolean notRemindRequestFloatWindowPermissionAgain = false; + protected Handler handler; + /** 表示是否正在挂断 */ + protected boolean isFinishing; + + protected PickupDetector pickupDetector; + protected PowerManager powerManager; + protected PowerManager.WakeLock wakeLock; + protected PowerManager.WakeLock screenLock; + + // static final String[] VIDEO_CALL_PERMISSIONS = { + // Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA + // }; + // static final String[] AUDIO_CALL_PERMISSIONS = {Manifest.permission.RECORD_AUDIO}; + + public static final int CALL_NOTIFICATION_ID = 4000; + boolean isMuteCamera = false; + + /** + * 融云 SDK 默认麦克风、摄像头流唯一标识,和 RongCallClient#publishCustomVideoStream(tag, PublishCallBack) 方法中 tag + * 用法一致; 用户发布自定义视频流唯一标示,不允许带下划线,不能为 “RongCloudRTC”; + * + * @see RongCallClient#publishCustomVideoStream(String, PublishCallBack) + */ + public static final String RONG_TAG_CALL = "RongCloudRTC"; + + RelativeLayout.LayoutParams mLargeLayoutParams = + new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + + public void setShouldShowFloat(boolean ssf) { + CallKitUtils.shouldShowFloat = ssf; + } + + public void showShortToast(String text) { + Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); + } + + public void postRunnableDelay(Runnable runnable) { + handler.postDelayed(runnable, DELAY_TIME); + } + + private HeadsetPlugReceiver headsetPlugReceiver = null; + private AudioManager.OnAudioFocusChangeListener onAudioFocusChangeListener; + + public static final String EXTRA_BUNDLE_KEY_MUTECAMERA = "muteCamera"; + public static final String EXTRA_BUNDLE_KEY_MUTEMIC = "muteMIC"; + public static final String EXTRA_BUNDLE_KEY_LOCALVIEWUSERID = "localViewUserId"; + public static final String EXTRA_BUNDLE_KEY_CALLACTION = "callAction"; + public static final String EXTRA_BUNDLE_KEY_MEDIATYPE = "mediaType"; + public static final String EXTRA_BUNDLE_KEY_USER_TOP_NAME = "rc_voip_user_top_name"; + public static final String EXTRA_BUNDLE_KEY_USER_TOP_NAME_TAG = "rc_voip_user_top_name_tag"; + public static final String EXTRA_BUNDLE_KEY_USER_PROFILE_TAG_ORDER_TAG = + "extra_bundle_key_user_profile_tag_order_tag"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + RLog.d(TAG, "BaseCallActivity onCreate"); + audioVideoConfig(); + getWindow() + .setFlags( + WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow() + .setFlags( + WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, + WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getWindow() + .addFlags( + WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); + shouldRestoreFloat = true; + CallKitUtils.shouldShowFloat = false; + + createPowerManager(); + boolean isScreenOn = powerManager.isScreenOn(); + if (!isScreenOn) { + wakeLock.acquire(); + } + handler = new Handler(); + mLargeLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); + RongCallProxy.getInstance().setCallListener(this); + + AudioPlayManager.getInstance().stopPlay(); + AudioRecordManager.getInstance().destroyRecord(); + RongUserInfoManager.getInstance().addUserDataObserver(this); + + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + if (am != null) { + onAudioFocusChangeListener = + new AudioManager.OnAudioFocusChangeListener() { + @Override + public void onAudioFocusChange(int focusChange) {} + }; + am.requestAudioFocus( + onAudioFocusChangeListener, + AudioManager.STREAM_MUSIC, + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + } + if (Build.VERSION.SDK_INT >= 31 + && getApplication().getApplicationInfo().targetSdkVersion >= 31) { + // Android 12 禁止了通过广播和服务跳板的方式启动 Activity,此代码是为了兼容之前的逻辑 + Intent intent = new Intent(); + intent.setAction(VoIPBroadcastReceiver.ACTION_CLEAR_VOIP_NOTIFICATION); + intent.setPackage(getPackageName()); + sendBroadcast(intent); + } + } + + @Override + protected void onStart() { + super.onStart(); + Intent intent = getIntent(); + Bundle bundle = intent.getBundleExtra("floatbox"); + if (shouldRestoreFloat && bundle != null) { + onRestoreFloatBox(bundle); + } + } + + public void callRinging(RingingMode mode) { + CallRingingUtil.getInstance().startRinging(this, mode); + } + + public void onIncomingCallRinging(RongCallSession callSession) { + CallRingingUtil.getInstance().startRinging(this, RingingMode.Incoming); + if (callSession != null) { + String callId = callSession.getCallId(); + if (!TextUtils.isEmpty(callId) + && callId.equals( + getIntent() + .getStringExtra( + RongIncomingCallService.KEY_NEED_AUTO_ANSWER))) { + RongCallClient.getInstance().acceptCall(callId); + } + } + } + + public void setupTime(final TextView timeView) { + try { + if (updateTimeRunnable != null) { + handler.removeCallbacks(updateTimeRunnable); + } + timeView.setVisibility(View.VISIBLE); + updateTimeRunnable = new UpdateTimeRunnable(timeView); + handler.post(updateTimeRunnable); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void cancelTime() { + if (handler != null && updateTimeRunnable != null) { + handler.removeCallbacks(updateTimeRunnable); + } + } + + public long getTime(long activeTime) { + long tmpTime = activeTime == 0 ? 0 : (System.currentTimeMillis() - activeTime) / 1000; + time = tmpTime == 0 ? time : tmpTime; + return time; + } + + @SuppressLint("MissingPermission") + protected void stopRing() { + CallRingingUtil.getInstance().stopRinging(); + } + + @Override + public void onCallIncoming(RongCallSession callSession, SurfaceView localVideo) { + CallKitUtils.shouldShowFloat = true; + CallKitUtils.isDial = false; + } + + @Override + public void onCallOutgoing(RongCallSession callProfile, SurfaceView localVideo) { + CallKitUtils.shouldShowFloat = true; + CallKitUtils.isDial = true; + } + + @Override + public void onRemoteUserRinging(String userId) {} + + @Override + public void onRemoteUserAccept(String userId, CallMediaType mediaType) {} + + @Override + public void onCallDisconnected( + RongCallSession callProfile, RongCallCommon.CallDisconnectedReason reason) { + stopForegroundService(); + if (RongCallKit.getCustomerHandlerListener() != null) { + RongCallKit.getCustomerHandlerListener().onCallDisconnected(callProfile, reason); + } + CallKitUtils.callConnected = false; + CallKitUtils.shouldShowFloat = false; + + toastDisconnectReason(reason); + + AudioPlayManager.getInstance().setInVoipMode(false); + stopRing(); + NotificationUtil.getInstance() + .clearNotification(this, BaseCallActivity.CALL_NOTIFICATION_ID); + RongCallProxy.getInstance().setCallListener(null); + } + + @Override + public void onRemoteUserJoined( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + CallKitUtils.isDial = false; + } + + @Override + public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) { + if (RongCallKit.getCustomerHandlerListener() != null) { + RongCallKit.getCustomerHandlerListener().onRemoteUserInvited(userId, mediaType); + } + } + + @Override + public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) { + RLog.i( + TAG, + "onRemoteUserLeft userId :" + + userId + + ", CallDisconnectedReason :" + + reason.name()); + toastDisconnectReason(reason); + } + + @Override + public void onMediaTypeChanged( + String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) {} + + @Override + public void onError(RongCallCommon.CallErrorCode errorCode) { + AudioPlayManager.getInstance().setInVoipMode(false); + if (RongCallCommon.CallErrorCode.ENGINE_NOT_FOUND.getValue() == errorCode.getValue()) { + Toast.makeText( + this, + getResources().getString(R.string.rc_voip_engine_notfound), + Toast.LENGTH_SHORT) + .show(); + finish(); + } + } + + @Override + public void onCallConnected(RongCallSession callProfile, SurfaceView localVideo) { + registerAudioRouteTypeChange(); + if (RongCallKit.getCustomerHandlerListener() != null) { + RongCallKit.getCustomerHandlerListener().onCallConnected(callProfile, localVideo); + } + CallKitUtils.callConnected = true; + CallKitUtils.shouldShowFloat = true; + CallKitUtils.isDial = false; + AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + if (audioManager != null) { + audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + } + AudioPlayManager.getInstance().setInVoipMode(true); + AudioRecordManager.getInstance().destroyRecord(); + } + + private void registerAudioRouteTypeChange() { + RCRTCAudioRouteManager.getInstance() + .setOnAudioRouteChangedListener( + new IRCRTCAudioRouteListener() { + @Override + public void onRouteChanged(RCAudioRouteType type) { + resetHandFreeStatus(type); + } + + @Override + public void onRouteSwitchFailed( + RCAudioRouteType fromType, RCAudioRouteType toType) {} + }); + } + + protected void resetHandFreeStatus(RCAudioRouteType type) {} + + @Override + protected void onStop() { + super.onStop(); + RLog.d(TAG, "BaseCallActivity onStop"); + if (CallKitUtils.shouldShowFloat && !checkingOverlaysPermission) { + showForegroundService(); + Bundle bundle = new Bundle(); + String action = onSaveFloatBoxState(bundle); + if (checkDrawOverlaysPermission(true)) { + if (action != null) { + bundle.putString("action", action); + showFB(getApplicationContext(), bundle); + if (!isFinishing()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + RLog.d(TAG, "BaseCallActivity onStop finishAndRemoveTask()"); + finishAndRemoveTask(); + } else { + RLog.d(TAG, "BaseCallActivity onStop finish()"); + finish(); + } + } + } + } else { + Toast.makeText( + this, + getString(R.string.rc_voip_float_window_not_allowed), + Toast.LENGTH_SHORT) + .show(); + } + } else if (checkingOverlaysPermission) { + showForegroundService(); + } + } + + private void showForegroundService() { + RongCallSession callSession = RongCallClient.getInstance().getCallSession(); + if (callSession == null) { + Log.e(TAG, "showForegroundService: RongCallSession is Null!"); + return; + } + + String content = + callSession.getMediaType().getValue() == CallMediaType.AUDIO.getValue() + ? getString(R.string.rc_audio_call_on_going) + : getString(R.string.rc_video_call_on_going); + String action = getIntent().getAction(); + String title = getString(R.string.rc_call_on_going); + Intent intent = new Intent(this, CallForegroundService.class); + intent.putExtra("content", content); + intent.putExtra("action", action); + intent.putExtra("title", title); + Bundle bundle = new Bundle(); + onSaveFloatBoxState(bundle); + bundle.putBoolean("isDial", isDial); + intent.putExtra("floatbox", bundle); + if (VERSION.SDK_INT >= VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + } + + private void stopForegroundService() { + try { + stopService(new Intent(this, CallForegroundService.class)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + protected void onResume() { + super.onResume(); + stopForegroundService(); + RLog.d(TAG, "BaseCallActivity onResume"); + try { + RongCallSession session = RongCallClient.getInstance().getCallSession(); + if (session != null) { + if (session.getMediaType() == RongCallCommon.CallMediaType.VIDEO && !isMuteCamera) { + RongCallClient.getInstance().startCapture(); + } + RongCallProxy.getInstance().setCallListener(this); + if (shouldRestoreFloat) { + CallFloatBoxView.hideFloatBox(); + NotificationUtil.getInstance() + .clearNotification(this, BaseCallActivity.CALL_NOTIFICATION_ID); + CallRingingUtil.getInstance().stopServiceButContinueRinging(this); + } + time = getTime(session.getActiveTime()); + shouldRestoreFloat = true; + if (time > 0) { + CallKitUtils.shouldShowFloat = true; + } + if (checkingOverlaysPermission) { + checkDrawOverlaysPermission(false); + checkingOverlaysPermission = false; + } + } + } catch (Exception e) { + e.printStackTrace(); + RLog.d(TAG, "BaseCallActivity onResume Error : " + e.getMessage()); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + shouldRestoreFloat = false; + if (RongCallKit.getCustomerHandlerListener() != null) { + List selectedUserIds = + RongCallKit.getCustomerHandlerListener() + .handleActivityResult(requestCode, resultCode, data); + if (selectedUserIds != null && selectedUserIds.size() > 0) onAddMember(selectedUserIds); + } + } + + @Override + protected void onDestroy() { + try { + RLog.d(TAG, "BaseCallActivity onDestroy"); + RongUserInfoManager.getInstance().removeUserDataObserver(this); + // RongUserInfoManager.getInstance().remove + handler.removeCallbacks(updateTimeRunnable); + CallRingingUtil.getInstance().stopRinging(); + + // 退出此页面后应设置成正常模式,否则按下音量键无法更改其他音频类型的音量 + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + if (am != null) { + am.setMode(AudioManager.MODE_NORMAL); + if (onAudioFocusChangeListener != null) { + am.abandonAudioFocus(onAudioFocusChangeListener); + } + } + } catch (IllegalStateException e) { + e.printStackTrace(); + Log.i(MEDIAPLAYERTAG, "--- onDestroy IllegalStateException---"); + } + super.onDestroy(); + // unRegisterHeadsetplugReceiver(); + if (wakeLock != null && wakeLock.isHeld()) { + wakeLock.release(); + } + + if (screenLock != null && screenLock.isHeld()) { + try { + screenLock.setReferenceCounted(false); + screenLock.release(); + } catch (Exception e) { + + } + } + } + + @Override + public void onRemoteCameraDisabled(String userId, boolean disabled) {} + + @Override + public void onRemoteMicrophoneDisabled(String userId, boolean disabled) {} + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) {} + + @Override + public void onNetworkSendLost(int lossRate, int delay) {} + + @Override + public void onFirstRemoteVideoFrame(String userId, int height, int width) {} + + @Override + public void onFirstRemoteAudioFrame(String userId) {} + + @Override + public void onAudioLevelSend(String audioLevel) {} + + @Override + public void onAudioLevelReceive(HashMap audioLevel) {} + + private void toastDisconnectReason(RongCallCommon.CallDisconnectedReason reason) { + String text = null; + switch (reason) { + case CANCEL: + text = getString(R.string.rc_voip_mo_cancel); + break; + case REJECT: + text = getString(R.string.rc_voip_mo_reject); + break; + case NO_RESPONSE: + case BUSY_LINE: + text = getString(R.string.rc_voip_mo_no_response); + break; + case REMOTE_BUSY_LINE: + text = getString(R.string.rc_voip_mt_busy); + break; + case REMOTE_CANCEL: + text = getString(R.string.rc_voip_mt_cancel); + break; + case REMOTE_REJECT: + text = getString(R.string.rc_voip_mt_reject); + break; + case REMOTE_NO_RESPONSE: + text = getString(R.string.rc_voip_mt_no_response); + break; + case NETWORK_ERROR: + if (!CallKitUtils.isNetworkAvailable(this)) { + text = getString(R.string.rc_voip_call_network_error); + } else { + text = getString(R.string.rc_voip_call_terminalted); + } + break; + case REMOTE_HANGUP: + case HANGUP: + case INIT_VIDEO_ERROR: + text = getString(R.string.rc_voip_call_terminalted); + break; + case OTHER_DEVICE_HAD_ACCEPTED: + text = getString(R.string.rc_voip_call_other); + break; + } + if (text != null) { + showShortToast(text); + } + } + + public void onRemoteUserPublishVideoStream( + String userId, String streamId, String tag, SurfaceView surfaceView) {} + + @Override + public void onRemoteUserUnpublishVideoStream(String userId, String streamId, String tag) {} + + /** onStart时恢复浮窗 * */ + public void onRestoreFloatBox(Bundle bundle) { + isMuteCamera = bundle.getBoolean(EXTRA_BUNDLE_KEY_MUTECAMERA); + } + + protected void addMember(ArrayList currentMemberIds) { + // do your job to add more member + // after got your new member, call onAddMember + if (RongCallKit.getCustomerHandlerListener() != null) { + RongCallKit.getCustomerHandlerListener().addMember(this, currentMemberIds); + } + } + + protected void onAddMember(List newMemberIds) {} + + /** onPause时保存页面各状态数据 * */ + public String onSaveFloatBoxState(Bundle bundle) { + return null; + } + + @TargetApi(23) + boolean requestCallPermissions(RongCallCommon.CallMediaType type, int requestCode) { + // String[] permissions = null; + Log.i(TAG, "BaseActivty requestCallPermissions requestCode=" + requestCode); + // if (type.equals(RongCallCommon.CallMediaType.VIDEO) + // || type.equals(RongCallCommon.CallMediaType.AUDIO)) { + // permissions = CallKitUtils.getCallpermissions(); + // } + // boolean result = false; + // if (permissions != null) { + // boolean granted = CallKitUtils.checkPermissions(this, permissions); + // Log.i(TAG, "BaseActivty requestCallPermissions granted=" + granted); + // if (granted) { + // result = true; + // } else { + // PermissionCheckUtil.requestPermissions(this, permissions, requestCode); + // } + // } + + return RongCallPermissionUtil.checkAndRequestPermissionByCallType(this, type, requestCode); + } + + @Override + public void onUserUpdate(UserInfo info) {} + + @Override + public void onGroupUpdate(Group group) {} + + @Override + public void onGroupUserInfoUpdate(GroupUserInfo groupUserInfo) {} + + private class UpdateTimeRunnable implements Runnable { + private TextView timeView; + + public UpdateTimeRunnable(TextView timeView) { + this.timeView = timeView; + } + + @SuppressLint("DefaultLocale") + @Override + public void run() { + time++; + if (time >= 3600) { + timeView.setText( + String.format( + Locale.ROOT, + "%d:%02d:%02d", + time / 3600, + (time % 3600) / 60, + (time % 60))); + } else { + timeView.setText( + String.format(Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60))); + } + handler.postDelayed(this, 1000); + } + } + + void onMinimizeClick(View view) { + if (checkDrawOverlaysPermission(true)) { + finish(); + } else { + Toast.makeText( + this, + getString(R.string.rc_voip_float_window_not_allowed), + Toast.LENGTH_SHORT) + .show(); + } + } + + private boolean checkDrawOverlaysPermission(boolean needOpenPermissionSetting) { + if (RongCallPermissionUtil.checkFloatWindowPermission(this)) { + checkingOverlaysPermission = false; + return true; + } else { + if (needOpenPermissionSetting + && !checkingOverlaysPermission + && !notRemindRequestFloatWindowPermissionAgain) { + RongCallPermissionUtil.requestFloatWindowNeedPermission( + this, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (DialogInterface.BUTTON_POSITIVE == which) { + checkingOverlaysPermission = true; + } else if (DialogInterface.BUTTON_NEGATIVE == which) { + checkingOverlaysPermission = false; + } else if (DialogInterface.BUTTON_NEUTRAL == which) { + checkingOverlaysPermission = false; + notRemindRequestFloatWindowPermissionAgain = true; + } + } + }); + } + return false; + } + } + + private void createPowerManager() { + if (powerManager == null) { + powerManager = (PowerManager) getSystemService(POWER_SERVICE); + wakeLock = + powerManager.newWakeLock( + PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, + TAG); + wakeLock.setReferenceCounted(false); + screenLock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG); + screenLock.setReferenceCounted(false); + } + } + + protected void createPickupDetector() { + if (pickupDetector == null) { + pickupDetector = new PickupDetector(this); + } + } + + @Override + public void onPickupDetected(boolean isPickingUp) { + if (screenLock == null) { + RLog.d(TAG, "No PROXIMITY_SCREEN_OFF_WAKE_LOCK"); + return; + } + if (isPickingUp && !screenLock.isHeld()) { + screenLock.acquire(); + } + if (!isPickingUp && screenLock.isHeld()) { + try { + screenLock.setReferenceCounted(false); + screenLock.release(); + } catch (Exception e) { + + } + } + } + + @Override + public void onRequestPermissionsResult( + int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (!RongCallPermissionUtil.checkPermissions(this, permissions)) { + RongCallPermissionUtil.showRequestPermissionFailedAlter( + this, permissions, grantResults); + } + } + + /** outgoing (initView)incoming处注册 */ + public void regisHeadsetPlugReceiver() { + if (BluetoothUtil.isSupportBluetooth()) { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction("android.intent.action.HEADSET_PLUG"); + intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); + intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); + headsetPlugReceiver = new HeadsetPlugReceiver(); + registerReceiver( + headsetPlugReceiver, + intentFilter, + this.getApplicationInfo().packageName + ".permission.RONG_ACCESS_RECEIVER", + null); + } + } + + /** onHangupBtnClick onDestory 处解绑 */ + public void unRegisterHeadsetplugReceiver() { + if (headsetPlugReceiver != null) { + unregisterReceiver(headsetPlugReceiver); + headsetPlugReceiver = null; + } + } + + /** + * 设置开始音视频参数配置信息
+ * 必须在{@link RongCallClient#startCall} 和 {@link RongCallClient#acceptCall(String)}之前设置
+ */ + public void audioVideoConfig() { + // RongRTCConfig.Builder configBuilder = new RongRTCConfig.Builder(); + // configBuilder.setVideoResolution(RCRTCVideoResolution.RESOLUTION_480_640); + // configBuilder.setVideoFps(RCRTCVideoFps.Fps_15); + // configBuilder.setMaxRate(1000); + // configBuilder.setMinRate(350); + // /* + // * 设置建立 Https 连接时,是否使用自签证书。 + // * 公有云用户无需调用此方法,私有云用户使用自签证书时调用此方法设置 + // */ + // // configBuilder.enableHttpsSelfCertificate(true); + // RongCallClient.getInstance().setRTCConfig(configBuilder); + + Builder builder = + Builder.create() + .setVideoResolution(RCRTCVideoResolution.RESOLUTION_480_640) + .setVideoFps(RCRTCVideoFps.Fps_15) + .setMaxRate(1000) + .setMinRate(350); + RongCallClient instance = RongCallClient.getInstance(); + if (instance != null) { + instance.setVideoConfig(builder); + } + } + + protected void onHeadsetPlugUpdate(HeadsetInfo headsetInfo) {} + + public class HeadsetPlugReceiver extends BroadcastReceiver { + + private final String TAG = HeadsetPlugReceiver.class.getSimpleName(); + // 动态注册了监听有线耳机之后 默认会调用一次有限耳机拔出 + public boolean FIRST_HEADSET_PLUG_RECEIVER = false; + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + HeadsetInfo headsetInfo = null; + if ("android.intent.action.HEADSET_PLUG".equals(action)) { + int state = -1; + if (FIRST_HEADSET_PLUG_RECEIVER) { + if (intent.hasExtra("state")) { + state = intent.getIntExtra("state", -1); + } + if (state == 1) { + headsetInfo = new HeadsetInfo(true, HeadsetInfo.HeadsetType.WiredHeadset); + } else if (state == 0) { + headsetInfo = new HeadsetInfo(false, HeadsetInfo.HeadsetType.WiredHeadset); + } + } else { + FIRST_HEADSET_PLUG_RECEIVER = true; + } + } else if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { + int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); + switch (state) { + case BluetoothProfile.STATE_DISCONNECTED: + headsetInfo = new HeadsetInfo(false, HeadsetInfo.HeadsetType.BluetoothA2dp); + break; + case BluetoothProfile.STATE_CONNECTED: + headsetInfo = new HeadsetInfo(true, HeadsetInfo.HeadsetType.BluetoothA2dp); + break; + } + } + if (null != headsetInfo) { // onHandFreeButtonClick + onHeadsetPlugUpdate(headsetInfo); + } else { + FinLog.e(TAG, "HeadsetPlugReceiver headsetInfo=null !"); + } + } + } + // +} diff --git a/callkit/src/main/java/io/rong/callkit/BaseNoActionBarActivity.java b/callkit/src/main/java/io/rong/callkit/BaseNoActionBarActivity.java new file mode 100644 index 000000000..efe0f6791 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/BaseNoActionBarActivity.java @@ -0,0 +1,14 @@ +package io.rong.callkit; + +import android.app.Activity; +import android.content.Context; +import io.rong.imkit.utils.language.RongConfigurationManager; + +public class BaseNoActionBarActivity extends Activity { + @Override + protected void attachBaseContext(Context newBase) { + Context newContext = + RongConfigurationManager.getInstance().getConfigurationContext(newBase); + super.attachBaseContext(newContext); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallEndMessageItemProvider.java b/callkit/src/main/java/io/rong/callkit/CallEndMessageItemProvider.java new file mode 100644 index 000000000..bbc31f32c --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallEndMessageItemProvider.java @@ -0,0 +1,248 @@ +package io.rong.callkit; + +import static io.rong.calllib.RongCallCommon.CallDisconnectedReason.HANGUP; +import static io.rong.calllib.RongCallCommon.CallDisconnectedReason.OTHER_DEVICE_HAD_ACCEPTED; + +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; +import io.rong.callkit.util.CallKitUtils; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.message.CallSTerminateMessage; +import io.rong.imkit.conversation.messgelist.provider.BaseMessageItemProvider; +import io.rong.imkit.model.UiMessage; +import io.rong.imkit.widget.adapter.IViewProviderListener; +import io.rong.imkit.widget.adapter.ViewHolder; +import io.rong.imlib.model.Message; +import io.rong.imlib.model.MessageContent; +import java.util.List; +import java.util.Locale; + +public class CallEndMessageItemProvider extends BaseMessageItemProvider { + @Override + protected io.rong.imkit.widget.adapter.ViewHolder onCreateMessageContentViewHolder( + ViewGroup parent, int viewType) { + View textView = + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.rc_text_message_item, parent, false); + return new ViewHolder(parent.getContext(), textView); + } + + @Override + protected void bindMessageContentViewHolder( + ViewHolder holder, + ViewHolder parentHolder, + CallSTerminateMessage callSTerminateMessage, + UiMessage uiMessage, + int position, + List list, + IViewProviderListener listener) { + Message message = uiMessage.getMessage(); + final TextView view = holder.getView(io.rong.imkit.R.id.rc_text); + if (message.getMessageDirection() == Message.MessageDirection.SEND) { + view.setBackgroundResource(R.drawable.rc_ic_bubble_right); + } else { + view.setBackgroundResource(R.drawable.rc_ic_bubble_left); + } + + RongCallCommon.CallMediaType mediaType = callSTerminateMessage.getMediaType(); + String direction = callSTerminateMessage.getDirection(); + Drawable drawable = null; + + String msgContent = ""; + switch (callSTerminateMessage.getReason()) { + case CANCEL: + msgContent = view.getResources().getString(R.string.rc_voip_mo_cancel); + break; + case REJECT: + msgContent = view.getResources().getString(R.string.rc_voip_mo_reject); + break; + case NO_RESPONSE: + case BUSY_LINE: + msgContent = view.getResources().getString(R.string.rc_voip_mo_no_response); + break; + case REMOTE_BUSY_LINE: + msgContent = view.getResources().getString(R.string.rc_voip_mt_busy); + break; + case REMOTE_CANCEL: + msgContent = view.getResources().getString(R.string.rc_voip_mt_cancel); + break; + case REMOTE_REJECT: + msgContent = view.getResources().getString(R.string.rc_voip_mt_reject); + break; + case REMOTE_NO_RESPONSE: + msgContent = view.getResources().getString(R.string.rc_voip_mt_no_response); + break; + case NETWORK_ERROR: + case REMOTE_NETWORK_ERROR: + case INIT_VIDEO_ERROR: + msgContent = view.getResources().getString(R.string.rc_voip_call_interrupt); + break; + case OTHER_DEVICE_HAD_ACCEPTED: + msgContent = view.getResources().getString(R.string.rc_voip_call_other); + break; + case SERVICE_NOT_OPENED: + case REMOTE_ENGINE_UNSUPPORTED: + msgContent = view.getResources().getString(R.string.rc_voip_engine_notfound); + break; + case REJECTED_BY_BLACKLIST: + msgContent = + view.getResources().getString(R.string.rc_voip_mo_rejected_by_blocklist); + break; + default: + String mo_reject = view.getResources().getString(R.string.rc_voip_mo_reject); + String mt_reject = view.getResources().getString(R.string.rc_voip_mt_reject); + String extra = callSTerminateMessage.getExtra(); + String timeRegex = "([0-9]?[0-9]:)?([0-5][0-9]:)?([0-5][0-9])$"; + if (!TextUtils.isEmpty(extra)) { + boolean val = extra.matches(timeRegex); + if (val) { + msgContent = + view.getResources().getString(R.string.rc_voip_call_time_length); + msgContent += extra; + } else { + msgContent = + view.getResources().getString(R.string.rc_voip_call_time_length); + } + } else { + msgContent = + callSTerminateMessage.getReason() == HANGUP ? mo_reject : mt_reject; + } + break; + } + + view.setText(msgContent); + view.setCompoundDrawablePadding(15); + + if (mediaType.equals(RongCallCommon.CallMediaType.VIDEO)) { + if (direction != null && direction.equals("MO")) { + drawable = view.getResources().getDrawable(R.drawable.rc_voip_video_right); + drawable.setBounds( + 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + view.setCompoundDrawablesRelative(null, null, drawable, null); + view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_right)); + } else { + drawable = view.getResources().getDrawable(R.drawable.rc_voip_video_left); + drawable.setBounds( + 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + view.setCompoundDrawablesRelative(drawable, null, null, null); + view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_left)); + } + } else { + if (direction != null && direction.equals("MO")) { + if (callSTerminateMessage.getReason().equals(HANGUP) + || callSTerminateMessage + .getReason() + .equals(RongCallCommon.CallDisconnectedReason.REMOTE_HANGUP)) { + drawable = + view.getResources() + .getDrawable(R.drawable.rc_voip_audio_right_connected); + } else { + drawable = + view.getResources().getDrawable(R.drawable.rc_voip_audio_right_cancel); + } + drawable.setBounds( + 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + view.setCompoundDrawablesRelative(null, null, drawable, null); + view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_right)); + } else { + if (callSTerminateMessage.getReason().equals(HANGUP) + || callSTerminateMessage + .getReason() + .equals(RongCallCommon.CallDisconnectedReason.REMOTE_HANGUP)) { + drawable = + view.getResources() + .getDrawable(R.drawable.rc_voip_audio_left_connected); + } else { + drawable = + view.getResources().getDrawable(R.drawable.rc_voip_audio_left_cancel); + } + drawable.setBounds( + 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + view.setCompoundDrawablesRelative(drawable, null, null, null); + view.setTextColor(view.getResources().getColor(R.color.rc_voip_color_left)); + } + } + } + + @Override + protected boolean onItemClick( + ViewHolder holder, + CallSTerminateMessage callSTerminateMessage, + UiMessage uiMessage, + int position, + List list, + IViewProviderListener listener) { + if (callSTerminateMessage.getReason() == OTHER_DEVICE_HAD_ACCEPTED) { + return true; + } + Context context = holder.getContext(); + RongCallSession profile = RongCallClient.getInstance().getCallSession(); + if (profile != null && profile.getActiveTime() > 0) { + if (profile.getMediaType() == RongCallCommon.CallMediaType.AUDIO) { + Toast.makeText( + context, + context.getString(R.string.rc_voip_call_audio_start_fail), + Toast.LENGTH_SHORT) + .show(); + } else { + Toast.makeText( + context, + context.getString(R.string.rc_voip_call_video_start_fail), + Toast.LENGTH_SHORT) + .show(); + } + return true; + } + if (!CallKitUtils.isNetworkAvailable(context)) { + Toast.makeText( + context, + context.getString(R.string.rc_voip_call_network_error), + Toast.LENGTH_SHORT) + .show(); + return true; + } + RongCallCommon.CallMediaType mediaType = callSTerminateMessage.getMediaType(); + String action = null; + if (mediaType.equals(RongCallCommon.CallMediaType.VIDEO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEVIDEO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO; + } + Intent intent = new Intent(action); + intent.setPackage(context.getPackageName()); + intent.putExtra( + "conversationType", + uiMessage.getMessage().getConversationType().getName().toLowerCase(Locale.US)); + intent.putExtra("targetId", uiMessage.getMessage().getTargetId()); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + context.startActivity(intent); + return true; + } + + @Override + protected boolean isMessageViewType(MessageContent messageContent) { + return messageContent instanceof CallSTerminateMessage; + } + + @Override + public Spannable getSummarySpannable( + Context context, CallSTerminateMessage callSTerminateMessage) { + RongCallCommon.CallMediaType mediaType = callSTerminateMessage.getMediaType(); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + return new SpannableString(context.getString(R.string.rc_voip_message_audio)); + } else { + return new SpannableString(context.getString(R.string.rc_voip_message_video)); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallFloatBoxView.java b/callkit/src/main/java/io/rong/callkit/CallFloatBoxView.java new file mode 100644 index 000000000..683cc1061 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallFloatBoxView.java @@ -0,0 +1,1216 @@ +package io.rong.callkit; + +import static io.rong.callkit.util.CallKitUtils.isDial; + +import android.app.ActivityManager; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.graphics.PixelFormat; +import android.media.AudioManager; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.text.TextUtils; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; +import io.rong.callkit.util.ActivityStartCheckUtils; +import io.rong.callkit.util.CallKitUtils; +import io.rong.calllib.CallUserProfile; +import io.rong.calllib.IRongCallListener; +import io.rong.calllib.ReportUtil; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallCommon.CallMediaType; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.message.CallSTerminateMessage; +import io.rong.common.RLog; +import io.rong.imkit.IMCenter; +import io.rong.imkit.manager.AudioPlayManager; +import io.rong.imkit.notification.NotificationUtil; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import io.rong.message.InformationNotificationMessage; +import java.util.HashMap; +import java.util.Locale; +import java.util.Timer; +import java.util.TimerTask; + +/** Created by weiqinxiao on 16/3/17. */ +public class CallFloatBoxView { + private static Context mContext; + private static Timer timer; + private static long mTime; + private static View mView; + private static Boolean isShown = false; + private static WindowManager wm; + private static Bundle mBundle; + private static final String TAG = "CallFloatBoxView"; + private static TextView showFBCallTime = null; + private static FrameLayout remoteVideoContainer = null; + private static boolean activityResuming = false; + + public static void showFB(Context context, Bundle bundle) { + Log.i("audioTag", "CallKitUtils.isDial=" + CallKitUtils.isDial); + setExcludeFromRecents(context, true); + activityResuming = false; + if (CallKitUtils.isDial) { + CallFloatBoxView.showFloatBoxToCall(context, bundle); + } else { + CallFloatBoxView.showFloatBox(context, bundle); + } + } + + public static void showFloatBox(Context context, Bundle bundle) { + if (isShown) { + return; + } + mContext = context; + isShown = true; + RongCallSession session = RongCallClient.getInstance().getCallSession(); + long activeTime = session != null ? session.getActiveTime() : 0; + mTime = activeTime == 0 ? 0 : (System.currentTimeMillis() - activeTime) / 1000; + if (mTime > 0) { + setAudioMode(AudioManager.MODE_IN_COMMUNICATION); + } + mBundle = bundle; + wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + WindowManager.LayoutParams params = createLayoutParams(context); + RongCallCommon.CallMediaType mediaType = + RongCallCommon.CallMediaType.valueOf(bundle.getInt("mediaType")); + if (mediaType == RongCallCommon.CallMediaType.VIDEO + && session != null + && session.getConversationType() == Conversation.ConversationType.PRIVATE) { + SurfaceView remoteVideo = null; + for (CallUserProfile profile : session.getParticipantProfileList()) { + if (!TextUtils.equals( + profile.getUserId(), RongIMClient.getInstance().getCurrentUserId())) { + remoteVideo = profile.getVideoView(); + } + } + if (remoteVideo != null) { + ViewGroup parent = (ViewGroup) remoteVideo.getParent(); + if (parent != null) { + parent.removeView(remoteVideo); + } + Resources resources = mContext.getResources(); + params.width = resources.getDimensionPixelSize(R.dimen.callkit_dimen_size_60); + params.height = resources.getDimensionPixelSize(R.dimen.callkit_dimen_size_80); + remoteVideoContainer = new FrameLayout(mContext); + remoteVideoContainer.addView( + remoteVideo, + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + remoteVideoContainer.setOnTouchListener(createTouchListener()); + wm.addView(remoteVideoContainer, params); + } + } + if (remoteVideoContainer == null) { + mView = LayoutInflater.from(context).inflate(R.layout.rc_voip_float_box, null); + mView.setOnTouchListener(createTouchListener()); + wm.addView(mView, params); + TextView timeV = (TextView) mView.findViewById(R.id.rc_time); + setupTime(timeV); + ImageView mediaIconV = (ImageView) mView.findViewById(R.id.rc_voip_media_type); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + mediaIconV.setImageResource(R.drawable.rc_voip_float_audio); + } else { + mediaIconV.setImageResource(R.drawable.rc_voip_float_video); + } + } else { + // 视频悬浮窗下,不需要UI显示时间,但是时间值也需要同步更新 + setupTime(null); + } + RongCallClient.getInstance() + .setVoIPCallListener( + new IRongCallListener() { + @Override + public void onCallIncoming( + RongCallSession callSession, SurfaceView localVideo) {} + + @Override + public void onCallOutgoing( + RongCallSession callInfo, SurfaceView localVideo) {} + + @Override + public void onRemoteUserRinging(String userId) {} + + @Override + public void onRemoteUserAccept( + String userId, CallMediaType mediaType) {} + + @Override + public void onCallDisconnected( + RongCallSession callProfile, + RongCallCommon.CallDisconnectedReason reason) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callProfile, + "state|reason|desc", + "onCallDisconnected", + reason.getValue(), + TAG); + stopForegroundService(mContext); + setExcludeFromRecents(mContext, false); + String senderId; + String extra = ""; + senderId = callProfile.getInviterUserId(); + long activeTime = callProfile.getActiveTime(); + long tmpTime = + activeTime == 0 + ? 0 + : (System.currentTimeMillis() - activeTime) / 1000; + mTime = tmpTime == 0 ? mTime : tmpTime; + if (mTime >= 3600) { + extra = + String.format( + Locale.ROOT, + "%d:%02d:%02d", + mTime / 3600, + (mTime % 3600) / 60, + (mTime % 60)); + } else { + extra = + String.format( + Locale.ROOT, + "%02d:%02d", + (mTime % 3600) / 60, + (mTime % 60)); + } + if (!TextUtils.isEmpty(senderId)) { + switch (callProfile.getConversationType()) { + case PRIVATE: + CallSTerminateMessage callSTerminateMessage = + new CallSTerminateMessage(); + callSTerminateMessage.setReason(reason); + callSTerminateMessage.setMediaType( + callProfile.getMediaType()); + callSTerminateMessage.setExtra(extra); + long serverTime = + System.currentTimeMillis() + - RongIMClient.getInstance() + .getDeltaTime(); + if (senderId.equals(callProfile.getSelfUserId())) { + callSTerminateMessage.setDirection("MO"); + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType + .PRIVATE, + callProfile.getTargetId(), + io.rong.imlib.model.Message + .SentStatus.SENT, + callSTerminateMessage, + serverTime, + null); + } else { + callSTerminateMessage.setDirection("MT"); + io.rong.imlib.model.Message.ReceivedStatus + receivedStatus = + new io.rong.imlib.model.Message + .ReceivedStatus(0); + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType + .PRIVATE, + callProfile.getTargetId(), + senderId, + receivedStatus, + callSTerminateMessage, + serverTime, + null); + } + break; + case GROUP: + InformationNotificationMessage + informationNotificationMessage; + serverTime = + System.currentTimeMillis() + - RongIMClient.getInstance() + .getDeltaTime(); + if (reason.equals( + RongCallCommon.CallDisconnectedReason + .NO_RESPONSE)) { + informationNotificationMessage = + InformationNotificationMessage.obtain( + mContext.getString( + R.string + .rc_voip_audio_no_response)); + } else { + informationNotificationMessage = + InformationNotificationMessage.obtain( + mContext.getString( + R.string + .rc_voip_audio_ended)); + } + + if (senderId.equals(callProfile.getSelfUserId())) { + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType.GROUP, + callProfile.getTargetId(), + io.rong.imlib.model.Message + .SentStatus.SENT, + informationNotificationMessage, + serverTime, + null); + } else { + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType.GROUP, + callProfile.getTargetId(), + senderId, + CallKitUtils.getReceivedStatus( + reason), + informationNotificationMessage, + serverTime, + null); + } + break; + default: + break; + } + } + Toast.makeText( + mContext, + mContext.getString( + R.string.rc_voip_call_terminalted), + Toast.LENGTH_SHORT) + .show(); + + if (wm != null && mView != null && mView.isAttachedToWindow()) { + wm.removeView(mView); + mView = null; + } + if (wm != null + && remoteVideoContainer != null + && remoteVideoContainer.isAttachedToWindow()) { + wm.removeView(remoteVideoContainer); + remoteVideoContainer.setOnTouchListener(null); + remoteVideoContainer = null; + } + if (timer != null) { + timer.cancel(); + timer = null; + } + isShown = false; + mTime = 0; + setAudioMode(AudioManager.MODE_NORMAL); + AudioPlayManager.getInstance().setInVoipMode(false); + NotificationUtil.getInstance() + .clearNotification( + mContext, BaseCallActivity.CALL_NOTIFICATION_ID); + RongCallClient.getInstance() + .setVoIPCallListener(RongCallProxy.getInstance()); + } + + @Override + public void onRemoteUserJoined( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + CallKitUtils.isDial = false; + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserJoined", + TAG); + } + + @Override + public void onRemoteUserInvited( + String userId, RongCallCommon.CallMediaType mediaType) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserInvited", + TAG); + } + + @Override + public void onRemoteUserLeft( + String userId, RongCallCommon.CallDisconnectedReason reason) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserLeft", + TAG); + } + + @Override + public void onMediaTypeChanged( + String userId, + RongCallCommon.CallMediaType mediaType, + SurfaceView video) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + RongCallClient.getInstance().getCallSession(), + "state|desc", + "onMediaTypeChanged", + TAG); + if (mContext == null || !isShown || wm == null) { + Log.e( + TAG, + "set onMediaTypeChanged Failed CallFloatBoxView is Hiden"); + return; + } + WindowManager.LayoutParams params = createLayoutParams(mContext); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + if (remoteVideoContainer != null) { + wm.removeView(remoteVideoContainer); + remoteVideoContainer = null; + } + if (mView == null) { + mView = + LayoutInflater.from(mContext) + .inflate(R.layout.rc_voip_float_box, null); + mView.setOnTouchListener(createTouchListener()); + wm.addView(mView, params); + TextView timeV = + (TextView) mView.findViewById(R.id.rc_time); + setupTime(timeV); + ImageView mediaIconV = + (ImageView) + mView.findViewById(R.id.rc_voip_media_type); + mediaIconV.setImageResource(R.drawable.rc_voip_float_audio); + } + } else if (RongCallClient.getInstance().getCallSession() != null) { + RongCallSession callSession = + RongCallClient.getInstance().getCallSession(); + if (callSession.getConversationType() + == Conversation.ConversationType.PRIVATE) { + if (mView != null) { + wm.removeView(mView); + mView = null; + } + SurfaceView remoteVideo = null; + for (CallUserProfile profile : + callSession.getParticipantProfileList()) { + if (!TextUtils.equals( + profile.getUserId(), + RongIMClient.getInstance() + .getCurrentUserId())) { + remoteVideo = profile.getVideoView(); + } + } + if (remoteVideo != null) { + ViewGroup parent = (ViewGroup) remoteVideo.getParent(); + if (parent != null) parent.removeView(remoteVideo); + Resources resources = mContext.getResources(); + params.width = + resources.getDimensionPixelSize( + R.dimen.callkit_dimen_size_60); + params.height = + resources.getDimensionPixelSize( + R.dimen.callkit_dimen_size_80); + remoteVideoContainer = new FrameLayout(mContext); + remoteVideoContainer.addView( + remoteVideo, + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + remoteVideoContainer.setOnTouchListener( + createTouchListener()); + wm.addView(remoteVideoContainer, params); + } + } else if (mView != null) { + ImageView mediaIconV = + (ImageView) + mView.findViewById(R.id.rc_voip_media_type); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + mediaIconV.setImageResource( + R.drawable.rc_voip_float_audio); + } else { + mediaIconV.setImageResource( + R.drawable.rc_voip_float_video); + } + } + } + } + + @Override + public void onError(RongCallCommon.CallErrorCode errorCode) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + RongCallClient.getInstance().getCallSession(), + "code|state|desc", + errorCode.getValue(), + "onError", + TAG); + setAudioMode(AudioManager.MODE_NORMAL); + AudioPlayManager.getInstance().setInVoipMode(false); + } + + @Override + public void onCallConnected( + RongCallSession callInfo, SurfaceView localVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callInfo, + "state|desc", + "onCallConnected", + TAG); + CallKitUtils.isDial = false; + setAudioMode(AudioManager.MODE_IN_COMMUNICATION); + AudioPlayManager.getInstance().setInVoipMode(true); + } + + @Override + public void onRemoteCameraDisabled(String userId, boolean disabled) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|disabled|desc", + userId, + "onRemoteCameraDisabled", + disabled, + TAG); + } + + @Override + public void onRemoteMicrophoneDisabled( + String userId, boolean disabled) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|disabled|desc", + userId, + "onRemoteMicrophoneDisabled", + disabled, + TAG); + } + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) {} + + @Override + public void onNetworkSendLost(int lossRate, int delay) {} + + @Override + public void onFirstRemoteVideoFrame( + String userId, int height, int width) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onFirstRemoteVideoFrame", + TAG); + } + + @Override + public void onFirstRemoteAudioFrame(String userId) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onFirstRemoteAudioFrame", + TAG); + } + + @Override + public void onAudioLevelSend(String audioLevel) {} + + public void onRemoteUserPublishVideoStream( + String userId, + String streamId, + String tag, + SurfaceView surfaceView) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|streamId|desc", + userId, + "onRemoteUserPublishVideoStream", + streamId, + TAG); + } + + @Override + public void onAudioLevelReceive(HashMap audioLevel) {} + + public void onRemoteUserUnpublishVideoStream( + String userId, String streamId, String tag) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|streamId|desc", + userId, + "onRemoteUserUnpublishVideoStream", + streamId, + TAG); + } + }); + } + + private static void stopForegroundService(Context context) { + if (context == null) { + return; + } + try { + context.stopService(new Intent(context, CallForegroundService.class)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static WindowManager.LayoutParams createLayoutParams(Context context) { + WindowManager.LayoutParams params = new WindowManager.LayoutParams(); + + int type; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < 24) { + type = WindowManager.LayoutParams.TYPE_TOAST; + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + } else { + type = WindowManager.LayoutParams.TYPE_PHONE; + } + params.type = type; + params.flags = + WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + params.format = PixelFormat.TRANSLUCENT; + params.width = ViewGroup.LayoutParams.WRAP_CONTENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + params.gravity = Gravity.END | Gravity.CENTER_VERTICAL; + return params; + } + + private static View.OnTouchListener createTouchListener() { + return new View.OnTouchListener() { + float lastX, lastY; + int oldOffsetX, oldOffsetY; + int tag = 0; + + @Override + public boolean onTouch(View v, MotionEvent event) { + final int action = event.getAction(); + float x = event.getX(); + float y = event.getY(); + WindowManager.LayoutParams params = + (WindowManager.LayoutParams) v.getLayoutParams(); + if (params == null) { + return true; + } + if (tag == 0) { + oldOffsetX = params.x; + oldOffsetY = params.y; + } + if (action == MotionEvent.ACTION_DOWN) { + lastX = x; + lastY = y; + } else if (action == MotionEvent.ACTION_MOVE) { + // 减小偏移量,防止过度抖动 + params.x += (int) (x - lastX) / 3; + params.y += (int) (y - lastY) / 3; + tag = 1; + // if (mView != null) + // wm.updateViewLayout(mView, params); + // if (remoteVideoContainer != null) { + // wm.updateViewLayout(remoteVideoContainer, params); + // } + wm.updateViewLayout(v, params); + } else if (action == MotionEvent.ACTION_UP) { + int newOffsetX = params.x; + int newOffsetY = params.y; + if (Math.abs(oldOffsetX - newOffsetX) <= 20 + && Math.abs(oldOffsetY - newOffsetY) <= 20) { + if (!CallKitUtils.isFastDoubleClick()) { + onClickToResume(); + } + } else { + tag = 0; + } + } + return true; + } + }; + } + + public static void showFloatBoxToCall(Context context, Bundle bundle) { + if (isShown) { + return; + } + mContext = context; + isShown = true; + + mBundle = bundle; + wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + final WindowManager.LayoutParams params = createLayoutParams(context); + + mView = LayoutInflater.from(context).inflate(R.layout.rc_voip_float_box, null); + mView.setOnTouchListener( + new View.OnTouchListener() { + float lastX, lastY; + int oldOffsetX, oldOffsetY; + int tag = 0; + + @Override + public boolean onTouch(View v, MotionEvent event) { + final int action = event.getAction(); + float x = event.getX(); + float y = event.getY(); + if (tag == 0) { + oldOffsetX = params.x; + oldOffsetY = params.y; + } + if (action == MotionEvent.ACTION_DOWN) { + lastX = x; + lastY = y; + } else if (action == MotionEvent.ACTION_MOVE) { + // 减小偏移量,防止过度抖动 + params.x += (int) (x - lastX) / 3; + params.y += (int) (y - lastY) / 3; + tag = 1; + if (mView != null) wm.updateViewLayout(mView, params); + } else if (action == MotionEvent.ACTION_UP) { + int newOffsetX = params.x; + int newOffsetY = params.y; + if (Math.abs(oldOffsetX - newOffsetX) <= 20 + && Math.abs(oldOffsetY - newOffsetY) <= 20) { + if (!CallKitUtils.isFastDoubleClick()) { + onClickToResume(); + } + } else { + tag = 0; + } + } + return true; + } + }); + wm.addView(mView, params); + showFBCallTime = (TextView) mView.findViewById(R.id.rc_time); + showFBCallTime.setVisibility(View.GONE); + + ImageView mediaIconV = (ImageView) mView.findViewById(R.id.rc_voip_media_type); + RongCallCommon.CallMediaType mediaType = + RongCallCommon.CallMediaType.valueOf(bundle.getInt("mediaType")); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + mediaIconV.setImageResource(R.drawable.rc_voip_float_audio); + } else { + mediaIconV.setImageResource(R.drawable.rc_voip_float_video); + } + RongCallClient.getInstance() + .setVoIPCallListener( + new IRongCallListener() { + @Override + public void onCallIncoming( + RongCallSession callSession, SurfaceView localVideo) {} + + @Override + public void onCallOutgoing( + RongCallSession callInfo, SurfaceView localVideo) {} + + @Override + public void onRemoteUserRinging(String userId) {} + + @Override + public void onRemoteUserAccept( + String userId, CallMediaType mediaType) {} + + @Override + public void onCallDisconnected( + RongCallSession callProfile, + RongCallCommon.CallDisconnectedReason reason) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callProfile, + "state|reason|desc", + "onCallDisconnected", + reason.getValue(), + TAG); + stopForegroundService(mContext); + setExcludeFromRecents(mContext, false); + String senderId; + String extra = ""; + senderId = callProfile.getInviterUserId(); + long activeTime = callProfile.getActiveTime(); + long tmpTime = + activeTime == 0 + ? 0 + : (System.currentTimeMillis() - activeTime) / 1000; + mTime = tmpTime == 0 ? mTime : tmpTime; + if (mTime >= 3600) { + extra = + String.format( + Locale.ROOT, + "%d:%02d:%02d", + mTime / 3600, + (mTime % 3600) / 60, + (mTime % 60)); + } else { + extra = + String.format( + Locale.ROOT, + "%02d:%02d", + (mTime % 3600) / 60, + (mTime % 60)); + } + if (!TextUtils.isEmpty(senderId)) { + switch (callProfile.getConversationType()) { + case PRIVATE: + CallSTerminateMessage callSTerminateMessage = + new CallSTerminateMessage(); + callSTerminateMessage.setReason(reason); + callSTerminateMessage.setMediaType( + callProfile.getMediaType()); + callSTerminateMessage.setExtra(extra); + if (senderId.equals(callProfile.getSelfUserId())) { + callSTerminateMessage.setDirection("MO"); + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType + .PRIVATE, + callProfile.getTargetId(), + io.rong.imlib.model.Message + .SentStatus.SENT, + callSTerminateMessage, + null); + } else { + callSTerminateMessage.setDirection("MT"); + io.rong.imlib.model.Message.ReceivedStatus + receivedStatus = + new io.rong.imlib.model.Message + .ReceivedStatus(0); + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType + .PRIVATE, + callProfile.getTargetId(), + senderId, + receivedStatus, + callSTerminateMessage, + null); + } + break; + case GROUP: + InformationNotificationMessage + informationNotificationMessage; + if (reason.equals( + RongCallCommon.CallDisconnectedReason + .NO_RESPONSE)) { + informationNotificationMessage = + InformationNotificationMessage.obtain( + mContext.getString( + R.string + .rc_voip_audio_no_response)); + } else { + informationNotificationMessage = + InformationNotificationMessage.obtain( + mContext.getString( + R.string + .rc_voip_audio_ended)); + } + + if (senderId.equals(callProfile.getSelfUserId())) { + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType.GROUP, + callProfile.getTargetId(), + io.rong.imlib.model.Message + .SentStatus.SENT, + informationNotificationMessage, + null); + } else { + io.rong.imlib.model.Message.ReceivedStatus + receivedStatus = + new io.rong.imlib.model.Message + .ReceivedStatus(0); + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType.GROUP, + callProfile.getTargetId(), + senderId, + receivedStatus, + informationNotificationMessage, + null); + } + break; + default: + break; + } + } + Toast.makeText( + mContext, + mContext.getString( + R.string.rc_voip_call_terminalted), + Toast.LENGTH_SHORT) + .show(); + + if (wm != null && mView != null) { + wm.removeView(mView); + if (null != timer) { + timer.cancel(); + timer = null; + } + isShown = false; + mView = null; + mTime = 0; + } + setAudioMode(AudioManager.MODE_NORMAL); + AudioPlayManager.getInstance().setInVoipMode(false); + NotificationUtil.getInstance() + .clearNotification( + mContext, BaseCallActivity.CALL_NOTIFICATION_ID); + RongCallClient.getInstance() + .setVoIPCallListener(RongCallProxy.getInstance()); + } + + @Override + public void onRemoteUserLeft( + String userId, RongCallCommon.CallDisconnectedReason reason) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserLeft", + TAG); + } + + @Override + public void onMediaTypeChanged( + String userId, + RongCallCommon.CallMediaType mediaType, + SurfaceView video) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + RongCallClient.getInstance().getCallSession(), + "state|desc", + "onMediaTypeChanged", + TAG); + ImageView mediaIconV = + (ImageView) mView.findViewById(R.id.rc_voip_media_type); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + mediaIconV.setImageResource(R.drawable.rc_voip_float_audio); + } else { + mediaIconV.setImageResource(R.drawable.rc_voip_float_video); + } + } + + @Override + public void onError(RongCallCommon.CallErrorCode errorCode) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + RongCallClient.getInstance().getCallSession(), + "code|state|desc", + errorCode.getValue(), + "onError", + TAG); + setAudioMode(AudioManager.MODE_NORMAL); + AudioPlayManager.getInstance().setInVoipMode(false); + } + + @Override + public void onCallConnected( + RongCallSession callInfo, SurfaceView localVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callInfo, + "state|desc", + "onCallConnected", + TAG); + if (CallKitUtils.isDial && isShown) { + CallFloatBoxView.showFloatBoxToCallTime(); + CallKitUtils.isDial = false; + } + AudioPlayManager.getInstance().setInVoipMode(true); + setAudioMode(AudioManager.MODE_IN_COMMUNICATION); + } + + @Override + public void onRemoteUserJoined( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserJoined", + TAG); + if (CallKitUtils.isDial && isShown) { + CallFloatBoxView.showFloatBoxToCallTime(); + CallKitUtils.isDial = false; + } + } + + @Override + public void onRemoteUserInvited( + String userId, RongCallCommon.CallMediaType mediaType) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserInvited", + TAG); + } + + @Override + public void onRemoteCameraDisabled(String userId, boolean disabled) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|disabled|desc", + userId, + "onRemoteCameraDisabled", + disabled, + TAG); + } + + @Override + public void onRemoteMicrophoneDisabled( + String userId, boolean disabled) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|disabled|desc", + userId, + "onRemoteMicrophoneDisabled", + disabled, + TAG); + } + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) {} + + @Override + public void onNetworkSendLost(int lossRate, int delay) {} + + @Override + public void onFirstRemoteVideoFrame( + String userId, int height, int width) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onFirstRemoteVideoFrame", + TAG); + } + + @Override + public void onFirstRemoteAudioFrame(String userId) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onFirstRemoteAudioFrame", + TAG); + } + + @Override + public void onAudioLevelSend(String audioLevel) {} + + public void onRemoteUserPublishVideoStream( + String userId, + String streamId, + String tag, + SurfaceView surfaceView) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|streamId|desc", + userId, + "onRemoteUserPublishVideoStream", + streamId, + TAG); + } + + @Override + public void onAudioLevelReceive(HashMap audioLevel) {} + + public void onRemoteUserUnpublishVideoStream( + String userId, String streamId, String tag) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|streamId|desc", + userId, + "onRemoteUserUnpublishVideoStream", + streamId, + TAG); + } + }); + } + + /** * 调用showFloatBoxToCall 之后 调用该方法设置 */ + public static void showFloatBoxToCallTime() { + if (!isShown) { + return; + } + RongCallSession session = RongCallClient.getInstance().getCallSession(); + long activeTime = session != null ? session.getActiveTime() : 0; + mTime = activeTime == 0 ? 0 : (System.currentTimeMillis() - activeTime) / 1000; + // mView = LayoutInflater.from(context).inflate(R.layout.rc_voip_float_box, null); + // TextView timeV = (TextView) mView.findViewById(R.id.rc_time); + if (null != showFBCallTime) { + setupTime(showFBCallTime); + } + } + + public static void hideFloatBox() { + setExcludeFromRecents(mContext, false); + RongCallClient.getInstance().setVoIPCallListener(RongCallProxy.getInstance()); + if (isShown) { + if (mView != null) { + wm.removeView(mView); + } + mView = null; + if (remoteVideoContainer != null) { + wm.removeView(remoteVideoContainer); + } + remoteVideoContainer = null; + if (null != timer) { + timer.cancel(); + timer = null; + } + isShown = false; + mView = null; + mTime = 0; + mBundle = null; + showFBCallTime = null; + } + } + + public static Intent getResumeIntent() { + if (mBundle == null) { + return null; + } + mBundle.putBoolean("isDial", isDial); + RongCallClient.getInstance().setVoIPCallListener(RongCallProxy.getInstance()); + Intent intent = new Intent(mBundle.getString("action")); + intent.putExtra("floatbox", mBundle); + intent.setPackage(mContext.getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra("callAction", RongCallAction.ACTION_RESUME_CALL.getName()); + + return intent; + } + + public static void onClickToResume() { + // 当快速双击悬浮窗时,第一次点击之后会把mBundle置为空,第二次点击的时候出现NPE + if (mBundle == null) { + RLog.d(TAG, "onClickToResume mBundle is null"); + return; + } + if (activityResuming) { + return; + } + activityResuming = true; + boolean muteCamera = mBundle.getBoolean("muteCamera"); + if (mBundle.getInt("mediaType") == RongCallCommon.CallMediaType.VIDEO.getValue() + && !isDial + && !muteCamera) { + RLog.d(TAG, "onClickToResume setEnableLocalVideo(true)"); + RongCallClient.getInstance().setEnableLocalVideo(true); + } + mBundle.putBoolean("isDial", isDial); + RongCallClient.getInstance().setVoIPCallListener(RongCallProxy.getInstance()); + Intent intent = new Intent(mBundle.getString("action")); + intent.setPackage(mContext.getPackageName()); + intent.putExtra("floatbox", mBundle); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra("callAction", RongCallAction.ACTION_RESUME_CALL.getName()); + + ActivityStartCheckUtils.getInstance() + .startActivity( + mContext, + intent, + BaseCallActivity.class.getSimpleName(), + new ActivityStartCheckUtils.ActivityStartResultCallback() { + @Override + public void onStartActivityResult(boolean isActivityStarted) { + activityResuming = false; + if (isActivityStarted) { + mBundle = null; + } else { + Toast.makeText( + mContext, + mContext.getString( + R.string + .rc_background_start_actvity_deny), + Toast.LENGTH_SHORT) + .show(); + } + } + }); + } + + private static void setupTime(final TextView timeView) { + final Handler handler = new Handler(Looper.getMainLooper()); + if (timer != null) { + timer.cancel(); + timer = null; + } + TimerTask task = + new TimerTask() { + @Override + public void run() { + handler.post( + new Runnable() { + @Override + public void run() { + mTime++; + if (timeView != null) { + if (mTime >= 3600) { + timeView.setText( + String.format( + Locale.ROOT, + "%d:%02d:%02d", + mTime / 3600, + (mTime % 3600) / 60, + (mTime % 60))); + timeView.setVisibility(View.VISIBLE); + } else { + timeView.setText( + String.format( + Locale.ROOT, + "%02d:%02d", + (mTime % 3600) / 60, + (mTime % 60))); + timeView.setVisibility(View.VISIBLE); + } + } + } + }); + } + }; + + timer = new Timer(); + timer.schedule(task, 0, 1000); + } + + private static void setAudioMode(int mode) { + AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + if (audioManager != null) { + audioManager.setMode(mode); + } + } + + /** + * 设置app是否现在在最近列表中, + * + * @param appContext + * @param excluded + */ + private static void setExcludeFromRecents(Context appContext, boolean excluded) { + if (appContext == null) return; + ActivityManager manager = + (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + for (ActivityManager.AppTask task : manager.getAppTasks()) { + task.setExcludeFromRecents(excluded); + } + } + } + + public static boolean isCallFloatBoxShown() { + return isShown; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallForegroundService.java b/callkit/src/main/java/io/rong/callkit/CallForegroundService.java new file mode 100644 index 000000000..1189c3147 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallForegroundService.java @@ -0,0 +1,124 @@ +package io.rong.callkit; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.graphics.Color; +import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.IBinder; +import android.util.Log; +import androidx.annotation.Nullable; +import io.rong.callkit.util.CallRingingUtil; +import io.rong.push.notification.RongNotificationInterface; +import io.rong.push.notification.RongNotificationInterface.SoundType; + +public class CallForegroundService extends Service { + + private static final String TAG = "CallForegroundService"; + + @Override + public void onCreate() { + super.onCreate(); + } + + private void showNotification( + String title, String content, PendingIntent pendingIntent, int notificationId) { + Log.d(TAG, "showNotification: "); + NotificationManager notificationManager = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + String channelId = CallRingingUtil.getInstance().getNotificationChannelId(); + Notification notification = + RongNotificationInterface.createNotification( + getApplicationContext(), + title, + pendingIntent, + content, + SoundType.SILENT, + channelId); + notification.flags |= Notification.FLAG_AUTO_CANCEL; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_LOW; + String channelName = CallRingingUtil.getInstance().getNotificationChannelName(this); + NotificationChannel notificationChannel = + new NotificationChannel(channelId, channelName, importance); + notificationChannel.enableLights(false); + notificationChannel.setLightColor(Color.GREEN); + notificationChannel.enableVibration(false); + notificationChannel.setSound(null, null); + notificationManager.createNotificationChannel(notificationChannel); + } + notification.defaults = Notification.DEFAULT_ALL; + if (VERSION.SDK_INT >= VERSION_CODES.Q) { + startForeground( + notificationId, + notification, + ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE + | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA); + } else { + startForeground(notificationId, notification); + } + Log.d(TAG, "showNotification: startForeground"); + } + + @Override + public void onDestroy() { + super.onDestroy(); + stopForeground(true); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String action = intent.getStringExtra("action"); + String title = intent.getStringExtra("title"); + String content = intent.getStringExtra("content"); + ResolveInfo info = + getPackageManager() + .resolveActivity(new Intent(action), PackageManager.MATCH_DEFAULT_ONLY); + ActivityInfo activityInfo; + if (info == null || (activityInfo = info.activityInfo) == null) { + Log.e(TAG, "onStartCommand: ResolveInfo is null! action=" + action); + return super.onStartCommand(intent, flags, startId); + } + Log.d(TAG, "onStartCommand: " + activityInfo.name); + Intent launched = new Intent(action); + launched.setClassName(activityInfo.packageName, activityInfo.name); + launched.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + launched.putExtra("floatbox", intent.getBundleExtra("floatbox")); + launched.putExtra("callAction", RongCallAction.ACTION_RESUME_CALL.getName()); + PendingIntent pendingIntent; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + pendingIntent = + PendingIntent.getActivity( + this, + 1000, + launched, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + pendingIntent = + PendingIntent.getActivity( + this, 1000, launched, PendingIntent.FLAG_UPDATE_CURRENT); + } + try { + showNotification(title, content, pendingIntent, BaseCallActivity.CALL_NOTIFICATION_ID); + } catch (Exception e) { + Log.e(TAG, "showNotification: ", e); + e.printStackTrace(); + } + return super.onStartCommand(intent, flags, startId); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallOptionMenu.java b/callkit/src/main/java/io/rong/callkit/CallOptionMenu.java new file mode 100644 index 000000000..fc5daa58e --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallOptionMenu.java @@ -0,0 +1,72 @@ +package io.rong.callkit; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +/** Created by mamingyang on 2018/3/19. */ +public class CallOptionMenu extends PopupWindow { + private View.OnClickListener onItemClickListener; + private TextView tv_right_text; + private LinearLayout layoutAdd; + private LinearLayout layoutWhiteBoard; + private LinearLayout layoutHandUp; + + public CallOptionMenu(Context context) { + super(context); + LayoutInflater inflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View content = inflater.inflate(R.layout.rc_voip_pop_menu, null); + setContentView(content); + setWidth(LayoutParams.WRAP_CONTENT); + setHeight(LayoutParams.WRAP_CONTENT); + layoutAdd = (LinearLayout) content.findViewById(R.id.voipItemAdd); + layoutAdd.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onItemClickListener != null) onItemClickListener.onClick(v); + } + }); + tv_right_text = content.findViewById(R.id.tv_right_text); + tv_right_text.setText(context.getString(R.string.rc_voip_add_member)); + layoutWhiteBoard = (LinearLayout) content.findViewById(R.id.voipItemWhiteboard); + layoutWhiteBoard.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onItemClickListener != null) onItemClickListener.onClick(v); + } + }); + + layoutHandUp = (LinearLayout) content.findViewById(R.id.voipItemHandup); + layoutHandUp.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onItemClickListener != null) onItemClickListener.onClick(v); + } + }); + + setBackgroundDrawable(context.getResources().getDrawable(R.drawable.rc_voip_menu_bg)); + setOutsideTouchable(true); + setFocusable(true); + } + + public void setOnItemClickListener(View.OnClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + } + + public void setHandUpvisibility(boolean isSeen) { + if (layoutHandUp != null) { + if (!isSeen) layoutHandUp.setVisibility(View.GONE); + else { + layoutHandUp.setVisibility(View.VISIBLE); + } + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallPromptDialog.java b/callkit/src/main/java/io/rong/callkit/CallPromptDialog.java new file mode 100644 index 000000000..d20f5a47d --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallPromptDialog.java @@ -0,0 +1,177 @@ +package io.rong.callkit; + +import android.app.AlertDialog; +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.TextView; + +public class CallPromptDialog extends AlertDialog { + private Context mContext; + private OnPromptButtonClickedListener mPromptButtonClickedListener; + private String mTitle; + private String mPositiveButton; + private String mNegativeButton; + private String mMessage; + private int mLayoutResId; + private boolean disableCancel; + private int positiveTxtColor = 0; + private int negativeTxtColor = 0; + + public static CallPromptDialog newInstance( + final Context context, String title, String message) { + return new CallPromptDialog(context, title, message); + } + + public static CallPromptDialog newInstance(final Context context, String message) { + return new CallPromptDialog(context, message); + } + + public static CallPromptDialog newInstance( + final Context context, String title, String message, String positiveButton) { + return new CallPromptDialog(context, title, message, positiveButton); + } + + public static CallPromptDialog newInstance( + final Context context, + String title, + String message, + String positiveButton, + String negativeButton) { + return new CallPromptDialog(context, title, message, positiveButton, negativeButton); + } + + public CallPromptDialog( + final Context context, + String title, + String message, + String positiveButton, + String negativeButton) { + this(context, title, message, positiveButton); + this.mNegativeButton = negativeButton; + } + + public CallPromptDialog( + final Context context, String title, String message, String positiveButton) { + this(context, title, message); + mPositiveButton = positiveButton; + } + + public CallPromptDialog(final Context context, String title, String message) { + super(context); + mLayoutResId = R.layout.rc_voip_dialog_popup_prompt; + mContext = context; + mTitle = title; + mMessage = message; + } + + public CallPromptDialog(final Context context, String message) { + this(context, "", message); + } + + @Override + protected void onStart() { + super.onStart(); + LayoutInflater inflater = + (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + final View view = inflater.inflate(mLayoutResId, null); + TextView txtViewTitle = (TextView) view.findViewById(io.rong.imkit.R.id.popup_dialog_title); + TextView txtViewMessage = + (TextView) view.findViewById(io.rong.imkit.R.id.popup_dialog_message); + TextView txtViewOK = + (TextView) view.findViewById(io.rong.imkit.R.id.popup_dialog_button_ok); + TextView txtViewCancel = + (TextView) view.findViewById(io.rong.imkit.R.id.popup_dialog_button_cancel); + if (disableCancel) txtViewCancel.setVisibility(View.GONE); + if (positiveTxtColor != 0) { + txtViewOK.setTextColor(positiveTxtColor); + } + if (negativeTxtColor != 0) { + txtViewCancel.setTextColor(negativeTxtColor); + } + txtViewOK.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mPromptButtonClickedListener != null) { + mPromptButtonClickedListener.onPositiveButtonClicked(); + } + dismiss(); + } + }); + txtViewCancel.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mPromptButtonClickedListener != null) { + mPromptButtonClickedListener.onNegativeButtonClicked(); + } + dismiss(); + } + }); + if (!TextUtils.isEmpty(mTitle)) { + txtViewTitle.setText(mTitle); + txtViewTitle.setVisibility(View.VISIBLE); + } + if (!TextUtils.isEmpty(mPositiveButton)) { + txtViewOK.setText(mPositiveButton); + } + + if (!TextUtils.isEmpty(mNegativeButton)) { + txtViewCancel.setText(mNegativeButton); + txtViewCancel.setVisibility(View.VISIBLE); + } + + txtViewMessage.setText(mMessage); + + setContentView(view); + WindowManager.LayoutParams layoutParams = getWindow().getAttributes(); + layoutParams.width = gePopupWidth(); + layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + getWindow().setAttributes(layoutParams); + } + + public void disableCancel() { + disableCancel = true; + } + + public CallPromptDialog setPromptButtonClickedListener( + OnPromptButtonClickedListener buttonClickedListener) { + this.mPromptButtonClickedListener = buttonClickedListener; + return this; + } + + public CallPromptDialog setLayoutRes(int resId) { + this.mLayoutResId = resId; + return this; + } + + public void setPositiveTextColor(int color) { + positiveTxtColor = color; + } + + public void setNegativeTextColor(int color) { + negativeTxtColor = color; + } + + public interface OnPromptButtonClickedListener { + void onPositiveButtonClicked(); + + void onNegativeButtonClicked(); + } + + private int gePopupWidth() { + int distanceToBorder = + (int) mContext.getResources().getDimension(R.dimen.callkit_dimen_size_40); + return getScreenWidth() - 2 * (distanceToBorder); + } + + private int getScreenWidth() { + return ((WindowManager) (mContext.getSystemService(Context.WINDOW_SERVICE))) + .getDefaultDisplay() + .getWidth(); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallSelectMemberActivity.java b/callkit/src/main/java/io/rong/callkit/CallSelectMemberActivity.java new file mode 100644 index 000000000..c275c3a4f --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallSelectMemberActivity.java @@ -0,0 +1,820 @@ +package io.rong.callkit; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Message; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; +import io.rong.callkit.util.CallKitSearchBarListener; +import io.rong.callkit.util.CallKitSearchBarView; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.CallSelectMemberSerializable; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.common.RLog; +import io.rong.imkit.feature.mention.RongMentionManager; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imkit.userinfo.model.GroupUserInfo; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.Group; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CallSelectMemberActivity extends BaseNoActionBarActivity + implements RongUserInfoManager.UserDataObserver { + private static final String TAG = "CallSelectMemberActivity"; + public static final String DISCONNECT_ACTION = "call_disconnect"; + ArrayList selectedMember; + private boolean isFirstDialog = true; + /** 已经选择的观察者列表 */ + private ArrayList observerMember; + + TextView txtvStart, callkit_conference_selected_number; + ListAdapter mAdapter; + ListView mList; + RongCallCommon.CallMediaType mMediaType; + private Conversation.ConversationType conversationType; + private EditText searchView; + private HashMap tempNickmembers = new HashMap<>(); + + private ArrayList searchMembers = new ArrayList<>(); + private ArrayList invitedMembers; + private ArrayList tempMembers = new ArrayList<>(); + + private ArrayList allObserver = null; // 保存当前通话中从多人音/视频传递过来的观察者列表 + + private String groupId; + private String callId; + private RelativeLayout rlSearchTop; + private RelativeLayout rlActionBar; + private ImageView ivBack; + private CallKitSearchBarView searchBar; + /** + * true:只能选择n个人同时进行音视频通话,>n选择无效; false:>n个人同时音视频通话之后,其他人视为观察者加入到本次通话中; n :NORMAL_VIDEO_NUMBER 和 + * NORMAL_AUDIO_NUMBER + */ + private boolean ctrlTag = true; + + private static final int NORMAL_VIDEO_NUMBER = 7; + private static final int NORMAL_AUDIO_NUMBER = 20; + private ArrayList userInfoArrayList = new ArrayList<>(); + /** 用于存储获取不到userInfo的用户在列表中的位置 */ + private HashMap userInfoIndex = new HashMap<>(); + + private final Object listLock = new Object(); + // + private Handler uiHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + if (msg.what == 2) { + Bundle bundle = msg.getData(); + if (bundle != null) { + CallSelectMemberSerializable callSelectMemberSerializable = + (CallSelectMemberSerializable) + bundle.getSerializable( + CALLSELECTMEMBERSERIALIZABLE_KEY); + if (callSelectMemberSerializable != null) { + tempNickmembers = callSelectMemberSerializable.getHashMap(); + } + } + if (userInfoArrayList.isEmpty() + && invitedMembers != null + && invitedMembers.size() > 0) { + String tmpUserID = ""; + for (int i = 0; i < invitedMembers.size(); i++) { + tmpUserID = invitedMembers.get(i); + fillInUserInfoList(tmpUserID, i); + } + } + RLog.i(TAG, "setAdapter"); + mAdapter = new ListAdapter(userInfoArrayList, invitedMembers); + mList.setAdapter(mAdapter); + callkit_conference_selected_number.setText( + getString( + R.string.callkit_selected_contacts_count, + getTotalSelectedNumber())); + } + } + }; + + private void fillInUserInfoList(String userid, int index) { + synchronized (listLock) { + if (!TextUtils.isEmpty(userid)) { + if (getUserInfo(userid) == null) { + userInfoIndex.put(userid, index); + } + // 当获取到的userInfo为空时,记录下当前index,并给userInfoArrayList增加一个空元素,等到异步结果(onHeadsetPlugUpdate)回来后,根据index,把正确的数据插入回原来位置 + userInfoArrayList.add(getUserInfo(userid)); + + } else { + RLog.e(TAG, "uiHandler->userid null."); + } + } + } + + private Handler mHandler; + private static final String GROUPMEMBERSRESULT_KEY = "GROUPMEMBERSRESULTKEY"; + private static final String CALLSELECTMEMBERSERIALIZABLE_KEY = + "CALLSELECTMEMBERSERIALIZABLEKEY"; + + private BroadcastReceiver disconnectBroadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (TextUtils.equals(intent.getAction(), DISCONNECT_ACTION)) { + if (!isFinishing()) { + setActivityResult(true); + } + } + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow() + .setFlags( + WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.activity_call_select_member2); + RongUserInfoManager.getInstance().addUserDataObserver(this); + + initTopBar(); + + selectedMember = new ArrayList<>(); + observerMember = new ArrayList<>(); + + Intent intent = getIntent(); + int type = intent.getIntExtra("mediaType", RongCallCommon.CallMediaType.VIDEO.getValue()); + mMediaType = RongCallCommon.CallMediaType.valueOf(type); + int conType = intent.getIntExtra("conversationType", 0); + conversationType = Conversation.ConversationType.setValue(conType); + invitedMembers = intent.getStringArrayListExtra("invitedMembers"); + groupId = intent.getStringExtra("groupId"); + callId = intent.getStringExtra("callId"); + allObserver = intent.getStringArrayListExtra("allObserver"); + + ArrayList list = intent.getStringArrayListExtra("allMembers"); + if (list != null) { + for (int i = 0; i < list.size(); i++) { + fillInUserInfoList(list.get(i), i); + } + } + HandlerThread handlerThread = new HandlerThread(TAG); + handlerThread.start(); + mHandler = + new Handler(handlerThread.getLooper()) { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + String key = (String) msg.obj; + if (GROUPMEMBERSRESULT_KEY.equals(key)) { + Bundle bundle = msg.getData(); + HashMap hashMap = new HashMap<>(); + if (bundle != null) { + ArrayList arrayList = + bundle.getParcelableArrayList(GROUPMEMBERSRESULT_KEY); + Conversation.ConversationType conversationType = + Conversation.ConversationType.setValue( + bundle.getInt("conversationType")); + if (arrayList != null) { + RLog.i(TAG, "onGetGroupMembersResult : " + arrayList.size()); + UserInfo userInfo = null; + String userNickName = ""; + GroupUserInfo groupUserInfo = null; + /** 转换昵称** */ + for (int i = 0; i < arrayList.size(); i++) { + userInfo = arrayList.get(i); + if (userInfo != null + && !TextUtils.isEmpty(userInfo.getUserId())) { + if (conversationType != null + && conversationType.equals( + Conversation.ConversationType.GROUP)) { + groupUserInfo = + RongUserInfoManager.getInstance() + .getGroupUserInfo( + groupId, + userInfo.getUserId()); + if (groupUserInfo != null + && !TextUtils.isEmpty( + groupUserInfo.getNickname())) { + userNickName = groupUserInfo.getNickname(); + } + } + if (TextUtils.isEmpty(userNickName)) { + userNickName = userInfo.getName(); + } else { + userInfo.setName(userNickName); + } + hashMap.put(userInfo.getUserId(), userNickName); + userNickName = ""; + } + } + } + } + CallSelectMemberSerializable callSelectMemberSerializable = + new CallSelectMemberSerializable(hashMap); + Message message = new Message(); + message.what = 2; + Bundle bundle1 = new Bundle(); + bundle1.putSerializable( + CALLSELECTMEMBERSERIALIZABLE_KEY, callSelectMemberSerializable); + message.setData(bundle1); + uiHandler.sendMessage(message); + } + } + }; + + RongCallKit.GroupMembersProvider provider = RongCallKit.getGroupMemberProvider(); + if (TextUtils.isEmpty(groupId)) { + return; + } + if (provider != null) { + provider.getMemberList( + groupId, + new RongCallKit.OnGroupMembersResult() { + @Override + public void onGotMemberList(ArrayList members) { + for (int i = 0; i < members.size(); i++) { + fillInUserInfoList(members.get(i), i); + } + Message message = new Message(); + message.obj = GROUPMEMBERSRESULT_KEY; + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList( + GROUPMEMBERSRESULT_KEY, userInfoArrayList); + bundle.putInt("conversationType", conversationType.getValue()); + message.setData(bundle); + mHandler.sendMessage(message); + } + }); + } else { + if (RongMentionManager.getInstance().getGroupMembersProvider() != null) { + RongMentionManager.getInstance() + .getGroupMembersProvider() + .getGroupMembers( + groupId, + new RongMentionManager.IGroupMemberCallback() { + @Override + public void onGetGroupMembersResult(List userInfos) { + if (userInfos == null || userInfos.size() == 0) { + RLog.e( + TAG, + "onGetGroupMembersResult userInfos is null!"); + return; + } + userInfoArrayList.addAll(userInfos); + + Message message = new Message(); + message.obj = GROUPMEMBERSRESULT_KEY; + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList( + GROUPMEMBERSRESULT_KEY, userInfoArrayList); + bundle.putInt( + "conversationType", conversationType.getValue()); + message.setData(bundle); + mHandler.sendMessage(message); + } + }); + } + } + + callkit_conference_selected_number = + (TextView) findViewById(R.id.callkit_conference_selected_number); + txtvStart = (TextView) findViewById(R.id.callkit_btn_ok); + txtvStart.setText(getString(R.string.callkit_voip_ok)); + txtvStart.setEnabled(false); + txtvStart.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + setActivityResult(false); + } + }); + + mList = (ListView) findViewById(R.id.calkit_list_view_select_member); + mList.setOnItemClickListener(adapterOnItemClickListener); + rlSearchTop = (RelativeLayout) findViewById(R.id.rl_search_top); + ivBack = (ImageView) findViewById(R.id.iv_back); + searchBar = (CallKitSearchBarView) findViewById(R.id.search_bar); + if (CallKitUtils.findConfigurationLanguage(CallSelectMemberActivity.this, "ar")) { + rlSearchTop.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); + searchBar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); + } + + ivBack.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + rlSearchTop.setVisibility(View.GONE); + rlActionBar.setVisibility(View.VISIBLE); + mAdapter.setAllMembers(userInfoArrayList); + mAdapter.notifyDataSetChanged(); + CallKitUtils.closeKeyBoard(CallSelectMemberActivity.this, null); + } + }); + searchBar.setSearchBarListener( + new CallKitSearchBarListener() { + @Override + public void onSearchStart(String content) { + if (userInfoArrayList != null && userInfoArrayList.size() > 0) { + startSearchMember(content); + } else { + Toast.makeText( + CallSelectMemberActivity.this, + getString(R.string.rc_voip_search_no_member), + Toast.LENGTH_SHORT) + .show(); + } + } + + @Override + public void onSoftSearchKeyClick() {} + + @Override + public void onClearButtonClick() { + if (invitedMembers != null) { + mAdapter = new ListAdapter(userInfoArrayList, invitedMembers); + mList.setAdapter(mAdapter); + mList.setOnItemClickListener(adapterOnItemClickListener); + } + } + }); + registerDisconnectBroadcastReceiver(); + } + + private void registerDisconnectBroadcastReceiver() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(DISCONNECT_ACTION); + registerReceiver( + disconnectBroadcastReceiver, + intentFilter, + this.getApplicationInfo().packageName + ".permission.RONG_ACCESS_RECEIVER", + null); + } + + private void startSearchMember(String searchEditContent) { + try { + searchMembers.clear(); + tempMembers.clear(); + if (!TextUtils.isEmpty(searchEditContent)) { + for (UserInfo info : userInfoArrayList) { + if (info != null && !TextUtils.isEmpty(info.getUserId())) { + if (((String) tempNickmembers.get(info.getUserId())) + .indexOf(searchEditContent) + != -1) { + tempMembers.add(info); + } + } + } + } else { + tempMembers.addAll(userInfoArrayList); + } + } catch (Exception e) { + e.printStackTrace(); + tempMembers.addAll(userInfoArrayList); + } + // closeKeyBoard(this, searchBar); + setData(); + } + + private void setData() { + if (null != tempMembers) { + ListAdapter adapter = new ListAdapter(tempMembers, invitedMembers); + mList.setAdapter(adapter); + mList.setOnItemClickListener(adapterOnItemClickListener); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + RongUserInfoManager.getInstance().removeUserDataObserver(this); + unregisterReceiver(disconnectBroadcastReceiver); + } + + @Override + public void onUserUpdate(UserInfo userInfo) { + if (mList != null && userInfo != null) { + if (userInfo.getUserId() == null + || !userInfoIndex.containsKey(userInfo.getUserId()) + || userInfoIndex.get(userInfo.getUserId()) == null) { + return; + } + synchronized (listLock) { + int index = userInfoIndex.get(userInfo.getUserId()); + if (index >= 0 && index < userInfoArrayList.size()) { + userInfoIndex.remove(userInfo.getUserId()); + userInfoArrayList.remove(index); + userInfoArrayList.add(index, userInfo); + } + Message message = new Message(); + message.obj = GROUPMEMBERSRESULT_KEY; + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList(GROUPMEMBERSRESULT_KEY, userInfoArrayList); + bundle.putInt("conversationType", conversationType.getValue()); + message.setData(bundle); + mHandler.sendMessage(message); + } + } + } + + @Override + public void onGroupUpdate(Group group) {} + + @Override + public void onGroupUserInfoUpdate(GroupUserInfo groupUserInfo) {} + + class ListAdapter extends BaseAdapter { + List mallMembers; + List invitedMembers; + + public ListAdapter(List allMembers, List invitedMembers) { + this.mallMembers = allMembers; + this.invitedMembers = invitedMembers; + } + + public void setAllMembers(List allMembers) { + this.mallMembers = allMembers; + } + + @Override + public int getCount() { + return mallMembers.size(); + } + + @Override + public Object getItem(int position) { + return mallMembers.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + if (convertView == null) { + holder = new ViewHolder(); + convertView = + LayoutInflater.from(CallSelectMemberActivity.this) + .inflate(R.layout.rc_voip_listitem_select_member, null); + holder.checkbox = (ImageView) convertView.findViewById(R.id.rc_checkbox); + holder.portrait = (ImageView) convertView.findViewById(R.id.rc_user_portrait); + holder.name = (TextView) convertView.findViewById(R.id.rc_user_name); + convertView.setTag(holder); + } + + UserInfo mUserInfo = mallMembers.get(position); + if (mUserInfo == null || TextUtils.isEmpty(mUserInfo.getUserId())) { + // userInfo为空前,把所有值都设置为默认 + holder = (ViewHolder) convertView.getTag(); + holder.checkbox.setImageResource(R.drawable.rc_voip_checkbox); + holder.checkbox.setClickable(false); + holder.checkbox.setEnabled(true); + holder.name.setText(""); + RongCallKit.getKitImageEngine() + .loadPortrait( + getApplicationContext(), + null, + R.drawable.rc_default_portrait, + holder.portrait); + // Glide.with(holder.portrait) + // .load(R.drawable.rc_default_portrait) + // .apply(RequestOptions.bitmapTransform(new CenterCrop())) + // .into(holder.portrait); + holder.checkbox.setTag(""); + return convertView; + } + holder = (ViewHolder) convertView.getTag(); + holder.checkbox.setTag(mUserInfo.getUserId()); + if (invitedMembers.contains(mUserInfo.getUserId())) { + holder.checkbox.setClickable(false); + holder.checkbox.setEnabled(false); + holder.checkbox.setImageResource(R.drawable.rc_voip_icon_checkbox_checked); + } else { + if (selectedMember.contains(mUserInfo.getUserId())) { + holder.checkbox.setImageResource(R.drawable.rc_voip_checkbox); + holder.checkbox.setSelected(true); + } else { + holder.checkbox.setImageResource(R.drawable.rc_voip_checkbox); + holder.checkbox.setSelected(false); + } + holder.checkbox.setClickable(false); + holder.checkbox.setEnabled(true); + } + + String displayName = ""; + if (conversationType != null + && conversationType.equals(Conversation.ConversationType.GROUP)) { + GroupUserInfo groupUserInfo = + RongUserInfoManager.getInstance() + .getGroupUserInfo(groupId, mUserInfo.getUserId()); + if (groupUserInfo != null && !TextUtils.isEmpty(groupUserInfo.getNickname())) { + displayName = groupUserInfo.getNickname(); + } + } + if (TextUtils.isEmpty(displayName)) { + holder.name.setText(mUserInfo.getName()); + } else { + holder.name.setText(displayName); + } + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + mUserInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + holder.portrait); + return convertView; + } + } + + /** + * 结束页面前设置值 + * + * @param val 是否是远端挂断,如果是则关闭该页面 + */ + private void setActivityResult(boolean val) { + RongCallSession profile = RongCallClient.getInstance().getCallSession(); + if (profile != null) { + // callid由多聊页面传入,如果先启动群组选择人员页面再启动多聊页面,不允许启动多聊页面 + if (null != profile.getCallId() && (!profile.getCallId().equals(callId))) { + String msg = + profile.getMediaType() == RongCallCommon.CallMediaType.AUDIO + ? getString(io.rong.callkit.R.string.rc_voip_call_audio_start_fail) + : getString(io.rong.callkit.R.string.rc_voip_call_video_start_fail); + Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); + return; + } + } + + CallKitUtils.closeKeyBoard(CallSelectMemberActivity.this, null); + Intent intent = new Intent(); + intent.putExtra("remote_hangup", val); + intent.setPackage(getPackageName()); + intent.putStringArrayListExtra("invited", selectedMember); + intent.putStringArrayListExtra("observers", observerMember); + setResult(RESULT_OK, intent); + CallSelectMemberActivity.this.finish(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + } + + class ViewHolder { + + ImageView checkbox; + ImageView portrait; + TextView name; + } + + public void initTopBar() { + rlActionBar = (RelativeLayout) findViewById(R.id.rl_actionbar); + ImageButton backImgBtn = (ImageButton) findViewById(R.id.imgbtn_custom_nav_back); + backImgBtn.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + TextView titleTextView = (TextView) findViewById(R.id.tv_custom_nav_title); + titleTextView.setText(getString(R.string.rc_select_contact)); + titleTextView.setTextSize(18); + titleTextView.setTextColor(getResources().getColor(R.color.callkit_normal_text)); + + findViewById(R.id.imgbtn_custom_nav_option).setVisibility(View.VISIBLE); + ((ImageButton) findViewById(R.id.imgbtn_custom_nav_option)) + .setImageResource(R.drawable.callkit_ic_search_focused_x); + findViewById(R.id.imgbtn_custom_nav_option) + .setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + rlSearchTop.setVisibility(View.VISIBLE); + rlActionBar.setVisibility(View.GONE); + } + }); + } + + private AdapterView.OnItemClickListener adapterOnItemClickListener = + new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + View v = view.findViewById(R.id.rc_checkbox); + String userId = (String) v.getTag(); + if (!TextUtils.isEmpty(userId) && !invitedMembers.contains(userId)) { + if (v.isSelected()) { + if (selectedMember.contains(userId)) { + selectedMember.remove(userId); + } + if (observerMember.contains(userId)) { + observerMember.remove(userId); + } + v.setSelected(false); + if (selectedMember.size() == 0 && observerMember.size() == 0) { + txtvStart.setEnabled(false); + txtvStart.setTextColor( + getResources() + .getColor( + R.color + .callkit_color_text_operation_disable)); + callkit_conference_selected_number.setTextColor( + getResources() + .getColor( + R.color + .callkit_color_text_operation_disable)); + } + if (searchMembers != null) { + callkit_conference_selected_number.setText( + getString( + R.string.callkit_selected_contacts_count, + getTotalSelectedNumber())); + } + return; + } + int totalNumber = getTotalSelectedNumber(); + boolean videoObserverState = + totalNumber + >= (mMediaType.equals(RongCallCommon.CallMediaType.AUDIO) + ? NORMAL_AUDIO_NUMBER + : NORMAL_VIDEO_NUMBER); + if (ctrlTag) { + if (videoObserverState) { + Toast.makeText( + CallSelectMemberActivity.this, + String.format( + getString( + mMediaType.equals( + RongCallCommon + .CallMediaType + .AUDIO) + ? R.string + .rc_voip_audio_numberofobservers + : R.string + .rc_voip_video_numberofobservers), + totalNumber), + Toast.LENGTH_SHORT) + .show(); + return; + } + if (selectedMember.contains(userId)) { + selectedMember.remove(userId); + } + v.setSelected(!v.isSelected()); // 1 false + if (v.isSelected()) { + selectedMember.add(userId); + } + if (selectedMember.size() > 0 || observerMember.size() > 0) { + txtvStart.setEnabled(true); + txtvStart.setTextColor( + getResources().getColor(R.color.rc_voip_check_enable)); + callkit_conference_selected_number.setTextColor( + getResources().getColor(R.color.rc_voip_check_enable)); + } else { + txtvStart.setEnabled(false); + txtvStart.setTextColor( + getResources() + .getColor( + R.color + .callkit_color_text_operation_disable)); + callkit_conference_selected_number.setTextColor( + getResources() + .getColor( + R.color + .callkit_color_text_operation_disable)); + } + } else { + if (videoObserverState && isFirstDialog) { + CallPromptDialog dialog = + CallPromptDialog.newInstance( + CallSelectMemberActivity.this, + getString(R.string.rc_voip_video_observer)); + dialog.setPromptButtonClickedListener( + new CallPromptDialog.OnPromptButtonClickedListener() { + @Override + public void onPositiveButtonClicked() {} + + @Override + public void onNegativeButtonClicked() {} + }); + dialog.disableCancel(); + dialog.setCancelable(false); + dialog.show(); + isFirstDialog = false; + } + v.setSelected(!v.isSelected()); // 1 false + if (videoObserverState) { + if (observerMember.contains(userId)) { + observerMember.remove(userId); + } + observerMember.add(userId); + } + if (selectedMember.contains(userId)) { + selectedMember.remove(userId); + } + if (v.isSelected()) { + selectedMember.add(userId); + } + if (selectedMember.size() > 0 || observerMember.size() > 0) { + txtvStart.setEnabled(true); + txtvStart.setTextColor( + getResources().getColor(R.color.rc_voip_check_enable)); + callkit_conference_selected_number.setTextColor( + getResources().getColor(R.color.rc_voip_check_enable)); + } else { + txtvStart.setEnabled(false); + txtvStart.setTextColor( + getResources() + .getColor( + R.color + .callkit_color_text_operation_disable)); + callkit_conference_selected_number.setTextColor( + getResources() + .getColor( + R.color + .callkit_color_text_operation_disable)); + } + } + } + if (searchMembers != null) { + callkit_conference_selected_number.setText( + getString( + R.string.callkit_selected_contacts_count, + getTotalSelectedNumber())); + } + } + }; + + /** + * 关闭软键盘 + * + * @param activity + * @param view + */ + private void closeKeyBoard(Activity activity, View view) { + IBinder token; + if (view == null || view.getWindowToken() == null) { + if (null == activity) { + return; + } + Window window = activity.getWindow(); + if (window == null) { + return; + } + View v = window.peekDecorView(); + if (v == null) { + return; + } + token = v.getWindowToken(); + } else { + token = view.getWindowToken(); + } + InputMethodManager imm = + (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(token, 0); + } + + private UserInfo getUserInfo(String userid) { + if (TextUtils.isEmpty(userid)) { + return null; + } + return RongUserInfoManager.getInstance().getUserInfo(userid); + } + + private int getTotalSelectedNumber() { + return (selectedMember == null ? 0 : selectedMember.size()) + + (invitedMembers == null ? 0 : invitedMembers.size()); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/CallUserGridView.java b/callkit/src/main/java/io/rong/callkit/CallUserGridView.java new file mode 100644 index 000000000..f071c4535 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/CallUserGridView.java @@ -0,0 +1,264 @@ +package io.rong.callkit; + +import android.content.Context; +import android.content.res.TypedArray; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.CircleCrop; +import com.bumptech.glide.request.RequestOptions; +import io.rong.callkit.util.ICallScrollView; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.List; + +/** Created by weiqinxiao on 16/3/25. coming 横向显示 多人语音_被叫 */ +public class CallUserGridView extends HorizontalScrollView implements ICallScrollView { + + private Context context; + private boolean enableTitle; + private LinearLayout linearLayout; + + private static int CHILDREN_PER_LINE = 5; + private static final int CHILDREN_SPACE = 13; + + private int portraitSize; + private boolean isHorizontal = true; + + @Override + public int getChildrenSpace() { + return CHILDREN_SPACE; + } + + public CallUserGridView(Context context) { + super(context); + init(context); + } + + public CallUserGridView(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CallUserGridView); + isHorizontal = a.getBoolean(R.styleable.CallUserGridView_CallGridViewOrientation, true); + CHILDREN_PER_LINE = + a.getInteger(R.styleable.CallUserGridView_CallGridViewChildrenPerLine, 4); + init(context); + a.recycle(); + } + + private void init(Context context) { + this.context = context; + linearLayout = new LinearLayout(context); + linearLayout.setLayoutParams( + new LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + // linearLayout.setOrientation(LinearLayout.HORIZONTAL); + addView(linearLayout); + } + + public int dip2pix(int dipValue) { + float scale = getResources().getDisplayMetrics().density; + return (int) (dipValue * scale + 0.5f); + } + + public int getScreenWidth() { + return getResources().getDisplayMetrics().widthPixels; + } + + public void setChildPortraitSize(int size) { + portraitSize = size; + } + + public void enableShowState(boolean enable) { + enableTitle = enable; + } + + public void addChild(String childId, UserInfo userInfo) { + addChild(childId, userInfo, null); + } + + public void addChild(String childId, UserInfo userInfo, String state) { + int containerCount = linearLayout.getChildCount(); + LinearLayout lastContainer = null; + int i; + for (i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + if (container.getChildCount() < CHILDREN_PER_LINE) { + lastContainer = container; + break; + } + } + if (lastContainer == null) { + lastContainer = new LinearLayout(context); + lastContainer.setLayoutParams( + new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + lastContainer.setGravity(Gravity.CENTER_HORIZONTAL); + lastContainer.setPadding(0, dip2pix(CHILDREN_SPACE), 0, 0); + linearLayout.addView(lastContainer); + } + + LinearLayout child = + (LinearLayout) + LayoutInflater.from(context).inflate(R.layout.rc_voip_user_info, null); + child.setLayoutParams( + new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + if (containerCount == 0) { + child.setPadding(dip2pix(15), 0, dip2pix(CHILDREN_SPACE), 0); + } else { + child.setPadding(0, 0, dip2pix(CHILDREN_SPACE), 0); + } + child.setTag(childId); + if (portraitSize > 0) { + child.findViewById(R.id.rc_user_portrait_layout) + .setLayoutParams(new LinearLayout.LayoutParams(portraitSize, portraitSize)); + } + ImageView imageView = (ImageView) child.findViewById(R.id.rc_user_portrait); + TextView name = (TextView) child.findViewById(R.id.rc_user_name); + name.setVisibility(enableTitle ? VISIBLE : GONE); + TextView stateV = (TextView) child.findViewById(R.id.rc_voip_member_state); + stateV.setVisibility(enableTitle ? VISIBLE : GONE); + if (state != null) { + stateV.setText(state); + } else { + stateV.setVisibility(GONE); + } + + if (userInfo != null) { + RongCallKit.getKitImageEngine() + .loadPortrait( + this.getContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + imageView); + name.setText(userInfo.getName() == null ? userInfo.getUserId() : userInfo.getName()); + } else { + name.setText(childId); + } + lastContainer.addView(child); + } + + @Override + public void setScrollViewOverScrollMode(int mode) { + this.setOverScrollMode(mode); + } + + @Override + public void removeAllChild() { + linearLayout.removeAllViews(); + } + + public void removeChild(String childId) { + int containerCount = linearLayout.getChildCount(); + + LinearLayout lastContainer = null; + List containerList = new ArrayList<>(); + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + containerList.add(container); + } + for (LinearLayout resultContainer : containerList) { + if (lastContainer == null) { + LinearLayout child = (LinearLayout) resultContainer.findViewWithTag(childId); + if (child != null) { + resultContainer.removeView(child); + if (resultContainer.getChildCount() == 0) { + linearLayout.removeView(resultContainer); + break; + } else { + lastContainer = resultContainer; + } + } + } else { + View view = resultContainer.getChildAt(0); + resultContainer.removeView(view); + lastContainer.addView(view); + if (resultContainer.getChildCount() == 0) { + linearLayout.removeView(resultContainer); + break; + } else { + lastContainer = resultContainer; + } + } + } + } + + public View findChildById(String childId) { + int containerCount = linearLayout.getChildCount(); + + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + return child; + } + } + return null; + } + + public void updateChildInfo(String childId, UserInfo userInfo) { + int containerCount = linearLayout.getChildCount(); + + LinearLayout lastContainer = null; + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + ImageView imageView = (ImageView) child.findViewById(R.id.rc_user_portrait); + Glide.with(this) + .load(userInfo.getPortraitUri()) + .placeholder(R.drawable.rc_default_portrait) + .apply(RequestOptions.bitmapTransform(new CircleCrop())) + .into(imageView); + if (enableTitle) { + TextView textView = (TextView) child.findViewById(R.id.rc_user_name); + textView.setLines(1); + textView.setEllipsize(TextUtils.TruncateAt.END); + textView.setText(userInfo.getName()); + } + } + } + } + + public void updateChildState(String childId, String state) { + int containerCount = linearLayout.getChildCount(); + + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + TextView textView = (TextView) child.findViewById(R.id.rc_voip_member_state); + textView.setText(state); + } + } + } + + public void updateChildState(String childId, boolean visible) { + int containerCount = linearLayout.getChildCount(); + + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + TextView textView = (TextView) child.findViewById(R.id.rc_voip_member_state); + textView.setVisibility(visible ? VISIBLE : GONE); + } + } + } + + @Override + public View getChildAtIndex(int index) { + return linearLayout.getChildAt(index); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/ContainerLayout.java b/callkit/src/main/java/io/rong/callkit/ContainerLayout.java new file mode 100644 index 000000000..ba0f6c34d --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/ContainerLayout.java @@ -0,0 +1,111 @@ +package io.rong.callkit; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.SurfaceView; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.RelativeLayout; +import androidx.annotation.NonNull; +import cn.rongcloud.rtc.api.stream.RCRTCVideoView; +import cn.rongcloud.rtc.utils.FinLog; + +/** Created by Administrator on 2017/3/30. */ +public class ContainerLayout extends RelativeLayout { + private final String TAG = ContainerLayout.class.getSimpleName(); + private Context context; + private static boolean isNeedFillScrren = true; + SurfaceView currentView; + + public ContainerLayout(Context context, AttributeSet attrs) { + super(context, attrs); + this.context = context; + } + + public void addView(final SurfaceView videoView) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + this.screenWidth = wm.getDefaultDisplay().getWidth(); + this.screenHeight = wm.getDefaultDisplay().getHeight(); + FinLog.d( + TAG, + "---xx-- add view " + + videoView.toString() + + " Height: " + + ((RCRTCVideoView) videoView).rotatedFrameHeight + + " Width: " + + ((RCRTCVideoView) videoView).rotatedFrameWidth); + super.addView(videoView, getBigContainerParams((RCRTCVideoView) videoView)); + currentView = videoView; + ((RCRTCVideoView) videoView) + .setOnSizeChangedListener( + new RCRTCVideoView.OnSizeChangedListener() { + @Override + public void onChanged(RCRTCVideoView.Size size) { + try { + ContainerLayout.this.removeAllViews(); + FinLog.d( + TAG, + "---xx-- change view " + + videoView.toString() + + " Height: " + + ((RCRTCVideoView) videoView) + .rotatedFrameHeight + + " Width: " + + ((RCRTCVideoView) videoView) + .rotatedFrameWidth); + ContainerLayout.this.addView( + videoView, + getBigContainerParams((RCRTCVideoView) videoView)); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @NonNull + private LayoutParams getBigContainerParams(RCRTCVideoView videoView) { + LayoutParams layoutParams = null; + if (!isNeedFillScrren) { + if (screenHeight > screenWidth) { // V + int layoutParamsHeight = + (videoView.rotatedFrameHeight == 0 || videoView.rotatedFrameWidth == 0) + ? ViewGroup.LayoutParams.WRAP_CONTENT + : screenWidth + * videoView.rotatedFrameHeight + / videoView.rotatedFrameWidth; + layoutParams = new LayoutParams(screenWidth, layoutParamsHeight); + } else { + int layoutParamsWidth = + (videoView.rotatedFrameWidth == 0 || videoView.rotatedFrameHeight == 0) + ? ViewGroup.LayoutParams.WRAP_CONTENT + : (screenWidth + * videoView.rotatedFrameWidth + / videoView.rotatedFrameHeight + > screenWidth + ? screenWidth + : screenHeight + * videoView.rotatedFrameWidth + / videoView.rotatedFrameHeight); + layoutParams = new LayoutParams(layoutParamsWidth, screenHeight); + } + } else { + layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); + } + layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); + return layoutParams; + } + + public void setIsNeedFillScrren(boolean isNeed) { + isNeedFillScrren = isNeed; + } + + @Override + public void removeAllViews() { + if (currentView != null) ((RCRTCVideoView) currentView).setOnSizeChangedListener(null); + super.removeAllViews(); + } + + private int screenWidth; + private int screenHeight; +} diff --git a/callkit/src/main/java/io/rong/callkit/GlideCallKitImageEngine.java b/callkit/src/main/java/io/rong/callkit/GlideCallKitImageEngine.java new file mode 100644 index 000000000..dfc991f5c --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/GlideCallKitImageEngine.java @@ -0,0 +1,28 @@ +package io.rong.callkit; + +import android.content.Context; +import android.net.Uri; +import android.widget.ImageView; +import androidx.annotation.DrawableRes; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; + +public class GlideCallKitImageEngine { + /** + * 设置头像加载样式 + * + * @param context + * @param url + * @param replaceRes + * @param imageView + */ + public void loadPortrait( + Context context, Uri url, @DrawableRes int replaceRes, ImageView imageView) { + Glide.with(context) + .load(url) + .error(replaceRes) + .placeholder(replaceRes) + .apply(RequestOptions.circleCropTransform()) + .into(imageView); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/MultiAudioCallActivity.java b/callkit/src/main/java/io/rong/callkit/MultiAudioCallActivity.java new file mode 100644 index 000000000..e10b4d557 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/MultiAudioCallActivity.java @@ -0,0 +1,989 @@ +package io.rong.callkit; + +import static io.rong.callkit.CallSelectMemberActivity.DISCONNECT_ACTION; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; +import cn.rongcloud.rtc.api.RCRTCEngine; +import cn.rongcloud.rtc.audioroute.RCAudioRouteType; +import cn.rongcloud.rtc.utils.FinLog; +import io.rong.callkit.util.BluetoothUtil; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.CallVerticalScrollView; +import io.rong.callkit.util.DefaultPushConfig; +import io.rong.callkit.util.HeadsetInfo; +import io.rong.callkit.util.ICallScrollView; +import io.rong.callkit.util.RingingMode; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.callkit.util.SPUtils; +import io.rong.calllib.CallUserProfile; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.message.MultiCallEndMessage; +import io.rong.common.RLog; +import io.rong.imkit.IMCenter; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imlib.IRongCoreCallback; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.discussion.base.RongDiscussionClient; +import io.rong.imlib.discussion.model.Discussion; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.Group; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +/** 如何实现不基于于群组的voip */ +public class MultiAudioCallActivity extends BaseCallActivity { + private static final String TAG = "VoIPMultiAudioCallActivity"; + LinearLayout audioContainer; + ICallScrollView memberContainer; + + RelativeLayout incomingLayout; + RelativeLayout outgoingLayout; + RelativeLayout outgoingController; + RelativeLayout incomingController; + RongCallAction callAction; + RongCallSession callSession; + + boolean shouldShowFloat = true; + boolean startForCheckPermissions = false; + private boolean handFree = false; + private boolean muted = false; + private final String KEY_MUTED = "muted"; + private final String KEY_HAND_FREE = "handFree"; + + @Override + @TargetApi(23) + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState != null && RongCallClient.getInstance() == null) { + // 音视频请求权限时,用户在设置页面取消权限,导致应用重启,退出当前activity. + finish(); + return; + } + setContentView(R.layout.rc_voip_ac_muti_audio); + audioContainer = (LinearLayout) findViewById(R.id.rc_voip_container); + incomingLayout = + (RelativeLayout) + LayoutInflater.from(this) + .inflate(R.layout.rc_voip_item_incoming_maudio, null); + TextView tv_invite_incoming_audio = + incomingLayout.findViewById(R.id.tv_invite_incoming_audio); + CallKitUtils.textViewShadowLayer(tv_invite_incoming_audio, MultiAudioCallActivity.this); + + outgoingLayout = + (RelativeLayout) + LayoutInflater.from(this) + .inflate(R.layout.rc_voip_item_outgoing_maudio, null); + TextView rc_voip_remind = incomingLayout.findViewById(R.id.rc_voip_remind); + CallKitUtils.textViewShadowLayer(rc_voip_remind, MultiAudioCallActivity.this); + + outgoingController = + (RelativeLayout) + LayoutInflater.from(this) + .inflate( + R.layout.rc_voip_call_bottom_connected_button_layout, null); + ImageView button = outgoingController.findViewById(R.id.rc_voip_call_mute_btn); + button.setEnabled(true); + incomingController = + (RelativeLayout) + LayoutInflater.from(this) + .inflate(R.layout.rc_voip_call_bottom_incoming_button_layout, null); + + startForCheckPermissions = getIntent().getBooleanExtra("checkPermissions", false); + if (requestCallPermissions( + RongCallCommon.CallMediaType.AUDIO, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)) { + initView(); + } + } + + @Override + protected void onNewIntent(Intent intent) { + startForCheckPermissions = getIntent().getBooleanExtra("checkPermissions", false); + super.onNewIntent(intent); + if (requestCallPermissions( + RongCallCommon.CallMediaType.AUDIO, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)) { + initView(); + } + } + + @TargetApi(23) + @Override + public void onRequestPermissionsResult( + int requestCode, String[] permissions, int[] grantResults) { + switch (requestCode) { + case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: + if (RongCallPermissionUtil.checkAudioCallNeedPermission(this)) { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionGranted(); + } else { + initView(); + } + } else { + if (startForCheckPermissions) { + startForCheckPermissions = false; + Toast.makeText( + this, + getString(R.string.rc_voip_relevant_permissions), + Toast.LENGTH_SHORT) + .show(); + RongCallClient.getInstance().onPermissionDenied(); + } else { + finish(); + } + } + break; + + default: + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + @Override + public void onRestoreFloatBox(Bundle bundle) { + super.onRestoreFloatBox(bundle); + if (bundle != null) { + handFree = bundle.getBoolean(KEY_HAND_FREE); + muted = bundle.getBoolean(KEY_MUTED); + audioContainer.removeAllViews(); + audioContainer.addView(outgoingLayout); + String str = (String) SPUtils.get(MultiAudioCallActivity.this, "ICallScrollView", ""); + + FrameLayout controller = + (FrameLayout) audioContainer.findViewById(R.id.rc_voip_control_layout); + controller.removeAllViews(); + controller.addView(outgoingController); + callSession = RongCallClient.getInstance().getCallSession(); + if (callSession == null) { + setShouldShowFloat(false); + finish(); + return; + } + List participantProfiles = callSession.getParticipantProfileList(); + + /** 初始化列表* */ + if (str.equals("CallVerticalScrollView")) { + memberContainer = + (CallVerticalScrollView) + audioContainer.findViewById(R.id.rc_voip_members_container); + } else { + memberContainer = + (CallUserGridView) + audioContainer.findViewById( + R.id.rc_voip_members_container_gridView); + } + memberContainer.enableShowState(true); + LinearLayout linear_scrollviewTag = + (LinearLayout) outgoingLayout.findViewById(R.id.linear_scrollviewTag); + if (participantProfiles.size() > 4) { + ViewGroup.LayoutParams params = linear_scrollviewTag.getLayoutParams(); + params.height = CallKitUtils.dp2px(200, MultiAudioCallActivity.this); + linear_scrollviewTag.setLayoutParams(params); + } + // 添加数据 + for (CallUserProfile item : participantProfiles) { + if (!item.getUserId().equals(callSession.getSelfUserId()) + && memberContainer.findChildById(item.getUserId()) == null) { + if (item.getCallStatus().equals(RongCallCommon.CallStatus.CONNECTED)) { + memberContainer.addChild( + item.getUserId(), + RongUserInfoManager.getInstance().getUserInfo(item.getUserId())); + memberContainer.updateChildState(item.getUserId(), false); + } else { + String state = getString(R.string.rc_voip_call_connecting); + memberContainer.addChild( + item.getUserId(), + RongUserInfoManager.getInstance().getUserInfo(item.getUserId()), + state); + } + } + } + if (!(boolean) bundle.get("isDial")) { + onCallConnected(callSession, null); // 接听 + } else { + onCallOutgoing(callSession, null); + } + } + } + + void initView() { + Intent intent = getIntent(); + callAction = RongCallAction.valueOf(intent.getStringExtra("callAction")); + if (callAction == null || callAction.equals(RongCallAction.ACTION_RESUME_CALL)) { + RelativeLayout relativeLayout = + (RelativeLayout) + outgoingLayout.findViewById(R.id.reltive_voip_outgoing_audio_title); + relativeLayout.setVisibility(View.VISIBLE); + return; + } + ArrayList invitedList = new ArrayList<>(); + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + // 正常在收到呼叫后,RongCallClient 和 CallSession均不会为空 + if (RongCallClient.getInstance() == null + || RongCallClient.getInstance().getCallSession() == null) { + // 如果为空 表示通话已经结束 但依然启动了本页面,这样会导致页面无法销毁问题 + // 所以 需要在这里 finish 结束当前页面 推荐开发者在结束当前页面前跳转至APP主页或者其他页面 + RLog.e( + TAG, + "MultiAudioCallActivity#initView()->RongCallClient or CallSession is empty---->finish()"); + finish(); + return; + } + audioContainer.removeAllViews(); + callSession = RongCallClient.getInstance().getCallSession(); + UserInfo userInfo = + RongUserInfoManager.getInstance().getUserInfo(callSession.getCallerUserId()); + setTopContainerUserView(callSession.getCallerUserId()); + + audioContainer.addView(incomingLayout); + memberContainer = + (CallUserGridView) + audioContainer.findViewById(R.id.rc_voip_members_container_gridView); + SPUtils.put(MultiAudioCallActivity.this, "ICallScrollView", "CallUserGridView"); + memberContainer.removeAllChild(); + memberContainer.setChildPortraitSize(memberContainer.dip2pix(55)); + List list = callSession.getParticipantProfileList(); + for (CallUserProfile profile : list) { + if (!profile.getUserId().equals(callSession.getCallerUserId())) { + invitedList.add(profile.getUserId()); + userInfo = RongUserInfoManager.getInstance().getUserInfo(profile.getUserId()); + memberContainer.addChild(profile.getUserId(), userInfo); + } + } + FrameLayout controller = + (FrameLayout) audioContainer.findViewById(R.id.rc_voip_control_layout); + controller.removeAllViews(); + controller.addView(incomingController); + + ImageView iv_answerBtn = + (ImageView) incomingController.findViewById(R.id.rc_voip_call_answer_btn); + iv_answerBtn.setBackground( + CallKitUtils.BackgroundDrawable( + R.drawable.rc_voip_audio_answer_selector_new, + MultiAudioCallActivity.this)); + + onIncomingCallRinging(callSession); + } else if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) { + audioContainer.removeAllViews(); + Conversation.ConversationType conversationType = + Conversation.ConversationType.valueOf( + intent.getStringExtra("conversationType").toUpperCase(Locale.US)); + String targetId = intent.getStringExtra("targetId"); + ArrayList userIds = intent.getStringArrayListExtra("invitedUsers"); + ArrayList observers = intent.getStringArrayListExtra("observers"); + audioContainer.addView(outgoingLayout); + + LinearLayout linear_scrollviewTag = + (LinearLayout) outgoingLayout.findViewById(R.id.linear_scrollviewTag); + + // 多人语音主叫方顶部布局 + RelativeLayout relativeLayout = + (RelativeLayout) + outgoingLayout.findViewById(R.id.reltive_voip_outgoing_audio_title); + relativeLayout.setVisibility(View.VISIBLE); + + memberContainer = + (CallVerticalScrollView) + audioContainer.findViewById(R.id.rc_voip_members_container); + SPUtils.put(MultiAudioCallActivity.this, "ICallScrollView", "CallVerticalScrollView"); + memberContainer.enableShowState(true); + FrameLayout controller = + (FrameLayout) audioContainer.findViewById(R.id.rc_voip_control_layout); + controller.removeAllViews(); + controller.addView(outgoingController); + + ImageView iv_answerBtn = + (ImageView) incomingController.findViewById(R.id.rc_voip_call_answer_btn); + iv_answerBtn.setBackground( + CallKitUtils.BackgroundDrawable( + R.drawable.rc_voip_audio_answer_selector_new, + MultiAudioCallActivity.this)); + + ImageView button = outgoingController.findViewById(R.id.rc_voip_call_mute_btn); + button.setEnabled(true); + for (int i = 0; i < userIds.size(); i++) { + if (!userIds.get(i).equals(RongIMClient.getInstance().getCurrentUserId())) { + invitedList.add(userIds.get(i)); + UserInfo userInfo = + RongUserInfoManager.getInstance().getUserInfo(userIds.get(i)); + memberContainer.addChild( + userIds.get(i), userInfo, getString(R.string.rc_voip_call_connecting)); + } + } + // + if (userIds.size() > 4) { + ViewGroup.LayoutParams params = linear_scrollviewTag.getLayoutParams(); + params.height = CallKitUtils.dp2px(200, MultiAudioCallActivity.this); + linear_scrollviewTag.setLayoutParams(params); + } + + String groupName = ""; + Group group = RongUserInfoManager.getInstance().getGroupInfo(targetId); + if (group != null && !TextUtils.isEmpty(group.getName())) { + groupName = group.getName(); + } + RongCallClient.getInstance() + .setPushConfig( + DefaultPushConfig.getInviteConfig(this, true, false, groupName), + DefaultPushConfig.getHangupConfig(this, false, groupName)); + + RongCallClient.getInstance() + .startCall( + conversationType, + targetId, + invitedList, + observers, + RongCallCommon.CallMediaType.AUDIO, + "multi"); + } + memberContainer.setScrollViewOverScrollMode(View.OVER_SCROLL_NEVER); + createPickupDetector(); + } + + @Override + protected void onPause() { + if (pickupDetector != null) { + pickupDetector.unRegister(); + } + super.onPause(); + } + + @Override + protected void onResume() { + if (pickupDetector == null) createPickupDetector(); + if (pickupDetector != null) { + pickupDetector.register(this); + } + super.onResume(); + } + + public void onHangupBtnClick(View view) { + // unRegisterHeadsetplugReceiver(); + if (callSession == null || isFinishing) { + FinLog.e( + TAG, + "_挂断多人语音出错 callSession=" + + (callSession == null) + + ",isFinishing=" + + isFinishing); + return; + } + RongCallClient.getInstance().hangUpCall(callSession.getCallId()); + } + + public void onReceiveBtnClick(View view) { + if (callSession == null || isFinishing) { + FinLog.e( + TAG, + "_接听多人语音出错 callSession=" + + (callSession == null) + + ",isFinishing=" + + isFinishing); + return; + } + RongCallClient.getInstance().acceptCall(callSession.getCallId()); + } + + @Override + protected void onAddMember(List newMemberIds) { + if (newMemberIds == null || newMemberIds.isEmpty()) { + return; + } + ArrayList added = new ArrayList<>(); + List participants = new ArrayList<>(); + List list = + RongCallClient.getInstance().getCallSession().getParticipantProfileList(); + for (CallUserProfile profile : list) { + participants.add(profile.getUserId()); + } + for (String id : newMemberIds) { + if (participants.contains(id)) { + continue; + } else { + added.add(id); + } + } + if (added.isEmpty()) { + return; + } + + RongCallClient.getInstance().addParticipants(callSession.getCallId(), added, null); + } + + @Override + public void onRemoteUserRinging(String userId) {} + + @Override + public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) { + super.onCallOutgoing(callSession, localVideo); + this.callSession = callSession; + callRinging(RingingMode.Outgoing); + } + + @Override + public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) { + super.onRemoteUserInvited(userId, mediaType); + memberContainer.addChild( + userId, + RongUserInfoManager.getInstance().getUserInfo(userId), + getString(R.string.rc_voip_call_connecting)); + } + + @Override + public void onRemoteUserJoined( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + View view = memberContainer.findChildById(userId); + if (view != null) { + memberContainer.updateChildState(userId, false); + } else { + memberContainer.addChild(userId, RongUserInfoManager.getInstance().getUserInfo(userId)); + } + } + + @Override + public void onRemoteUserLeft( + final String userId, RongCallCommon.CallDisconnectedReason reason) { + if (isTopContainerUserExit(userId)) { + return; + } + String text = null; + switch (reason) { + case REMOTE_BUSY_LINE: + text = getString(R.string.rc_voip_mt_busy_toast); + break; + case REMOTE_CANCEL: + text = getString(R.string.rc_voip_mt_cancel); + break; + case REMOTE_REJECT: + text = getString(R.string.rc_voip_mt_reject); + break; + case NO_RESPONSE: + text = getString(R.string.rc_voip_mt_no_response); + break; + case NETWORK_ERROR: + case HANGUP: + case REMOTE_HANGUP: + break; + } + if (text != null && memberContainer != null) { + memberContainer.updateChildState(userId, text); + } + if (memberContainer != null) { + memberContainer.removeChild(userId); + } + } + + private boolean isTopContainerUserExit(String userId) { + if (CallKitUtils.callConnected) { + return false; + } + if (callSession != null + && TextUtils.equals(callSession.getInviterUserId(), userId) + && memberContainer != null) { + if (((LinearLayout) memberContainer.getChildAtIndex(0)) != null + && ((LinearLayout) memberContainer.getChildAtIndex(0)).getChildAt(0) != null + && ((LinearLayout) memberContainer.getChildAtIndex(0)).getChildAt(0).getTag() + != null) { + LinearLayout firstView = + (LinearLayout) + ((LinearLayout) memberContainer.getChildAtIndex(0)).getChildAt(0); + String firstUserId = (String) firstView.getTag(); + setTopContainerUserView(firstUserId); + + memberContainer.removeChild(firstUserId); + + LinearLayout linearLayout = + (LinearLayout) + ((LinearLayout) memberContainer.getChildAtIndex(0)).getChildAt(0); + linearLayout.setPadding( + memberContainer.dip2pix(15), + 0, + memberContainer.dip2pix(memberContainer.getChildrenSpace()), + 0); + linearLayout.requestLayout(); + return true; + } + } + return false; + } + + private void setTopContainerUserView(String userId) { + TextView name = (TextView) incomingLayout.findViewById(R.id.rc_user_name); + ImageView userPortrait = + (ImageView) incomingLayout.findViewById(R.id.rc_voip_user_portrait); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(userId); + if (userInfo != null && userInfo.getName() != null) { + name.setText(userInfo.getName()); + } else { + name.setText(userId); + } + if (userInfo != null && userInfo.getPortraitUri() != null) { + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + userPortrait.setVisibility(View.VISIBLE); + } + name.setTag(userId + "callerName"); + } + + /** + * 已建立通话。 通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息。 + * + * @param callSession 通话实体。 + * @param localVideo 本地 camera 信息。 + */ + @Override + public void onCallConnected(final RongCallSession callSession, SurfaceView localVideo) { + super.onCallConnected(callSession, localVideo); + RongCallClient.getInstance().setEnableLocalVideo(false); + this.callSession = callSession; + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + audioContainer.removeAllViews(); + FrameLayout controller = + (FrameLayout) outgoingLayout.findViewById(R.id.rc_voip_control_layout); + controller.addView(outgoingController); + audioContainer.addView(outgoingLayout); + SPUtils.put(MultiAudioCallActivity.this, "ICallScrollView", "CallVerticalScrollView"); + // 多人语音通话中竖向滑动 + memberContainer = + (CallVerticalScrollView) + outgoingLayout.findViewById(R.id.rc_voip_members_container); + memberContainer.enableShowState(true); + LinearLayout linear_scrollviewTag = + (LinearLayout) outgoingLayout.findViewById(R.id.linear_scrollviewTag); + if (callSession.getParticipantProfileList().size() > 4) { + ViewGroup.LayoutParams params = linear_scrollviewTag.getLayoutParams(); + params.height = CallKitUtils.dp2px(200, MultiAudioCallActivity.this); + linear_scrollviewTag.setLayoutParams(params); + } + for (CallUserProfile profile : callSession.getParticipantProfileList()) { + if (!profile.getUserId().equals(callSession.getSelfUserId())) { + UserInfo userInfo = + RongUserInfoManager.getInstance().getUserInfo(profile.getUserId()); + String state = + profile.getCallStatus().equals(RongCallCommon.CallStatus.CONNECTED) + ? null + : getString(R.string.rc_voip_call_connecting); + memberContainer.addChild(profile.getUserId(), userInfo, state); + } + } + } + + outgoingLayout.findViewById(R.id.rc_voip_remind).setVisibility(View.GONE); + outgoingLayout.findViewById(R.id.rc_voip_handfree).setVisibility(View.VISIBLE); + ImageView button = outgoingController.findViewById(R.id.rc_voip_call_mute_btn); + button.setEnabled(true); + outgoingLayout.findViewById(R.id.rc_voip_call_mute).setVisibility(View.VISIBLE); + // 多人语音主叫方顶部布局 + RelativeLayout relativeLayout = + (RelativeLayout) + outgoingLayout.findViewById(R.id.reltive_voip_outgoing_audio_title); + relativeLayout.setVisibility(View.GONE); + + View muteV = outgoingLayout.findViewById(R.id.rc_voip_call_mute_btn); + muteV.setVisibility(View.VISIBLE); + muteV.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + onMuteButtonClick(v); + } + }); + + View handfreeV = outgoingLayout.findViewById(R.id.rc_voip_handfree_btn); + handfreeV.setVisibility(View.VISIBLE); + handfreeV.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + onHandFreeButtonClick(v); + } + }); + + outgoingLayout.findViewById(R.id.rc_voip_title).setVisibility(View.VISIBLE); + TextView timeV = (TextView) outgoingLayout.findViewById(R.id.rc_voip_time); + setupTime(timeV); + + View imgvAdd = outgoingLayout.findViewById(R.id.rc_voip_add_btn); + imgvAdd.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + setShouldShowFloat(false); + if (callSession + .getConversationType() + .equals(Conversation.ConversationType.DISCUSSION)) { + RongDiscussionClient.getInstance() + .getDiscussion( + callSession.getTargetId(), + new IRongCoreCallback.ResultCallback() { + @Override + public void onSuccess(Discussion discussion) { + Intent intent = + new Intent( + MultiAudioCallActivity.this, + CallSelectMemberActivity.class); + ArrayList added = + new ArrayList(); + List list = + RongCallClient.getInstance() + .getCallSession() + .getParticipantProfileList(); + for (CallUserProfile profile : list) { + added.add(profile.getUserId()); + } + List allObserver = + RongCallClient.getInstance() + .getCallSession() + .getObserverUserList(); + intent.putStringArrayListExtra( + "allObserver", + new ArrayList<>(allObserver)); + intent.putStringArrayListExtra( + "allMembers", + (ArrayList) + discussion.getMemberIdList()); + intent.putStringArrayListExtra( + "invitedMembers", added); + intent.putExtra( + "conversationType", + callSession + .getConversationType() + .getValue()); + intent.putExtra( + "mediaType", + RongCallCommon.CallMediaType.AUDIO + .getValue()); + startActivityForResult( + intent, REQUEST_CODE_ADD_MEMBER); + } + + @Override + public void onError( + IRongCoreEnum.CoreErrorCode e) {} + }); + } else if (callSession + .getConversationType() + .equals(Conversation.ConversationType.GROUP)) { + Intent intent = + new Intent( + MultiAudioCallActivity.this, + CallSelectMemberActivity.class); + ArrayList added = new ArrayList<>(); + List list = + RongCallClient.getInstance() + .getCallSession() + .getParticipantProfileList(); + for (CallUserProfile profile : list) { + added.add(profile.getUserId()); + } + List allObserver = + RongCallClient.getInstance() + .getCallSession() + .getObserverUserList(); + intent.putExtra("callId", callSession.getCallId()); + intent.putStringArrayListExtra( + "allObserver", new ArrayList<>(allObserver)); + intent.putStringArrayListExtra("invitedMembers", added); + intent.putExtra( + "conversationType", + callSession.getConversationType().getValue()); + intent.putExtra("groupId", callSession.getTargetId()); + intent.putExtra( + "mediaType", RongCallCommon.CallMediaType.AUDIO.getValue()); + startActivityForResult(intent, REQUEST_CODE_ADD_MEMBER); + } else { + ArrayList added = new ArrayList<>(); + List list = + RongCallClient.getInstance() + .getCallSession() + .getParticipantProfileList(); + for (CallUserProfile profile : list) { + added.add(profile.getUserId()); + } + addMember(added); + } + } + }); + outgoingLayout.findViewById(R.id.rc_voip_minimize_outgoing).setVisibility(View.VISIBLE); + View minimizeV = outgoingLayout.findViewById(R.id.rc_voip_minimize); + minimizeV.setVisibility(View.VISIBLE); + minimizeV.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.i( + "audioTag", + "************ outgoingLayout.findViewById(R.id.rc_voip_minimize)*****************"); + MultiAudioCallActivity.super.onMinimizeClick(v); + } + }); + + RongCallClient.getInstance().setEnableLocalAudio(!muted); + if (muteV != null) { + muteV.setSelected(muted); + } + RCRTCEngine.getInstance().enableSpeaker(false); + + stopRing(); + } + + protected void resetHandFreeStatus(RCAudioRouteType type) { + ImageView handFreeV = null; + if (null != outgoingLayout) { + handFreeV = outgoingLayout.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + // 耳机状态 + if (type == RCAudioRouteType.HEADSET || type == RCAudioRouteType.HEADSET_BLUETOOTH) { + // handFreeV.setSelected(false); + } else { + // 非耳机状态 + handFreeV.setSelected(type == RCAudioRouteType.SPEAKER_PHONE); + } + } + } + + @Override + public void onCallDisconnected( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + super.onCallDisconnected(callSession, reason); + + isFinishing = true; + if (reason == null || callSession == null) { + RLog.e(TAG, "onCallDisconnected. callSession is null!"); + postRunnableDelay( + new Runnable() { + @Override + public void run() { + finish(); + } + }); + return; + } + + MultiCallEndMessage multiCallEndMessage = new MultiCallEndMessage(); + multiCallEndMessage.setReason(reason); + multiCallEndMessage.setMediaType(IRongCoreEnum.MediaType.AUDIO); + long serverTime = System.currentTimeMillis() - RongIMClient.getInstance().getDeltaTime(); + IMCenter.getInstance() + .insertIncomingMessage( + callSession.getConversationType(), + callSession.getTargetId(), + callSession.getCallerUserId(), + CallKitUtils.getReceivedStatus(reason), + multiCallEndMessage, + serverTime, + null); + cancelTime(); + stopRing(); + postRunnableDelay( + new Runnable() { + @Override + public void run() { + finish(); + } + }); + sendBroadcast(new Intent(DISCONNECT_ACTION).setPackage(getPackageName())); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + callSession = RongCallClient.getInstance().getCallSession(); + if (requestCode == REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS) { + if (RongCallPermissionUtil.checkAudioCallNeedPermission(this)) { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionGranted(); + } else { + initView(); + } + } else { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionDenied(); + } else { + finish(); + } + } + + } else if (requestCode == REQUEST_CODE_ADD_MEMBER) { + if (resultCode == RESULT_OK) { + if (data.getBooleanExtra("remote_hangup", false)) { + RLog.d(TAG, "Remote exit, end the call."); + return; + } + } + if (callSession.getEndTime() != 0) { + finish(); + return; + } + shouldShowFloat = true; + if (resultCode == RESULT_OK) { + ArrayList invited = data.getStringArrayListExtra("invited"); + ArrayList observers = data.getStringArrayListExtra("observers"); + List callUserProfiles = callSession.getParticipantProfileList(); + Iterator iterator = invited.iterator(); + while (iterator.hasNext()) { + String id = iterator.next(); + for (CallUserProfile profile : callUserProfiles) { + if (profile.getUserId().equals(id)) { + iterator.remove(); + } + } + } + RongCallClient.getInstance() + .addParticipants(callSession.getCallId(), invited, observers); + } + } else if (requestCode == REQUEST_CODE_ADD_MEMBER_NONE) { + try { + if (callSession.getEndTime() != 0) { + finish(); + return; + } + setShouldShowFloat(true); + if (resultCode == RESULT_OK) { + ArrayList invited = data.getStringArrayListExtra("pickedIds"); + RongCallClient.getInstance() + .addParticipants(callSession.getCallId(), invited, null); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void onHandFreeButtonClick(View view) { + RongCallClient.getInstance().setEnableSpeakerphone(!view.isSelected()); + view.setSelected(!view.isSelected()); + handFree = view.isSelected(); + } + + public void onMuteButtonClick(View view) { + RongCallClient.getInstance().setEnableLocalAudio(view.isSelected()); + view.setSelected(!view.isSelected()); + muted = view.isSelected(); + } + + @Override + public String onSaveFloatBoxState(Bundle bundle) { + super.onSaveFloatBoxState(bundle); + String intentAction = null; + Log.i("audioTag", "onSaveFloatBoxState shouldShowFloat=" + shouldShowFloat); + if (shouldShowFloat) { + intentAction = getIntent().getAction(); + bundle.putInt("mediaType", RongCallCommon.CallMediaType.AUDIO.getValue()); + bundle.putBoolean(KEY_HAND_FREE, handFree); + bundle.putBoolean(KEY_MUTED, muted); + } + return intentAction; + } + + @Override + public void onBackPressed() { + return; + } + + public void onMinimizeClick(View view) { + super.onMinimizeClick(view); + } + + @Override + public void onUserUpdate(UserInfo userInfo) { + if (isFinishing()) { + return; + } + TextView callerName = + (TextView) audioContainer.findViewWithTag(userInfo.getUserId() + "callerName"); + + if (callerName != null && userInfo.getName() != null) { + callerName.setLines(1); + callerName.setEllipsize(TextUtils.TruncateAt.END); + callerName.setText(userInfo.getName()); + } + if (memberContainer != null + && memberContainer.findChildById(userInfo.getUserId()) != null) { + memberContainer.updateChildInfo(userInfo.getUserId(), userInfo); + } + } + + public void onHeadsetPlugUpdate(HeadsetInfo headsetInfo) { + if (headsetInfo == null || !BluetoothUtil.isForground(MultiAudioCallActivity.this)) { + FinLog.v("bugtags", "MultiAudioCallActivity 不在前台!"); + return; + } + Log.i( + "bugtags", + "Insert=" + + headsetInfo.isInsert() + + ",headsetInfo.getType=" + + headsetInfo.getType().getValue()); + try { + if (headsetInfo.isInsert()) { + RongCallClient.getInstance().setEnableSpeakerphone(false); + ImageView handFreeV = null; + if (null != outgoingLayout) { + handFreeV = outgoingLayout.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + handFreeV.setSelected(false); + handFreeV.setEnabled(false); + handFreeV.setClickable(false); + } + if (headsetInfo.getType() == HeadsetInfo.HeadsetType.BluetoothA2dp) { + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + am.setMode(AudioManager.MODE_IN_COMMUNICATION); + am.startBluetoothSco(); + am.setBluetoothScoOn(true); + am.setSpeakerphoneOn(false); + } + } else { + if (headsetInfo.getType() == HeadsetInfo.HeadsetType.WiredHeadset + && BluetoothUtil.hasBluetoothA2dpConnected()) { + return; + } + RongCallClient.getInstance().setEnableSpeakerphone(true); + ImageView handFreeV = null; + if (null != outgoingLayout) { + handFreeV = outgoingLayout.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + handFreeV.setSelected(true); + handFreeV.setEnabled(true); + handFreeV.setClickable(true); + } + } + } catch (Exception e) { + e.printStackTrace(); + Log.i("bugtags", "MultiAudioCallActivity->onHeadsetPlugUpdate Error=" + e.getMessage()); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/MultiCallEndMessageProvider.java b/callkit/src/main/java/io/rong/callkit/MultiCallEndMessageProvider.java new file mode 100644 index 000000000..1f46bed43 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/MultiCallEndMessageProvider.java @@ -0,0 +1,103 @@ +package io.rong.callkit; + +import android.content.Context; +import android.text.Spannable; +import android.text.SpannableString; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.message.MultiCallEndMessage; +import io.rong.imkit.conversation.messgelist.provider.BaseNotificationMessageItemProvider; +import io.rong.imkit.model.UiMessage; +import io.rong.imkit.widget.adapter.IViewProviderListener; +import io.rong.imkit.widget.adapter.ViewHolder; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.model.MessageContent; +import java.util.List; + +public class MultiCallEndMessageProvider + extends BaseNotificationMessageItemProvider { + + @Override + protected ViewHolder onCreateMessageContentViewHolder(ViewGroup parent, int viewType) { + View v = + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.rc_voip_msg_multi_call_end, parent, false); + return new ViewHolder(parent.getContext(), v); + } + + @Override + protected void bindMessageContentViewHolder( + ViewHolder holder, + ViewHolder parentHolder, + MultiCallEndMessage multiCallEndMessage, + UiMessage uiMessage, + int position, + List list, + IViewProviderListener listener) { + Context context = holder.getContext(); + String msg = ""; + RongCallCommon.CallDisconnectedReason reason = multiCallEndMessage.getReason(); + IRongCoreEnum.MediaType mediaType = multiCallEndMessage.getMediaType(); + if (reason == RongCallCommon.CallDisconnectedReason.OTHER_DEVICE_HAD_ACCEPTED) { + msg = context.getResources().getString(R.string.rc_voip_call_other); + } else if (reason == RongCallCommon.CallDisconnectedReason.REMOTE_HANGUP + || reason == RongCallCommon.CallDisconnectedReason.HANGUP) { + if (mediaType == IRongCoreEnum.MediaType.AUDIO) { + msg = context.getResources().getString(R.string.rc_voip_audio_ended); + } else if (mediaType == IRongCoreEnum.MediaType.VIDEO) { + msg = context.getResources().getString(R.string.rc_voip_video_ended); + } + } else if (reason == RongCallCommon.CallDisconnectedReason.REMOTE_REJECT + || reason == RongCallCommon.CallDisconnectedReason.REJECT) { + if (mediaType == IRongCoreEnum.MediaType.AUDIO) { + msg = context.getResources().getString(R.string.rc_voip_audio_refuse); + } else if (mediaType == IRongCoreEnum.MediaType.VIDEO) { + msg = context.getResources().getString(R.string.rc_voip_video_refuse); + } + } else if (reason == RongCallCommon.CallDisconnectedReason.SERVICE_NOT_OPENED + || reason == RongCallCommon.CallDisconnectedReason.REMOTE_ENGINE_UNSUPPORTED) { + msg = context.getResources().getString(R.string.rc_voip_engine_notfound); + } else if (reason == RongCallCommon.CallDisconnectedReason.CANCEL) { + if (mediaType == IRongCoreEnum.MediaType.AUDIO) { + msg = context.getResources().getString(R.string.rc_voip_audio_cancel); + } else if (mediaType == IRongCoreEnum.MediaType.VIDEO) { + msg = context.getResources().getString(R.string.rc_voip_video_cancel); + } + } else { + if (mediaType == IRongCoreEnum.MediaType.AUDIO) { + msg = context.getResources().getString(R.string.rc_voip_audio_no_response); + } else if (mediaType == IRongCoreEnum.MediaType.VIDEO) { + msg = context.getResources().getString(R.string.rc_voip_video_no_response); + } + } + TextView tv = holder.getView(R.id.rc_msg); + tv.setText(msg); + } + + @Override + protected boolean isMessageViewType(MessageContent messageContent) { + return messageContent instanceof MultiCallEndMessage; + } + + @Override + public Spannable getSummarySpannable(Context context, MultiCallEndMessage multiCallEndMessage) { + String msg = ""; + if (multiCallEndMessage.getReason() == RongCallCommon.CallDisconnectedReason.NO_RESPONSE) { + if (multiCallEndMessage.getMediaType() == IRongCoreEnum.MediaType.AUDIO) { + msg = context.getResources().getString(R.string.rc_voip_audio_no_response); + } else if (multiCallEndMessage.getMediaType() == IRongCoreEnum.MediaType.VIDEO) { + msg = context.getResources().getString(R.string.rc_voip_video_no_response); + } + } else { + if (multiCallEndMessage.getMediaType() == IRongCoreEnum.MediaType.AUDIO) { + msg = context.getResources().getString(R.string.rc_voip_message_audio); + } else if (multiCallEndMessage.getMediaType() == IRongCoreEnum.MediaType.VIDEO) { + msg = context.getResources().getString(R.string.rc_voip_message_video); + } + } + return new SpannableString(msg); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/MultiVideoCallActivity.java b/callkit/src/main/java/io/rong/callkit/MultiVideoCallActivity.java new file mode 100644 index 000000000..2870dec15 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/MultiVideoCallActivity.java @@ -0,0 +1,1943 @@ +package io.rong.callkit; + +import static io.rong.callkit.CallSelectMemberActivity.DISCONNECT_ACTION; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; +import cn.rongcloud.rtc.api.RCRTCEngine; +import cn.rongcloud.rtc.api.stream.RCRTCVideoView; +import cn.rongcloud.rtc.audioroute.RCAudioRouteType; +import cn.rongcloud.rtc.base.RCRTCStream; +import cn.rongcloud.rtc.core.RendererCommon; +import cn.rongcloud.rtc.utils.FinLog; +import io.rong.callkit.util.BluetoothUtil; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.DefaultPushConfig; +import io.rong.callkit.util.GlideUtils; +import io.rong.callkit.util.HeadsetInfo; +import io.rong.callkit.util.RingingMode; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.callkit.util.UserProfileOrderManager; +import io.rong.calllib.CallUserProfile; +import io.rong.calllib.ReportUtil; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.StartIncomingPreviewCallback; +import io.rong.calllib.StreamProfile; +import io.rong.calllib.Utils; +import io.rong.calllib.message.MultiCallEndMessage; +import io.rong.common.RLog; +import io.rong.imkit.IMCenter; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imlib.IRongCoreCallback; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.discussion.base.RongDiscussionClient; +import io.rong.imlib.discussion.model.Discussion; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.Group; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +/** 如何实现不基于于群组的voip */ +public class MultiVideoCallActivity extends BaseCallActivity { + private static final String TAG = "MultiVideoCallActivity"; + private static final String REMOTE_FURFACEVIEW_TAG = "surfaceview"; // + private static final String REMOTE_VIEW_TAG = "remoteview"; // rc_voip_viewlet_remote_user tag + private static final String VOIP_USERNAME_TAG = + "username"; // topContainer.findViewById(R.id.rc_voip_user_name); + private static final String VOIP_PARTICIPANT_PORTAIT_CONTAINER_TAG = + "participantPortraitView"; // 被叫方显示头像容器tag + RongCallSession callSession; + SurfaceView localView; + ContainerLayout localViewContainer; + LinearLayout remoteViewContainer; + LinearLayout remoteViewContainer2; + LinearLayout topContainer; + LinearLayout waitingContainer; + LinearLayout bottomButtonContainer; + LinearLayout participantPortraitContainer; + LinearLayout portraitContainer1; // 维护未接听时,所有成员列表 + LayoutInflater inflater; + // 通话中的最小化按钮、呼叫中的最小化按钮 + ImageView minimizeButton, rc_voip_multiVideoCall_minimize; + ImageView moreButton; + ImageView switchCameraButton; + ImageView userPortrait; + LinearLayout infoLayout; + ImageView signalView; + TextView userNameView; + private int remoteUserViewWidth; + // private int remoteUserViewHeight; + // 主叫、通话中 远端View + private float remoteUserViewMarginsRight = 10; + private float remoteUserViewMarginsLeft = 20; + + boolean isFullScreen = false; + boolean isMuteMIC = false; + boolean startForCheckPermissions = false; + + String localViewUserId; + private CallOptionMenu optionMenu; + ImageView muteButtion; + ImageView disableCameraButtion; + CallPromptDialog dialog = null; + RelativeLayout observerLayout; + private ImageView iv_large_preview_mutilvideo, iv_large_preview_Mask; + private String topUserName = "", topUserNameTag = ""; + private UserProfileOrderManager mUserProfileOrderManager; + + @Override + @TargetApi(23) + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState != null && RongCallClient.getInstance() == null) { + // 音视频请求权限时,用户在设置页面取消权限,导致应用重启,退出当前activity. + finish(); + return; + } + setContentView(R.layout.rc_voip_multi_video_call); + Intent intent = getIntent(); + startForCheckPermissions = intent.getBooleanExtra("checkPermissions", false); + boolean val = + requestCallPermissions( + RongCallCommon.CallMediaType.VIDEO, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); + RLog.i(TAG, "onCreate initViews requestCallPermissions=" + val); + if (val) { + RLog.i(TAG, "--- onCreate initViews------"); + initViews(); + setupIntent(); + } + mUserProfileOrderManager = new UserProfileOrderManager(); + } + + @Override + protected void onNewIntent(Intent intent) { + RLog.d(TAG, "onNewIntent: [intent]"); + startForCheckPermissions = intent.getBooleanExtra("checkPermissions", false); + super.onNewIntent(intent); + boolean bool = + requestCallPermissions( + RongCallCommon.CallMediaType.VIDEO, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); + RLog.i(TAG, "mult onNewIntent==" + bool); + if (bool) { + RLog.i(TAG, "mult onNewIntent initViews"); + initViews(); + setupIntent(); + } + } + + @TargetApi(23) + @Override + public void onRequestPermissionsResult( + int requestCode, String[] permissions, int[] grantResults) { + RLog.d(TAG, "onRequestPermissionsResult: " + requestCode); + switch (requestCode) { + case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: + if (RongCallPermissionUtil.checkVideoCallNeedPermission(this)) { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionGranted(); + } else { + initViews(); + setupIntent(); + } + } else { + if (permissions.length > 0) { + RongCallClient.getInstance().onPermissionDenied(); + Toast.makeText( + this, + getString(R.string.rc_voip_relevant_permissions), + Toast.LENGTH_SHORT) + .show(); + finish(); + } + } + break; + default: + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + RLog.i(TAG, "mult onActivityResult requestCode=" + requestCode); + super.onActivityResult(requestCode, resultCode, data); + callSession = RongCallClient.getInstance().getCallSession(); + if (requestCode == REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS) { + if (RongCallPermissionUtil.checkVideoCallNeedPermission(this)) { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionGranted(); + } else { + RLog.i(TAG, "mult onActivityResult initView"); + initViews(); + setupIntent(); + } + } else { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionDenied(); + } else { + finish(); + } + } + + } else if (requestCode == REQUEST_CODE_ADD_MEMBER) { + if (resultCode == RESULT_OK) { + if (data.getBooleanExtra("remote_hangup", false)) { + RLog.d(TAG, "Remote exit, end the call."); + return; + } + } + if (callSession.getEndTime() != 0) { + finish(); + return; + } + setShouldShowFloat(true); + if (resultCode == RESULT_OK) { + ArrayList invited = data.getStringArrayListExtra("invited"); + ArrayList observers = data.getStringArrayListExtra("observers"); + List callUserProfiles = callSession.getParticipantProfileList(); + Iterator iterator = invited.iterator(); + while (iterator.hasNext()) { + String id = iterator.next(); + for (CallUserProfile profile : callUserProfiles) { + if (profile.getUserId().equals(id)) { + iterator.remove(); + } + } + } + RongCallClient.getInstance() + .addParticipants(callSession.getCallId(), invited, observers); + } + } else if (requestCode == REQUEST_CODE_ADD_MEMBER_NONE) { + try { + if (callSession.getEndTime() != 0) { + finish(); + return; + } + setShouldShowFloat(true); + if (resultCode == RESULT_OK) { + ArrayList invited = data.getStringArrayListExtra("pickedIds"); + RongCallClient.getInstance() + .addParticipants(callSession.getCallId(), invited, null); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + CallKitUtils.callConnected = false; + if (localViewContainer != null) { + localViewContainer.setIsNeedFillScrren(true); + } + } + + @Override + public String onSaveFloatBoxState(Bundle bundle) { + super.onSaveFloatBoxState(bundle); + String intentAction = getIntent().getAction(); + bundle.putBoolean(EXTRA_BUNDLE_KEY_MUTECAMERA, isMuteCamera); + bundle.putBoolean(EXTRA_BUNDLE_KEY_MUTEMIC, isMuteMIC); + bundle.putString(EXTRA_BUNDLE_KEY_LOCALVIEWUSERID, localViewUserId); + bundle.putString(EXTRA_BUNDLE_KEY_CALLACTION, RongCallAction.ACTION_RESUME_CALL.getName()); + bundle.putInt(EXTRA_BUNDLE_KEY_MEDIATYPE, RongCallCommon.CallMediaType.VIDEO.getValue()); + bundle.putString(EXTRA_BUNDLE_KEY_USER_TOP_NAME, topUserName); + bundle.putString(EXTRA_BUNDLE_KEY_USER_TOP_NAME_TAG, topUserNameTag); + bundle.putStringArrayList( + EXTRA_BUNDLE_KEY_USER_PROFILE_TAG_ORDER_TAG, mUserProfileOrderManager.getUserIds()); + RLog.d(TAG, "onSaveFloatBoxState-->localViewUserId : " + localViewUserId); + return intentAction; + } + + @Override + public void onRestoreFloatBox(Bundle bundle) { + super.onRestoreFloatBox(bundle); + try { + RLog.i(TAG, "--- onRestoreFloatBox ------"); + callSession = RongCallClient.getInstance().getCallSession(); + if (bundle != null) { + RongCallAction callAction = RongCallAction.valueOf(bundle.getString("callAction")); + if (!callAction.equals(RongCallAction.ACTION_RESUME_CALL)) { + return; + } + + if (mUserProfileOrderManager != null) { + mUserProfileOrderManager = null; + } + mUserProfileOrderManager = + new UserProfileOrderManager( + bundle.getStringArrayList( + EXTRA_BUNDLE_KEY_USER_PROFILE_TAG_ORDER_TAG)); + localViewUserId = bundle.getString(EXTRA_BUNDLE_KEY_LOCALVIEWUSERID); + isMuteCamera = bundle.getBoolean(EXTRA_BUNDLE_KEY_MUTECAMERA); + isMuteMIC = bundle.getBoolean(EXTRA_BUNDLE_KEY_MUTEMIC); + topUserName = bundle.getString(EXTRA_BUNDLE_KEY_USER_TOP_NAME); + topUserNameTag = bundle.getString(EXTRA_BUNDLE_KEY_USER_TOP_NAME_TAG); + if (callSession == null) { + setShouldShowFloat(false); + finish(); + return; + } + + boolean isLocalViewExist = false; + for (CallUserProfile profile : callSession.getParticipantProfileList()) { + if (profile.getUserId().equals(localViewUserId)) { + isLocalViewExist = true; + break; + } + for (StreamProfile streamProfile : profile.streamProfiles) { + if (TextUtils.equals(streamProfile.streamId, localViewUserId)) { + isLocalViewExist = true; + break; + } + } + if (isLocalViewExist) { + break; + } + } + if (remoteViewContainer2 != null) { + remoteViewContainer2.removeAllViews(); + } + for (CallUserProfile profile : callSession.getParticipantProfileList()) { + String currentUserId = RongIMClient.getInstance().getCurrentUserId(); + if (profile.getUserId().equals(localViewUserId) + || (!isLocalViewExist && profile.getUserId().equals(currentUserId))) { + localView = profile.getVideoView(); + } + if (isLocalViewExist) { + for (StreamProfile streamProfile : profile.streamProfiles) { + if (TextUtils.equals(streamProfile.streamId, localViewUserId)) { + localView = streamProfile.videoView; + } + } + } + if (localView != null) { + if (localView.getParent() != null) { + ((ViewGroup) localView.getParent()).removeAllViews(); + } + String tag = (String) localView.getTag(); + localViewUserId = tag.substring(0, tag.indexOf(REMOTE_FURFACEVIEW_TAG)); + localView.setZOrderOnTop(false); + localView.setZOrderMediaOverlay(false); + localViewContainer.addView(localView); + localViewContainer.addView(getObserverLayout()); + localView.setTag( + CallKitUtils.getStitchedContent( + localViewUserId, REMOTE_FURFACEVIEW_TAG)); + TextView userNameView = + (TextView) topContainer.findViewById(R.id.rc_voip_user_name); + userNameView.setLines(1); + userNameView.setEllipsize(TextUtils.TruncateAt.END); + if (!TextUtils.isEmpty(topUserName)) { + userNameView.setTag(topUserNameTag); + userNameView.setText(CallKitUtils.nickNameRestrict(topUserName)); + } else { + userNameView.setTag( + CallKitUtils.getStitchedContent( + localViewUserId, VOIP_USERNAME_TAG)); + UserInfo userInfo = + RongUserInfoManager.getInstance().getUserInfo(localViewUserId); + if (userInfo != null) { + userNameView.setText( + CallKitUtils.nickNameRestrict(userInfo.getName())); + } else { + userNameView.setText(localViewUserId); + } + } + break; + } + } + if (!(boolean) bundle.get("isDial")) { + // 已经有用户接听 + onCallConnected(callSession, null); + } else { + // 无用户接听 + updateRemoteVideoViews(callSession); + FrameLayout bottomButtonLayout; + if (CallKitUtils.findConfigurationLanguage(MultiVideoCallActivity.this, "ar")) { + bottomButtonLayout = + (FrameLayout) + inflater.inflate( + R.layout + .rc_voip_multi_video_calling_bottom_view_rtl, + null); + } else { + bottomButtonLayout = + (FrameLayout) + inflater.inflate( + R.layout.rc_voip_multi_video_calling_bottom_view, + null); + } + bottomButtonLayout + .findViewById(R.id.rc_voip_call_mute) + .setVisibility(View.GONE); + bottomButtonLayout + .findViewById(R.id.rc_voip_disable_camera) + .setVisibility(View.GONE); + bottomButtonLayout.findViewById(R.id.rc_voip_handfree).setVisibility(View.GONE); + bottomButtonContainer.removeAllViews(); + bottomButtonContainer.addView(bottomButtonLayout); + topContainer.setVisibility(View.GONE); + waitingContainer.setVisibility(View.VISIBLE); + remoteViewContainer.setVisibility(View.VISIBLE); + participantPortraitContainer.setVisibility(View.GONE); + bottomButtonContainer.setVisibility(View.VISIBLE); + rc_voip_multiVideoCall_minimize.setVisibility(View.GONE); + + callRinging(RingingMode.Outgoing); + } + } + } catch (Exception e) { + e.printStackTrace(); + RLog.i(TAG, "MultiVideoCallActivity onRestoreFloatBox Error=" + e.getMessage()); + } + } + + private void incomingPreview() { + RongCallClient.getInstance().setEnableLocalAudio(true); + RongCallClient.getInstance().setEnableLocalVideo(true); + RongCallClient.getInstance() + .startIncomingPreview( + new StartIncomingPreviewCallback() { + @Override + public void onDone(boolean isFront, SurfaceView localVideo) { + localView = localVideo; + ((RCRTCVideoView) localView) + .setScalingType( + RendererCommon.ScalingType.SCALE_ASPECT_BALANCED); + // localView.setZOrderOnTop(true); + // localView.setZOrderMediaOverlay(true); + ViewParent parent = localView.getParent(); + if (parent != null) { + ((ViewGroup) parent).removeView(localView); + } + localViewContainer.addView(localView); + + // 加载观察者布局 默认不显示 + localViewContainer.addView(getObserverLayout()); + localViewUserId = RongIMClient.getInstance().getCurrentUserId(); + localView.setTag( + CallKitUtils.getStitchedContent( + localViewUserId, REMOTE_FURFACEVIEW_TAG)); + } + + @Override + public void onError(int errorCode) {} + }); + } + + /** + * 电话已拨出。 主叫端拨出电话后 + * + * @param callSession 通话实体。 + * @param localVideo 本地 camera 信息。 + */ + @Override + public void onCallOutgoing(final RongCallSession callSession, SurfaceView localVideo) { + super.onCallOutgoing(callSession, localVideo); + this.callSession = callSession; + RongCallClient.getInstance().setEnableLocalAudio(true); + RongCallClient.getInstance().setEnableLocalVideo(true); + localView = localVideo; + callRinging(RingingMode.Outgoing); + ((RCRTCVideoView) localView) + .setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_BALANCED); + // localView.setZOrderOnTop(true); + // localView.setZOrderMediaOverlay(true); + localViewContainer.addView(localView); + + // 加载观察者布局 默认不显示 + localViewContainer.addView(getObserverLayout()); + + localViewUserId = RongIMClient.getInstance().getCurrentUserId(); + localView.setTag(CallKitUtils.getStitchedContent(localViewUserId, REMOTE_FURFACEVIEW_TAG)); + } + + @Override + public void onFirstRemoteVideoFrame(String userId, int height, int width) { + RLog.d("bugtags", "onFirstRemoteVideoFrame,uid :" + userId); + if (remoteViewContainer2 == null) { + RLog.e( + "bugtags", + "onFirstRemoteVideoFrame()->remoteViewContainer2 is empty.userId : " + userId); + return; + } + + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(userId, REMOTE_VIEW_TAG)); + if (singleRemoteView == null) { + RLog.e("bugtags", "onFirstRemoteVideoFrame(). singleRemoteView is empty"); + + if (localViewContainer == null || localViewContainer.getChildCount() == 0) { + RLog.e("bugtags", "onFirstRemoteVideoFrame(). localViewContainer is empty"); + } else { + for (int i = 0; i < localViewContainer.getChildCount(); i++) { + if (localViewContainer.getChildAt(i) instanceof RCRTCVideoView) { + ((RCRTCVideoView) localViewContainer.getChildAt(i)).setZOrderOnTop(false); + ((RCRTCVideoView) localViewContainer.getChildAt(i)) + .setZOrderMediaOverlay(false); + ((RCRTCVideoView) localViewContainer.getChildAt(i)) + .setBackgroundColor(Color.TRANSPARENT); + break; + } + } + } + return; + } + View stateView = singleRemoteView.findViewById(R.id.user_status); + if (stateView != null) { + stateView.setVisibility(View.GONE); + } + + FrameLayout remoteVideoView = + (FrameLayout) singleRemoteView.findViewById(R.id.viewlet_remote_video_user); + if (remoteVideoView == null) { + return; + } + int childCount = remoteVideoView.getChildCount(); + for (int i = 0; i < childCount; i++) { + if (remoteVideoView.getChildAt(i) != null + && remoteVideoView.getChildAt(i) instanceof RCRTCVideoView) { + // if (!TextUtils.equals(Build.MODEL, "PEPM00")) { + // ((RCRTCVideoView) + // remoteVideoView.getChildAt(i)).setZOrderOnTop(true); + // ((RCRTCVideoView) + // remoteVideoView.getChildAt(i)).setZOrderMediaOverlay(true); + // } + remoteVideoView.getChildAt(i).setBackgroundColor(Color.TRANSPARENT); + break; + } + } + + TextView textView = singleRemoteView.findViewById(R.id.user_name); + textView.setVisibility(View.VISIBLE); + } + + /** + * 被叫端加入通话。 主叫端拨出电话,被叫端收到请求后,加入通话,回调 onRemoteUserJoined。 + * + * @param userId 加入用户的 id。 + * @param mediaType 加入用户的媒体类型,audio or video。 + * @param userType 加入用户的类型,1:正常用户,2:观察者。 + * @param remoteVideo 加入用户者的 camera 信息。 + */ + @Override + public void onRemoteUserJoined( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + remoteVideo.setBackgroundColor(Color.BLACK); + stopRing(); + if (localViewContainer != null && localViewContainer.getVisibility() != View.VISIBLE) { + localViewContainer.setVisibility(View.VISIBLE); + if (null != iv_large_preview_mutilvideo) { + iv_large_preview_mutilvideo.setVisibility(View.GONE); + } + if (null != iv_large_preview_Mask) { + iv_large_preview_Mask.setVisibility(View.GONE); + } + } + if (localViewUserId != null && localViewUserId.equals(userId)) { + return; + } + View singleRemoteView = + remoteViewContainer.findViewWithTag( + CallKitUtils.getStitchedContent(userId, REMOTE_VIEW_TAG)); + + if (singleRemoteView == null) { + singleRemoteView = addSingleRemoteView(userId, userType); + } + addRemoteVideo(singleRemoteView, remoteVideo, userId, false); + singleRemoteView.findViewById(R.id.user_status).setVisibility(View.GONE); + singleRemoteView.findViewById(R.id.user_name).setVisibility(View.GONE); + } + + @Override + public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) { + // 通话过程中 toast "通话结束"有些突兀,所以只有远端忙线和拒绝时我们提醒用户 + if (reason.equals(RongCallCommon.CallDisconnectedReason.REMOTE_BUSY_LINE) + || reason.equals(RongCallCommon.CallDisconnectedReason.REMOTE_REJECT)) { + super.onRemoteUserLeft(userId, reason); + } + if (isTopContainerUserExit(userId)) { + return; + } + String delUserid = userId; + // incomming state + if (participantPortraitContainer != null + && participantPortraitContainer.getVisibility() == View.VISIBLE) { + View participantView = + participantPortraitContainer.findViewWithTag( + CallKitUtils.getStitchedContent( + userId, VOIP_PARTICIPANT_PORTAIT_CONTAINER_TAG)); + if (participantView == null) { + return; + } + LinearLayout portraitContainer = (LinearLayout) participantView.getParent(); + portraitContainer.removeView(participantView); + } + // incoming状态,localViewUserId为空 + if (localViewUserId == null) { + return; + } + if (localViewUserId.equals(userId)) { + localViewContainer.removeAllViews(); + delUserid = RongIMClient.getInstance().getCurrentUserId(); + // 拿到本地视频流装载对象 + FrameLayout remoteVideoView = + (FrameLayout) remoteViewContainer.findViewWithTag(delUserid); + localView = (SurfaceView) remoteVideoView.getChildAt(0); + remoteVideoView.removeAllViews(); + localView.setZOrderOnTop(false); + localViewContainer.addView(localView); // 将本地的给大屏 + + localViewContainer.addView(getObserverLayout()); + + TextView topUserNameView = (TextView) topContainer.findViewById(R.id.rc_voip_user_name); + topUserNameView.setTag(CallKitUtils.getStitchedContent(delUserid, VOIP_USERNAME_TAG)); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(delUserid); + if (userInfo != null) { + topUserNameView.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + } else { + topUserNameView.setText(delUserid); + } + localViewUserId = delUserid; + } + if (remoteViewContainer2 != null && !TextUtils.isEmpty(delUserid)) { // 删除退出用户的头像框 + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(delUserid, REMOTE_VIEW_TAG)); + if (singleRemoteView == null) { + return; + } + remoteViewContainer2.removeView(singleRemoteView); + } + } + + private boolean isTopContainerUserExit(String userId) { + if (CallKitUtils.callConnected) { + return false; + } + if (callSession != null + && TextUtils.equals(callSession.getInviterUserId(), userId) + && portraitContainer1 != null) { + View userPortraitView = portraitContainer1.getChildAt(0); + if (userPortraitView != null && userPortraitView.getTag() != null) { + String tag = (String) userPortraitView.getTag(); + String firstUserId = tag.replace(VOIP_PARTICIPANT_PORTAIT_CONTAINER_TAG, ""); + UserInfo firstUserInfo = RongUserInfoManager.getInstance().getUserInfo(firstUserId); + // topContainer + TextView userNameView = + (TextView) topContainer.findViewById(R.id.rc_voip_user_name); + userNameView.setTag( + CallKitUtils.getStitchedContent(firstUserId, VOIP_USERNAME_TAG)); + if (firstUserInfo != null) { + userNameView.setText(CallKitUtils.nickNameRestrict(firstUserInfo.getName())); + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + firstUserInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + userPortrait.setVisibility(View.VISIBLE); + } else { + userNameView.setText(firstUserId); + } + // + if (participantPortraitContainer != null + && participantPortraitContainer.getVisibility() == View.VISIBLE) { + View participantView = + participantPortraitContainer.findViewWithTag( + CallKitUtils.getStitchedContent( + firstUserId, VOIP_PARTICIPANT_PORTAIT_CONTAINER_TAG)); + if (participantView != null) { + LinearLayout portraitContainer = (LinearLayout) participantView.getParent(); + portraitContainer.removeView(participantView); + } + } + // + View firstView = portraitContainer1.getChildAt(0); + LinearLayout.LayoutParams layoutParams = (LayoutParams) firstView.getLayoutParams(); + layoutParams.setMargins( + CallKitUtils.dp2px(remoteUserViewMarginsLeft, MultiVideoCallActivity.this), + 0, + CallKitUtils.dp2px(remoteUserViewMarginsRight, MultiVideoCallActivity.this), + 0); + firstView.requestLayout(); + return true; + } + } + return false; + } + + private ArrayList getInvitedList() { + ArrayList invitedList = new ArrayList<>(); + List list = callSession.getParticipantProfileList(); + List incomingObserverUserList = callSession.getObserverUserList(); + for (CallUserProfile profile : list) { + if (!profile.getUserId().equals(callSession.getCallerUserId())) { + if (null != incomingObserverUserList + && !incomingObserverUserList.contains(profile.getUserId())) { + invitedList.add(profile.getUserId()); + } + } + } + return invitedList; + } + + @Override + public void onRemoteUserPublishVideoStream( + String userId, String streamId, String tag, SurfaceView surfaceView) { + if (TextUtils.equals(userId, localViewUserId)) { + return; + } + View singleRemoteView = null; + if (remoteViewContainer2 != null) { + // 先去找是否已经添加了对方的viewGroup,没有再创建 + singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(userId, REMOTE_VIEW_TAG)); + } + if (singleRemoteView == null) { + singleRemoteView = addSingleRemoteView(userId, 1); + } + singleRemoteView.findViewById(R.id.user_status).setVisibility(View.GONE); + singleRemoteView.findViewById(R.id.user_portrait).setVisibility(View.GONE); + singleRemoteView.findViewById(R.id.user_name).setVisibility(View.GONE); + // 把最新的 surfaceView 展示出来,onRemoteUserJoined 返回的 surfaceView 已经失效了,流被绑定到新的 surfaceView 上了 + addRemoteVideo(singleRemoteView, surfaceView, userId, true); + } + + @Override + public void onRemoteUserUnpublishVideoStream(String userId, String streamId, String tag) { + if (remoteViewContainer2 != null) { // 删除退出用户的头像框 + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(streamId, REMOTE_VIEW_TAG)); + if (singleRemoteView == null) { + onRemoteUserLeft(streamId, RongCallCommon.CallDisconnectedReason.HANGUP); + } else { + remoteViewContainer2.removeView(singleRemoteView); + } + } + } + + /** + * @param userId + * @param mediaType + */ + @Override + public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) { + super.onRemoteUserInvited(userId, mediaType); + if (callSession != null) { + for (CallUserProfile profile : callSession.getParticipantProfileList()) { + if (profile.getUserId().equals(RongIMClient.getInstance().getCurrentUserId())) { + if (profile.getCallStatus().equals(RongCallCommon.CallStatus.CONNECTED)) { + int callUserType = 1; + if (callSession.getObserverUserList() != null + && callSession.getObserverUserList().contains(userId)) { + callUserType = 2; + } + addSingleRemoteView(userId, callUserType); + } + } + } + } + } + + /** + * 已建立通话。 通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息。 + * + * @param callSession 通话实体。 + * @param localVideo 本地 camera 信息。 + */ + @SuppressLint("NewApi") + @Override + public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) { + super.onCallConnected(callSession, localVideo); + this.callSession = callSession; + if (null != rc_voip_multiVideoCall_minimize) { + rc_voip_multiVideoCall_minimize.setVisibility(View.GONE); + } + if (iv_large_preview_mutilvideo != null + && iv_large_preview_mutilvideo.getVisibility() == View.VISIBLE) { + iv_large_preview_mutilvideo.setVisibility(View.GONE); + } + if (null != iv_large_preview_Mask) { + iv_large_preview_Mask.setVisibility(View.GONE); + } + + if (localView == null) { + localView = localVideo; + // localView.setZOrderOnTop(true); + // localView.setZOrderMediaOverlay(true); + localViewContainer.removeAllViews(); + localViewContainer.addView(localView); + getObserverLayout(); + localViewContainer.addView(observerLayout); + observerLayout.setVisibility( + callSession.getUserType() == RongCallCommon.CallUserType.OBSERVER + ? View.VISIBLE + : View.GONE); + localViewUserId = RongIMClient.getInstance().getCurrentUserId(); + localView.setTag( + CallKitUtils.getStitchedContent(localViewUserId, REMOTE_FURFACEVIEW_TAG)); + } + + localViewContainer.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!isFullScreen) { + isFullScreen = true; + rc_voip_multiVideoCall_minimize.setVisibility(View.INVISIBLE); + topContainer.setVisibility(View.GONE); + bottomButtonContainer.setVisibility(View.GONE); + } else { + isFullScreen = false; + rc_voip_multiVideoCall_minimize.setVisibility(View.VISIBLE); + topContainer.setVisibility(View.VISIBLE); + bottomButtonContainer.setVisibility(View.VISIBLE); + } + } + }); + bottomButtonContainer.removeAllViews(); + + FrameLayout bottomButtonLayout; + if (CallKitUtils.findConfigurationLanguage(MultiVideoCallActivity.this, "ar")) { + bottomButtonLayout = + (FrameLayout) + inflater.inflate( + R.layout.rc_voip_multi_video_calling_bottom_view_rtl, null); + bottomButtonLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + } else { + bottomButtonLayout = + (FrameLayout) + inflater.inflate( + R.layout.rc_voip_multi_video_calling_bottom_view, null); + } + + RelativeLayout relativeHangup = bottomButtonLayout.findViewById(R.id.relativeHangup); + if (CallKitUtils.findConfigurationLanguage(MultiVideoCallActivity.this, "ar")) { + relativeHangup.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + } + bottomButtonContainer.addView(bottomButtonLayout); + muteButtion = bottomButtonContainer.findViewById(R.id.rc_voip_call_mute_btn); + muteButtion.setSelected(isMuteMIC); + disableCameraButtion = bottomButtonContainer.findViewById(R.id.rc_voip_disable_camera_btn); + disableCameraButtion.setSelected(isMuteCamera); + topContainer.setVisibility(View.VISIBLE); + minimizeButton.setVisibility(View.VISIBLE); + rc_voip_multiVideoCall_minimize.setVisibility(View.VISIBLE); + userPortrait.setVisibility(View.GONE); + moreButton.setVisibility(View.VISIBLE); + switchCameraButton.setVisibility(View.VISIBLE); + waitingContainer.setVisibility(View.GONE); + remoteViewContainer.setVisibility(View.VISIBLE); + participantPortraitContainer.setVisibility(View.GONE); + + userNameView = (TextView) topContainer.findViewById(R.id.rc_voip_user_name); + CallKitUtils.textViewShadowLayer(userNameView, MultiVideoCallActivity.this); + + String currentUserId = RongIMClient.getInstance().getCurrentUserId(); + if (!TextUtils.isEmpty(topUserName)) { + userNameView.setTag(topUserNameTag); + userNameView.setText(CallKitUtils.nickNameRestrict(topUserName)); + } else { + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(currentUserId); + userNameView.setTag(CallKitUtils.getStitchedContent(currentUserId, VOIP_USERNAME_TAG)); + if (userInfo != null) { + userNameView.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + } else { + userNameView.setText(currentUserId); + } + } + RelativeLayout.LayoutParams parm = + new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT); + parm.addRule(RelativeLayout.CENTER_HORIZONTAL); // ALIGN_PARENT_LEFT + parm.setMarginEnd(10); + parm.setMarginStart(20); + parm.setMargins(20, 40, 0, 0); + userNameView.setLayoutParams(parm); + + TextView remindInfo = (TextView) topContainer.findViewById(R.id.rc_voip_call_remind_info); + CallKitUtils.textViewShadowLayer(remindInfo, MultiVideoCallActivity.this); + setupTime(remindInfo); + + infoLayout = (LinearLayout) topContainer.findViewById(R.id.rc_voip_call_info_layout); + parm = + new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT); + parm.addRule(RelativeLayout.CENTER_HORIZONTAL); + parm.addRule(RelativeLayout.BELOW, userNameView.getId()); + parm.setMargins(0, 8, 0, 0); + infoLayout.setLayoutParams(parm); + + signalView = (ImageView) topContainer.findViewById(R.id.rc_voip_signal); + signalView.setVisibility(View.VISIBLE); + + updateRemoteVideoViews(callSession); + RCRTCEngine.getInstance().enableSpeaker(true); + } + + protected void resetHandFreeStatus(RCAudioRouteType type) { + ImageView handFreeV = null; + if (null != bottomButtonContainer) { + handFreeV = bottomButtonContainer.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + // 耳机状态 + if (type == RCAudioRouteType.HEADSET || type == RCAudioRouteType.HEADSET_BLUETOOTH) { + // handFreeV.setSelected(false); + } else { + // 非耳机状态 + handFreeV.setSelected(type == RCAudioRouteType.SPEAKER_PHONE); + } + } + } + + void updateRemoteVideoViews(RongCallSession callSession) { + String remoteUserID = ""; + FrameLayout remoteVideoView = null; + View singleRemoteView = null; + SurfaceView video; + List callUserProfileList = + mUserProfileOrderManager.getSortedProfileList( + callSession.getParticipantProfileList()); + for (CallUserProfile profile : callUserProfileList) { + remoteUserID = profile.getUserId(); + RLog.d( + TAG, + "remoteUserID : " + remoteUserID + " , localViewUserId : " + localViewUserId); + if (remoteUserID.equals(localViewUserId) + || profile.getUserType() == RongCallCommon.CallUserType.OBSERVER) continue; + singleRemoteView = + remoteViewContainer.findViewWithTag( + CallKitUtils.getStitchedContent(remoteUserID, REMOTE_VIEW_TAG)); + if (singleRemoteView == null) { + int userType = 1; + if (callSession.getObserverUserList() != null + && callSession.getObserverUserList().contains(remoteUserID)) { + userType = 2; + } + singleRemoteView = addSingleRemoteView(remoteUserID, userType); + } + video = profile.getVideoView(); + if (video != null) { + remoteVideoView = (FrameLayout) remoteViewContainer.findViewWithTag(remoteUserID); + if (remoteVideoView == null) { + addRemoteVideo(singleRemoteView, video, remoteUserID, false); + } + } + for (StreamProfile streamProfile : profile.streamProfiles) { + if (TextUtils.equals(localViewUserId, streamProfile.streamId)) { + continue; + } + onRemoteUserPublishVideoStream( + streamProfile.userId, + streamProfile.streamId, + streamProfile.tag, + streamProfile.videoView); + } + if (profile.drawed() + || TextUtils.equals( + profile.getUserId(), RongIMClient.getInstance().getCurrentUserId())) { + View statusView = singleRemoteView.findViewById(R.id.user_status); + if (statusView != null) { + statusView.setVisibility(View.GONE); + } + } + } + } + + /** + * 添加 远端视频流 至singleRemoteView 的FrameLayout中,并缓存最新的远端用户头像 + * + * @param userId 自定义流时,传入的是streamID + */ + void addRemoteVideo( + View singleRemoteView, SurfaceView video, String userId, boolean isStreamId) { + if (singleRemoteView == null) return; + String realUserId = userId; + String streamTag = RCRTCStream.RONG_TAG; + if (isStreamId) { + realUserId = Utils.parseUserId(userId); + streamTag = Utils.parseTag(userId); + } + FinLog.d(TAG, "addRemoteVideo realUserId = " + realUserId + " streamTag = " + streamTag); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(realUserId); + FrameLayout remoteVideoView = + (FrameLayout) singleRemoteView.findViewById(R.id.viewlet_remote_video_user); + + remoteVideoView.removeAllViews(); + ImageView userPortraitView = (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + if (userInfo != null) { + GlideUtils.showPortrait(getBaseContext(), userPortraitView, userInfo.getPortraitUri()); + } + if (video.getParent() != null) { + ((ViewGroup) video.getParent()).removeView(video); + } + video.setTag(CallKitUtils.getStitchedContent(userId, REMOTE_FURFACEVIEW_TAG)); + if (TextUtils.equals(RONG_TAG_CALL, streamTag)) { + ((RCRTCVideoView) video).setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL); + } else { + ((RCRTCVideoView) video).setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); + } + remoteVideoView.addView( + video, + new FrameLayout.LayoutParams( + remoteUserViewWidth, remoteUserViewWidth, Gravity.CENTER)); + + TextView remoteNameTextView = (TextView) singleRemoteView.findViewById(R.id.user_name); + if (userInfo != null) { + remoteNameTextView.setText(userInfo.getName()); + } else { + remoteNameTextView.setText(userId); + } + CallKitUtils.textViewShadowLayer(remoteNameTextView, MultiVideoCallActivity.this); + remoteNameTextView.setVisibility(View.VISIBLE); + remoteVideoView.setVisibility(View.VISIBLE); + remoteVideoView.setTag(userId); + } + + /** + * 根据userid创建RemoteView显示头像,并添加至远端View容器 + * + * @param userId 用户id + * @param userType 加入用户的类型,1:正常用户,2:观察者。 + * @return + */ + View addSingleRemoteView(String userId, int userType) { + View singleRemoteView = inflater.inflate(R.layout.rc_voip_viewlet_remote_user, null); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(userId); + singleRemoteView.setTag(CallKitUtils.getStitchedContent(userId, REMOTE_VIEW_TAG)); + TextView userStatus = (TextView) singleRemoteView.findViewById(R.id.user_status); + CallKitUtils.textViewShadowLayer(userStatus, MultiVideoCallActivity.this); + TextView nameView = (TextView) singleRemoteView.findViewById(R.id.user_name); + ImageView userPortraitView = (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + if (userInfo != null) { + GlideUtils.showPortrait(getBaseContext(), userPortraitView, userInfo.getPortraitUri()); + if (!TextUtils.isEmpty(userInfo.getName())) { + nameView.setText(userInfo.getName()); + } + } + LinearLayout.LayoutParams params = + new LinearLayout.LayoutParams(remoteUserViewWidth, remoteUserViewWidth); + params.setMargins( + 0, + 0, + CallKitUtils.dp2px(remoteUserViewMarginsRight, MultiVideoCallActivity.this), + 0); + remoteViewContainer2.addView(singleRemoteView, params); + if (userType == 2) { + singleRemoteView.setVisibility(View.GONE); + } + return singleRemoteView; + } + + /** + * 根据userid创建每个正常视频用户的RemoteView头像,并添加至远端View容器 观察者不显示头像 + * + * @param userId 用户id + * @param i 控制第一个头像边距位置 + */ + private void createAddSingleRemoteView(String userId, int i) { + View singleRemoteView = inflater.inflate(R.layout.rc_voip_viewlet_remote_user, null); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(userId); + singleRemoteView.setTag(CallKitUtils.getStitchedContent(userId, REMOTE_VIEW_TAG)); + TextView userStatus = (TextView) singleRemoteView.findViewById(R.id.user_status); + CallKitUtils.textViewShadowLayer(userStatus, MultiVideoCallActivity.this); + ImageView userPortraitView = (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + TextView nameView = (TextView) singleRemoteView.findViewById(R.id.user_name); + if (userInfo != null) { + GlideUtils.showPortrait(getBaseContext(), userPortraitView, userInfo.getPortraitUri()); + if (!TextUtils.isEmpty(userInfo.getName())) { + nameView.setText(userInfo.getName()); + } + } + LinearLayout.LayoutParams params = + new LinearLayout.LayoutParams(remoteUserViewWidth, remoteUserViewWidth); + if (i == 0) { + params.setMargins( + CallKitUtils.dp2px(remoteUserViewMarginsLeft, MultiVideoCallActivity.this), + 0, + CallKitUtils.dp2px(remoteUserViewMarginsRight, MultiVideoCallActivity.this), + 0); + } else { + params.setMargins( + 0, + 0, + CallKitUtils.dp2px(remoteUserViewMarginsRight, MultiVideoCallActivity.this), + 0); + } + remoteViewContainer2.addView(singleRemoteView, params); + } + + @Override + public void onCallDisconnected( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + isFinishing = true; + if (reason == null || callSession == null) { + RLog.e(TAG, "onCallDisconnected. callSession is null!"); + postRunnableDelay( + new Runnable() { + @Override + public void run() { + finish(); + } + }); + return; + } + + MultiCallEndMessage multiCallEndMessage = new MultiCallEndMessage(); + multiCallEndMessage.setMediaType(IRongCoreEnum.MediaType.VIDEO); + multiCallEndMessage.setReason(reason); + long serverTime = System.currentTimeMillis() - RongIMClient.getInstance().getDeltaTime(); + IMCenter.getInstance() + .insertIncomingMessage( // + callSession.getConversationType(), // + callSession.getTargetId(), // + callSession.getCallerUserId(), // + CallKitUtils.getReceivedStatus(reason), // + multiCallEndMessage, // + serverTime, // + null); // + cancelTime(); + stopRing(); + postRunnableDelay( + new Runnable() { + @Override + public void run() { + finish(); + } + }); + super.onCallDisconnected(callSession, reason); + sendBroadcast(new Intent(DISCONNECT_ACTION).setPackage(getPackageName())); + } + + @Override + public void onRemoteCameraDisabled(String userId, boolean disabled) { + if (!disabled) { + if (localViewUserId.equals(userId)) { + localView.setBackgroundColor(Color.TRANSPARENT); + } else { + View remoteView = + remoteViewContainer.findViewWithTag( + CallKitUtils.getStitchedContent(userId, REMOTE_FURFACEVIEW_TAG)); + if (remoteView != null) { + remoteView.setBackgroundColor(Color.TRANSPARENT); + } + } + } else { + if (localViewUserId.equals(userId)) { + localView.setBackgroundColor(Color.BLACK); + } else { + View remoteView = + remoteViewContainer.findViewWithTag( + CallKitUtils.getStitchedContent(userId, REMOTE_FURFACEVIEW_TAG)); + if (remoteView != null) { + remoteView.setBackgroundColor(Color.BLACK); + } + } + } + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(userId, REMOTE_VIEW_TAG)); + if (singleRemoteView != null) { + ImageView userPortraitView = + (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + userPortraitView.setVisibility(disabled ? View.VISIBLE : View.GONE); + TextView tv = (TextView) singleRemoteView.findViewById(R.id.user_name); + tv.setVisibility(View.VISIBLE); + } else { + RLog.e(TAG, "onRemoteCameraDisabled->singleRemoteView is empty"); + } + } + + @Override + public void onNetworkSendLost(int lossRate, int delay) { + super.onNetworkSendLost(lossRate, delay); + } + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) { + final int resId; + if (signalView != null) { + if (lossRate < 5) { + resId = R.drawable.rc_voip_signal_1; + } else if (lossRate < 15) { + resId = R.drawable.rc_voip_signal_2; + } else if (lossRate < 30) { + resId = R.drawable.rc_voip_signal_3; + } else if (lossRate < 45) { + resId = R.drawable.rc_voip_signal_4; + } else { + resId = R.drawable.rc_voip_signal_5; + } + signalView.post( + new Runnable() { + @Override + public void run() { + signalView.setImageResource(resId); + } + }); + } + } + + protected void initViews() { + RLog.i(TAG, "---------- initViews ---------------"); + inflater = LayoutInflater.from(this); + localViewContainer = (ContainerLayout) findViewById(R.id.rc_local_user_view); + remoteViewContainer = (LinearLayout) findViewById(R.id.rc_remote_user_container); + remoteViewContainer2 = (LinearLayout) findViewById(R.id.rc_remote_user_container_2); + topContainer = (LinearLayout) findViewById(R.id.rc_top_container); + topContainer.setVisibility(View.VISIBLE); + waitingContainer = (LinearLayout) findViewById(R.id.rc_waiting_container); + bottomButtonContainer = (LinearLayout) findViewById(R.id.rc_bottom_button_container); + participantPortraitContainer = + (LinearLayout) findViewById(R.id.rc_participant_portait_container); + portraitContainer1 = + (LinearLayout) + participantPortraitContainer.findViewById( + R.id.rc_participant_portait_container_1); + minimizeButton = (ImageView) findViewById(R.id.rc_voip_call_minimize); + rc_voip_multiVideoCall_minimize = + (ImageView) findViewById(R.id.rc_voip_multiVideoCall_minimize); + userPortrait = (ImageView) findViewById(R.id.rc_voip_user_portrait); + moreButton = (ImageView) findViewById(R.id.rc_voip_call_more); + switchCameraButton = (ImageView) findViewById(R.id.rc_voip_switch_camera); + iv_large_preview_mutilvideo = (ImageView) findViewById(R.id.iv_large_preview_mutilvideo); + iv_large_preview_Mask = (ImageView) findViewById(R.id.iv_large_preview_Mask); + + DisplayMetrics metrics = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(metrics); + remoteUserViewWidth = (metrics.widthPixels - 50) / 4; + + localView = null; + localViewContainer.removeAllViews(); + remoteViewContainer2.removeAllViews(); + portraitContainer1.removeAllViews(); + + minimizeButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + MultiVideoCallActivity.super.onMinimizeClick(v); + } + }); + rc_voip_multiVideoCall_minimize.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + MultiVideoCallActivity.super.onMinimizeClick(v); + } + }); + } + + protected void setupIntent() { + Intent intent = getIntent(); + RongCallAction callAction = RongCallAction.valueOf(intent.getStringExtra("callAction")); + if (callAction == null || callAction.equals(RongCallAction.ACTION_RESUME_CALL)) { + return; + } + ArrayList invitedList = new ArrayList<>(); + ArrayList observerList = new ArrayList<>(); + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + callSession = intent.getParcelableExtra("callSession"); + // 正常在收到呼叫后,RongCallClient 和 CallSession均不会为空 + if (RongCallClient.getInstance() == null + || RongCallClient.getInstance().getCallSession() == null) { + // 如果为空 表示通话已经结束 但依然启动了本页面,这样会导致页面无法销毁问题 + // 所以 需要在这里 finish 结束当前页面 推荐开发者在结束当前页面前跳转至APP主页或者其他页面 + RLog.e( + TAG, + "MultiVideoCallActivity#setupIntent()->RongCallClient or CallSession is empty---->finish()"); + finish(); + return; + } + + onIncomingCallRinging(callSession); + TextView callRemindInfoView = + (TextView) topContainer.findViewById(R.id.rc_voip_call_remind_info); + TextView userNameView = (TextView) topContainer.findViewById(R.id.rc_voip_user_name); + callRemindInfoView.setText(R.string.rc_voip_video_call_inviting); + if (callSession != null) { + if (!RongCallClient.getInstance().canCallContinued(callSession.getCallId())) { + RLog.w(TAG, "Already received hangup message before, finish current activity"); + ReportUtil.libStatus( + ReportUtil.TAG.ACTIVITYFINISH, "reason", "canCallContinued not"); + finish(); + return; + } + UserInfo userInfo = + RongUserInfoManager.getInstance() + .getUserInfo(callSession.getInviterUserId()); + userNameView.setTag( + CallKitUtils.getStitchedContent( + callSession.getInviterUserId(), VOIP_USERNAME_TAG)); + if (userInfo != null) { + userNameView.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + userPortrait.setVisibility(View.VISIBLE); + // + // GlideUtils.showPortrait(MultiVideoCallActivity.this,iv_large_preview_mutilvideo,null!=userInfo?userInfo.getPortraitUri():null); + // iv_large_preview_mutilvideo.setVisibility(View.VISIBLE); + // iv_large_preview_Mask.setVisibility(View.VISIBLE); + } else { + userNameView.setText(callSession.getInviterUserId()); + } + invitedList = getInvitedList(); + RelativeLayout bottomButtonLayout = + (RelativeLayout) + inflater.inflate( + R.layout.rc_voip_call_bottom_incoming_button_layout, null); + ImageView answerV = + (ImageView) bottomButtonLayout.findViewById(R.id.rc_voip_call_answer_btn); + answerV.setImageResource(R.drawable.rc_voip_vedio_answer_selector); + bottomButtonContainer.removeAllViews(); + bottomButtonContainer.addView(bottomButtonLayout); + + for (int i = 0; i < invitedList.size(); i++) { + boolean bool = invitedList.get(i).equals(callSession.getCallerUserId()); + if (bool) { + continue; + } + View userPortraitView = inflater.inflate(R.layout.rc_voip_user_portrait, null); + ImageView portraitView = + (ImageView) userPortraitView.findViewById(R.id.rc_user_portrait); + userInfo = RongUserInfoManager.getInstance().getUserInfo(invitedList.get(i)); + if (userInfo != null) { + GlideUtils.showPortrait( + getBaseContext(), portraitView, userInfo.getPortraitUri()); + } + LinearLayout.LayoutParams params = + new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + if (i == 0 && !bool) { + params.setMargins( + CallKitUtils.dp2px( + remoteUserViewMarginsLeft, MultiVideoCallActivity.this), + 0, + CallKitUtils.dp2px( + remoteUserViewMarginsRight, MultiVideoCallActivity.this), + 0); + } else { + params.setMargins( + 0, + 0, + CallKitUtils.dp2px( + remoteUserViewMarginsRight, MultiVideoCallActivity.this), + 0); + } + portraitContainer1.addView(userPortraitView, params); + userPortraitView.setTag( + CallKitUtils.getStitchedContent( + invitedList.get(i), VOIP_PARTICIPANT_PORTAIT_CONTAINER_TAG)); + } + } + + topContainer.setVisibility(View.VISIBLE); + minimizeButton.setVisibility(View.GONE); + rc_voip_multiVideoCall_minimize.setVisibility(View.GONE); + moreButton.setVisibility(View.GONE); + switchCameraButton.setVisibility(View.GONE); + waitingContainer.setVisibility(View.GONE); + remoteViewContainer.setVisibility(View.GONE); + participantPortraitContainer.setVisibility(View.VISIBLE); + bottomButtonContainer.setVisibility(View.VISIBLE); + incomingPreview(); + } else if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) { + Conversation.ConversationType conversationType = + Conversation.ConversationType.valueOf( + intent.getStringExtra("conversationType").toUpperCase(Locale.US)); + String targetId = intent.getStringExtra("targetId"); + ArrayList userIds = intent.getStringArrayListExtra("invitedUsers"); + ArrayList observerIds = intent.getStringArrayListExtra("observerUsers"); + if (observerIds != null && observerIds.size() > 0) { + observerList.addAll(observerIds); + } + + for (int i = 0; i < userIds.size(); i++) { + if (!userIds.get(i).equals(RongIMClient.getInstance().getCurrentUserId())) { + invitedList.add(userIds.get(i)); + String userId = userIds.get(i); + if (observerList.size() == 0 || !observerList.contains(userId)) { + createAddSingleRemoteView(userId, i); + } + } + } + + String groupName = ""; + Group group = RongUserInfoManager.getInstance().getGroupInfo(targetId); + if (group != null && !TextUtils.isEmpty(group.getName())) { + groupName = group.getName(); + } + RongCallClient.getInstance() + .setPushConfig( + DefaultPushConfig.getInviteConfig(this, false, false, groupName), + DefaultPushConfig.getHangupConfig(this, false, groupName)); + + RongCallClient.getInstance() + .startCall( + conversationType, + targetId, + invitedList, + observerList, + RongCallCommon.CallMediaType.VIDEO, + "multi"); + FrameLayout bottomButtonLayout; + if (CallKitUtils.findConfigurationLanguage(MultiVideoCallActivity.this, "ar")) { + bottomButtonLayout = + (FrameLayout) + inflater.inflate( + R.layout.rc_voip_multi_video_calling_bottom_view_rtl, null); + bottomButtonLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + } else { + bottomButtonLayout = + (FrameLayout) + inflater.inflate( + R.layout.rc_voip_multi_video_calling_bottom_view, null); + } + + bottomButtonLayout.findViewById(R.id.rc_voip_call_mute).setVisibility(View.GONE); + bottomButtonLayout.findViewById(R.id.rc_voip_disable_camera).setVisibility(View.GONE); + bottomButtonLayout.findViewById(R.id.rc_voip_handfree).setVisibility(View.GONE); + RelativeLayout relativeHangup = bottomButtonLayout.findViewById(R.id.relativeHangup); + if (CallKitUtils.findConfigurationLanguage(MultiVideoCallActivity.this, "ar")) { + relativeHangup.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + } + + bottomButtonContainer.removeAllViews(); + bottomButtonContainer.addView(bottomButtonLayout); + topContainer.setVisibility(View.GONE); + waitingContainer.setVisibility(View.VISIBLE); + remoteViewContainer.setVisibility(View.VISIBLE); + participantPortraitContainer.setVisibility(View.GONE); + bottomButtonContainer.setVisibility(View.VISIBLE); + rc_voip_multiVideoCall_minimize.setVisibility(View.GONE); + } + } + + /** 挂断通话 */ + public void onHangupBtnClick(View view) { + CallKitUtils.callConnected = false; + if (callSession == null || isFinishing) { + FinLog.e( + TAG, + "hangup call error: callSession=" + + (callSession == null) + + ",isFinishing=" + + isFinishing); + return; + } + stopRing(); + RongCallClient.getInstance().hangUpCall(callSession.getCallId()); + } + + /** 接听通话 */ + public void onReceiveBtnClick(View view) { + if (callSession == null || isFinishing) { + FinLog.e( + TAG, + "hangup call error: callSession=" + + (callSession == null) + + ",isFinishing=" + + isFinishing); + return; + } + RongCallClient.getInstance().acceptCall(callSession.getCallId()); + RongCallClient.getInstance().setEnableLocalAudio(true); + RongCallClient.getInstance().setEnableLocalVideo(true); + stopRing(); + } + + private void addButtionClickEvent() { + setShouldShowFloat(false); + + if (callSession.getConversationType().equals(Conversation.ConversationType.DISCUSSION)) { + RongDiscussionClient.getInstance() + .getDiscussion( + callSession.getTargetId(), + new IRongCoreCallback.ResultCallback() { + @Override + public void onSuccess(Discussion discussion) { + Intent intent = + new Intent( + MultiVideoCallActivity.this, + CallSelectMemberActivity.class); + ArrayList added = new ArrayList<>(); + List list = + RongCallClient.getInstance() + .getCallSession() + .getParticipantProfileList(); + for (CallUserProfile profile : list) { + added.add(profile.getUserId()); + } + List allObserver = + RongCallClient.getInstance() + .getCallSession() + .getObserverUserList(); + intent.putStringArrayListExtra( + "allObserver", new ArrayList<>(allObserver)); + intent.putStringArrayListExtra( + "allMembers", + (ArrayList) discussion.getMemberIdList()); + intent.putStringArrayListExtra("invitedMembers", added); + intent.putExtra( + "conversationType", + callSession.getConversationType().getValue()); + intent.putExtra( + "mediaType", + RongCallCommon.CallMediaType.VIDEO.getValue()); + startActivityForResult(intent, REQUEST_CODE_ADD_MEMBER); + } + + @Override + public void onError(IRongCoreEnum.CoreErrorCode e) {} + }); + } else if (callSession.getConversationType().equals(Conversation.ConversationType.GROUP)) { + Intent intent = new Intent(MultiVideoCallActivity.this, CallSelectMemberActivity.class); + ArrayList added = new ArrayList<>(); + List list = + RongCallClient.getInstance().getCallSession().getParticipantProfileList(); + for (CallUserProfile profile : list) { + added.add(profile.getUserId()); + } + List allObserver = + RongCallClient.getInstance().getCallSession().getObserverUserList(); + intent.putStringArrayListExtra("allObserver", new ArrayList<>(allObserver)); + intent.putStringArrayListExtra("invitedMembers", added); + intent.putExtra("callId", callSession.getCallId()); + intent.putExtra("groupId", callSession.getTargetId()); + intent.putExtra("conversationType", callSession.getConversationType().getValue()); + intent.putExtra("mediaType", RongCallCommon.CallMediaType.VIDEO.getValue()); + startActivityForResult(intent, REQUEST_CODE_ADD_MEMBER); + } else { + ArrayList added = new ArrayList<>(); + List list = + RongCallClient.getInstance().getCallSession().getParticipantProfileList(); + for (CallUserProfile profile : list) { + added.add(profile.getUserId()); + } + addMember(added); + } + } + + public void onMoreButtonClick(View view) { + optionMenu = new CallOptionMenu(MultiVideoCallActivity.this); + optionMenu.setHandUpvisibility( + callSession.getUserType() == RongCallCommon.CallUserType.OBSERVER); + optionMenu.setOnItemClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + int i = v.getId(); + if (i == R.id.voipItemAdd) { + addButtionClickEvent(); + } + optionMenu.dismiss(); + } + }); + optionMenu.showAsDropDown(moreButton, (int) moreButton.getX(), 0); + } + + @Override + protected void onAddMember(List newMemberIds) { + if (newMemberIds == null || newMemberIds.isEmpty()) { + return; + } + ArrayList added = new ArrayList<>(); + List participants = new ArrayList<>(); + List list = + RongCallClient.getInstance().getCallSession().getParticipantProfileList(); + for (CallUserProfile profile : list) { + participants.add(profile.getUserId()); + } + for (String id : newMemberIds) { + if (participants.contains(id)) { + continue; + } else { + added.add(id); + } + } + if (added.isEmpty()) { + return; + } + + RongCallClient.getInstance().addParticipants(callSession.getCallId(), added, null); + } + + public void onSwitchCameraClick(View view) { + RongCallClient.getInstance().switchCamera(); + } + + public void onMuteButtonClick(View view) { + RongCallClient.getInstance().setEnableLocalAudio(view.isSelected()); + view.setSelected(!view.isSelected()); + isMuteMIC = view.isSelected(); + } + + public void onDisableCameraBtnClick(View view) { + TextView text = + (TextView) bottomButtonContainer.findViewById(R.id.rc_voip_disable_camera_text); + String currentUserId = RongIMClient.getInstance().getCurrentUserId(); + + // false:摄像头已关闭 true:摄像头已打开 + boolean isSelected = view.isSelected(); + RongCallClient.getInstance().setEnableLocalVideo(isSelected); + RLog.d( + "onDisableCameraBtnClick", + "isSelected: " + + isSelected + + " ,localViewUserId : " + + localViewUserId + + " , currentUserId : " + + currentUserId); + + if (isSelected) { + text.setText(R.string.rc_voip_disable_camera); + if (localViewUserId.equals(currentUserId)) { + localView.setVisibility(View.VISIBLE); + } else { + remoteViewContainer + .findViewWithTag(currentUserId) + .findViewWithTag( + CallKitUtils.getStitchedContent( + currentUserId, REMOTE_FURFACEVIEW_TAG)) + .setVisibility(View.VISIBLE); + + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(currentUserId, REMOTE_VIEW_TAG)); + if (singleRemoteView != null) { + ImageView userPortraitView = + (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + if (userPortraitView != null) { + userPortraitView.setVisibility(View.GONE); + } + } + } + } else { + text.setText(R.string.rc_voip_enable_camera); + if (localViewUserId.equals(currentUserId)) { + localView.setVisibility(View.INVISIBLE); + } else { + remoteViewContainer + .findViewWithTag(currentUserId) + .findViewWithTag( + CallKitUtils.getStitchedContent( + currentUserId, REMOTE_FURFACEVIEW_TAG)) + .setVisibility(View.INVISIBLE); + + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(currentUserId, REMOTE_VIEW_TAG)); + if (singleRemoteView != null) { + ImageView userPortraitView = + (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + if (userPortraitView != null) { + userPortraitView.setVisibility(View.VISIBLE); + } + } + } + } + isMuteCamera = !isSelected; + view.setSelected(isMuteCamera); + } + + /** + * 小窗口FrameLayout点击事件 + * + * @param view + */ + public void onSwitchRemoteUsers(View view) { + String from = (String) view.getTag(); + RLog.i(TAG, "onSwitchRemoteUsers->from = " + from); + if (from == null) return; + String to = (String) localView.getTag(); + RLog.i(TAG, "onSwitchRemoteUsers->to = " + to); + to = to.substring(0, to.length() - REMOTE_FURFACEVIEW_TAG.length()); + FrameLayout frameLayout = (FrameLayout) view; + SurfaceView fromView = (SurfaceView) frameLayout.getChildAt(0); + SurfaceView toSurfaceView = localView; + if (fromView == null || toSurfaceView == null) { + return; + } + // 大屏删除frameLayout和observerLayout + localViewContainer.removeAllViews(); + // 清空小屏装载SurfaceView的FrameLayout + frameLayout.removeAllViews(); + + /** 从远端容器中取出被点击的小屏装载视频流和头像的View,并将头像修改成大屏的 */ + View singleRemoteView = + remoteViewContainer2.findViewWithTag( + CallKitUtils.getStitchedContent(from, REMOTE_VIEW_TAG)); + ImageView userPortraitView = (ImageView) singleRemoteView.findViewById(R.id.user_portrait); + + String fromUid = from; + if (from.contains(RCRTCStream.RONG_TAG) || from.contains(RONG_TAG_CALL)) { + fromUid = Utils.parseUserId(from); + } + String toUid = to; + if (to.contains(RCRTCStream.RONG_TAG) || to.contains(RONG_TAG_CALL)) { + toUid = Utils.parseUserId(to); + } + mUserProfileOrderManager.exchange(from, toUid); + + RLog.i(TAG, "onSwitchRemoteUsers->getUserInfo->fromUid : " + fromUid + " toUid : " + toUid); + UserInfo toUserInfo = RongUserInfoManager.getInstance().getUserInfo(toUid); + UserInfo fromUserInfo = RongUserInfoManager.getInstance().getUserInfo(fromUid); + String toTag = Utils.parseTag(to); + if (TextUtils.equals(toTag, RONG_TAG_CALL)) { + userPortraitView.setVisibility(View.VISIBLE); + } else { + userPortraitView.setVisibility(View.GONE); + } + + if (RongCallClient.getInstance().getCallSession() != null) { + String currentUserId = RongIMClient.getInstance().getCurrentUserId(); + for (CallUserProfile userProfile : + RongCallClient.getInstance().getCallSession().getParticipantProfileList()) { + if (TextUtils.equals(currentUserId, toUid)) { + RLog.e(TAG, "onSwitchRemoteUsers->isMuteCamera: " + isMuteCamera); + userPortraitView.setVisibility(isMuteCamera ? View.VISIBLE : View.GONE); + ImageView imageView = + bottomButtonContainer.findViewById(R.id.rc_voip_disable_camera_btn); + imageView.setSelected(isMuteCamera); + } else if (TextUtils.equals(userProfile.getUserId(), toUid)) { + userPortraitView.setVisibility( + userProfile.isCameraDisabled() ? View.VISIBLE : View.GONE); + } + } + } + + if (toUserInfo != null) { + Uri portraitUri = toUserInfo.getPortraitUri(); + GlideUtils.showPortrait(getBaseContext(), userPortraitView, portraitUri); + RLog.d( + TAG, + "onSwitchRemoteUsers-> getKitImageEngine->PortraitUri: " + + portraitUri.toString() + + " , userPortraitViewVisibility : " + + (userPortraitView.getVisibility() == View.VISIBLE) + + " , wxh: " + + userPortraitView.getWidth() + + " x " + + userPortraitView.getHeight()); + } else { + RLog.e( + TAG, + "onSwitchRemoteUsers-> toUserInfo is empty or userPortraitViewVisibility : " + + userPortraitView.getVisibility()); + } + + fromView.setZOrderOnTop(false); + fromView.setZOrderMediaOverlay(false); + localViewContainer.addView(fromView); // 将点击的小屏视频流添加至本地大容器中 + fromView.setVisibility(View.INVISIBLE); + /** 本地容器添加观察者图层 */ + getObserverLayout(); + localViewContainer.addView(observerLayout); + + if (RongCallClient.getInstance().getCallSession() != null + && RongCallClient.getInstance().getCallSession().getSelfUserId().equals(from) + && callSession.getUserType().getValue() + == RongCallCommon.CallUserType.OBSERVER.getValue()) { + observerLayout.setVisibility(View.VISIBLE); + RLog.d(TAG, "onSwitchRemoteUsers->observerLayout VISIBLE"); + } else { + observerLayout.setVisibility(View.GONE); + } + + /** 将原大屏视频流添加到小屏的FrameLayout上 */ + singleRemoteView.setTag(CallKitUtils.getStitchedContent(to, REMOTE_VIEW_TAG)); + toSurfaceView.setZOrderOnTop(true); + toSurfaceView.setZOrderMediaOverlay(true); + toSurfaceView.setTag(CallKitUtils.getStitchedContent(to, REMOTE_FURFACEVIEW_TAG)); + frameLayout.addView( + toSurfaceView, + new FrameLayout.LayoutParams( + remoteUserViewWidth, remoteUserViewWidth, Gravity.CENTER)); + + TextView tv = (TextView) singleRemoteView.findViewById(R.id.user_name); + if (toUserInfo != null && !TextUtils.isEmpty(toUserInfo.getName())) { + tv.setText(toUserInfo.getName()); + } else { + FinLog.e(TAG, "onSwitchRemoteUsers->toUserInfo or getName is empty"); + tv.setText(to); + } + CallKitUtils.textViewShadowLayer(tv, MultiVideoCallActivity.this); + tv.setVisibility(View.VISIBLE); + + TextView topUserNameView = (TextView) topContainer.findViewById(R.id.rc_voip_user_name); + CallKitUtils.textViewShadowLayer(topUserNameView, MultiVideoCallActivity.this); + + topUserNameView.setTag(CallKitUtils.getStitchedContent(from, VOIP_USERNAME_TAG)); + topUserNameView.setLines(1); + topUserNameView.setEllipsize(TextUtils.TruncateAt.END); + if (fromUserInfo != null && !TextUtils.isEmpty(fromUserInfo.getName())) { + topUserNameView.setText(CallKitUtils.nickNameRestrict(fromUserInfo.getName())); + } else { + topUserNameView.setText(from); + } + topUserName = topUserNameView.getText().toString(); + topUserNameTag = topUserNameView.getTag().toString(); + frameLayout.setTag(to); + localView = fromView; + localView.setTag(CallKitUtils.getStitchedContent(from, REMOTE_FURFACEVIEW_TAG)); + localViewUserId = from; + + Handler handler = new Handler(); + handler.postDelayed( + new Runnable() { + @Override + public void run() { + localView.setVisibility(View.VISIBLE); + } + }, + 30); + } + + @Override + public void onBackPressed() { + return; + } + + @Override + public void onUserUpdate(UserInfo userInfo) { + if (isFinishing() || inflater == null) { + return; + } + if (participantPortraitContainer.getVisibility() == View.VISIBLE) { + View participantView = + participantPortraitContainer.findViewWithTag( + CallKitUtils.getStitchedContent( + userInfo.getUserId(), VOIP_PARTICIPANT_PORTAIT_CONTAINER_TAG)); + if (participantView != null) { + ImageView portraitView = + (ImageView) participantView.findViewById(R.id.rc_user_portrait); + GlideUtils.showPortrait(getBaseContext(), portraitView, userInfo.getPortraitUri()); + } + } + if (remoteViewContainer.getVisibility() == View.VISIBLE) { + View remoteView = + remoteViewContainer.findViewWithTag( + CallKitUtils.getStitchedContent(userInfo.getUserId(), REMOTE_VIEW_TAG)); + if (remoteView != null) { + ImageView portraitView = (ImageView) remoteView.findViewById(R.id.user_portrait); + GlideUtils.showPortrait(getBaseContext(), portraitView, userInfo.getPortraitUri()); + } + } + if (topContainer.getVisibility() == View.VISIBLE) { + TextView nameView = + (TextView) + topContainer.findViewWithTag( + CallKitUtils.getStitchedContent( + userInfo.getUserId(), VOIP_USERNAME_TAG)); + if (nameView != null && userInfo.getName() != null) + nameView.setText(userInfo.getName()); + } + } + + public void onHeadsetPlugUpdate(HeadsetInfo headsetInfo) { + if (headsetInfo == null || !BluetoothUtil.isForground(MultiVideoCallActivity.this)) { + FinLog.v(TAG, "MultiVideoCallActivity is not in the foreground!!"); + return; + } + RLog.i( + TAG, + "Insert=" + + headsetInfo.isInsert() + + ",headsetInfo.getType=" + + headsetInfo.getType().getValue()); + try { + if (headsetInfo.isInsert()) { + RongCallClient.getInstance().setEnableSpeakerphone(false); + ImageView handFreeV = null; + if (null != bottomButtonContainer) { + handFreeV = bottomButtonContainer.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + handFreeV.setSelected(false); + handFreeV.setEnabled(false); + handFreeV.setClickable(false); + } + if (headsetInfo.getType() == HeadsetInfo.HeadsetType.BluetoothA2dp) { + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + am.setMode(AudioManager.MODE_IN_COMMUNICATION); + am.startBluetoothSco(); + am.setBluetoothScoOn(true); + am.setSpeakerphoneOn(false); + } + } else { + if (headsetInfo.getType() == HeadsetInfo.HeadsetType.WiredHeadset + && BluetoothUtil.hasBluetoothA2dpConnected()) { + return; + } + RongCallClient.getInstance().setEnableSpeakerphone(true); + ImageView handFreeV = bottomButtonContainer.findViewById(R.id.rc_voip_handfree_btn); + if (handFreeV != null) { + handFreeV.setSelected(true); + handFreeV.setEnabled(true); + handFreeV.setClickable(true); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private RelativeLayout getObserverLayout() { + observerLayout = (RelativeLayout) inflater.inflate(R.layout.rc_voip_observer_hint, null); + RelativeLayout.LayoutParams param = + new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.MATCH_PARENT, + RelativeLayout.LayoutParams.MATCH_PARENT); + observerLayout.setGravity(Gravity.CENTER); + observerLayout.setLayoutParams(param); + return observerLayout; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/PickupDetector.java b/callkit/src/main/java/io/rong/callkit/PickupDetector.java new file mode 100644 index 000000000..dae818003 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/PickupDetector.java @@ -0,0 +1,62 @@ +package io.rong.callkit; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class PickupDetector { + + private SensorManager manager; + private Sensor mProximitysensor; + + private boolean isPickUp; + private PickupDetectListener listener; + + public PickupDetector(Context context) { + + manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + if (manager != null) { + mProximitysensor = manager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + } + } + + SensorEventListener sensorEventListener = + new SensorEventListener() { + @Override + public void onSensorChanged(SensorEvent sensorEvent) { + + if (mProximitysensor == null) return; + + float value = sensorEvent.values[0]; + isPickUp = value < sensorEvent.sensor.getMaximumRange(); + // 打开或者关闭屏幕 + if (listener != null) { + listener.onPickupDetected(isPickUp); + } + } + + @Override + public void onAccuracyChanged(Sensor sensor, int i) {} + }; + + public void register(PickupDetectListener listener) { + this.listener = listener; + if (manager != null) { + manager.registerListener( + sensorEventListener, mProximitysensor, SensorManager.SENSOR_DELAY_FASTEST); + } + } + + public void unRegister() { + if (manager != null) { + manager.unregisterListener(sensorEventListener); + } + listener = null; // 释放引用。 + } + + public interface PickupDetectListener { + void onPickupDetected(boolean isPickingUp); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/RongCallAction.java b/callkit/src/main/java/io/rong/callkit/RongCallAction.java new file mode 100644 index 000000000..b2f867297 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongCallAction.java @@ -0,0 +1,25 @@ +package io.rong.callkit; + +/** Created by weiqinxiao on 16/3/15. */ +public enum RongCallAction { + ACTION_OUTGOING_CALL(1, "ACTION_OUTGOING_CALL"), + ACTION_INCOMING_CALL(2, "ACTION_INCOMING_CALL"), + ACTION_ADD_MEMBER(3, "ACTION_ADD_MEMBER"), + ACTION_RESUME_CALL(4, "ACTION_RESUME_CALL"); + + int value; + String msg; + + RongCallAction(int v, String msg) { + this.value = v; + this.msg = msg; + } + + public int getValue() { + return value; + } + + public String getName() { + return msg; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/RongCallCustomerHandlerListener.java b/callkit/src/main/java/io/rong/callkit/RongCallCustomerHandlerListener.java new file mode 100644 index 000000000..4f0a49c2e --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongCallCustomerHandlerListener.java @@ -0,0 +1,25 @@ +package io.rong.callkit; + +import android.content.Context; +import android.content.Intent; +import android.view.SurfaceView; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import java.util.ArrayList; +import java.util.List; + +public interface RongCallCustomerHandlerListener { + + List handleActivityResult(int requestCode, int resultCode, Intent data); + + void addMember(Context context, ArrayList currentMemberIds); + + void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType); + + void onCallConnected(RongCallSession callSession, SurfaceView localVideo); + + void onCallDisconnected( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason); + + void onCallMissed(RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason); +} diff --git a/callkit/src/main/java/io/rong/callkit/RongCallKit.java b/callkit/src/main/java/io/rong/callkit/RongCallKit.java new file mode 100644 index 000000000..769f32cb2 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongCallKit.java @@ -0,0 +1,379 @@ +package io.rong.callkit; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.widget.Toast; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallMissedListener; +import io.rong.calllib.RongCallSession; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import java.util.ArrayList; + +public class RongCallKit { + + public enum CallMediaType { + CALL_MEDIA_TYPE_AUDIO, + CALL_MEDIA_TYPE_VIDEO + } + + public interface ICallUsersProvider { + void onGotUserList(ArrayList userIds); + } + + private static GroupMembersProvider mGroupMembersProvider; + + private static RongCallCustomerHandlerListener customerHandlerListener; + private static GlideCallKitImageEngine kitImageEngine = new GlideCallKitImageEngine(); + + /** + * 发起单人通话。 + * + * @param context 上下文 + * @param targetId 目标会话 id ,单人通话为对方 UserId ,群组通话为 GroupId ,如果实现的是不基于群组的通话,那此参数无意义,传 null 即可 + * @param mediaType 会话媒体类型 + */ + public static void startSingleCall(Context context, String targetId, CallMediaType mediaType) { + startSingleCallInternal(context, targetId, mediaType, RongCallCommon.RoomType.NORMAL); + } + + /** + * 发起单人跨APP通话。 + * + * @param context 上下文 + * @param targetId 目标会话 id ,单人通话为对方 UserId + * @param mediaType 会话媒体类型 + */ + public static void startSingleCrossCall( + Context context, String targetId, CallMediaType mediaType) { + startSingleCallInternal(context, targetId, mediaType, RongCallCommon.RoomType.CROSS); + } + + private static void startSingleCallInternal( + Context context, + String targetId, + CallMediaType mediaType, + RongCallCommon.RoomType roomType) { + String action; + if (mediaType.equals(CallMediaType.CALL_MEDIA_TYPE_AUDIO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEVIDEO; + } + Intent intent = new Intent(action); + intent.putExtra( + "conversationType", Conversation.ConversationType.PRIVATE.getName().toLowerCase()); + intent.putExtra("targetId", targetId); + intent.putExtra("roomType", roomType); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.setPackage(context.getPackageName()); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * 发起多人通话 + * + * @param context 上下文 + * @param conversationType 会话类型 + * @param targetId 目标会话 id ,单人通话为对方 UserId ,群组通话为 GroupId ,如果实现的是不基于群组的通话,那此参数无意义,传 null 即可 + * @param mediaType 会话媒体类型 + * @param userIds 参与者 id 列表 + */ + public static void startMultiCall( + Context context, + Conversation.ConversationType conversationType, + String targetId, + CallMediaType mediaType, + ArrayList userIds) { + if (checkEnvironment(context, mediaType)) { + String action; + if (mediaType.equals(CallMediaType.CALL_MEDIA_TYPE_AUDIO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO; + } + + Intent intent = new Intent(action); + userIds.add(RongIMClient.getInstance().getCurrentUserId()); + intent.putExtra("conversationType", conversationType.getName().toLowerCase()); + intent.putExtra("targetId", targetId); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.setPackage(context.getPackageName()); + intent.putStringArrayListExtra("invitedUsers", userIds); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + } + + /** + * 开始多人通话。 返回当前会话用户列表提供者对象,用户拿到该对象后,异步从服务器取出当前会话用户列表后, 调用提供者中的 onGotUserList 方法,填充 + * ArrayList userIds 后,就会自动发起多人通话。 + * + * @param context 上下文 + * @param conversationType 会话类型 + * @param targetId 目标会话 id ,单人通话为对方 UserId ,群组通话为 GroupId ,如果实现的是不基于群组的通话,那此参数无意义,传 null 即可 + * @param mediaType 通话的媒体类型:CALL_MEDIA_TYPE_AUDIO, CALL_MEDIA_TYPE_VIDEO + * @return 返回当前会话用户列表提供者对象 + */ + public static ICallUsersProvider startMultiCall( + final Context context, + final Conversation.ConversationType conversationType, + final String targetId, + final CallMediaType mediaType) { + return new ICallUsersProvider() { + @Override + public void onGotUserList(ArrayList userIds) { + String action; + if (mediaType.equals(CallMediaType.CALL_MEDIA_TYPE_AUDIO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO; + } + Intent intent = new Intent(action); + userIds.add(RongIMClient.getInstance().getCurrentUserId()); + intent.putExtra("conversationType", conversationType.getName().toLowerCase()); + intent.putExtra("targetId", targetId); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.setPackage(context.getPackageName()); + intent.putStringArrayListExtra("invitedUsers", userIds); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + }; + } + + /** + * 发起的多人通话,不依赖群、讨论组等 + * + * @param context + * @param userIds 邀请的成员 + * @param oberverIds 邀请的以观察者身份加入房间的成员 + * @param mediaType + */ + public static void startMultiCall( + final Context context, + ArrayList userIds, + ArrayList oberverIds, + final CallMediaType mediaType) { + String action; + if (mediaType.equals(CallMediaType.CALL_MEDIA_TYPE_AUDIO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO; + } + Intent intent = new Intent(action); + userIds.add(RongIMClient.getInstance().getCurrentUserId()); + intent.putExtra( + "conversationType", Conversation.ConversationType.NONE.getName().toLowerCase()); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.putStringArrayListExtra("invitedUsers", userIds); + intent.putStringArrayListExtra("observerUsers", oberverIds); + intent.setPackage(context.getPackageName()); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * 发起的多人通话,不依赖群、讨论组等 + * + *

如何实现不基于于群组的voip + * + * @param context + * @param mediaType + * @return + */ + public static void startMultiCall( + final Context context, ArrayList userIds, final CallMediaType mediaType) { + String action; + if (mediaType.equals(CallMediaType.CALL_MEDIA_TYPE_AUDIO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO; + } + Intent intent = new Intent(action); + userIds.add(RongIMClient.getInstance().getCurrentUserId()); + intent.putExtra( + "conversationType", Conversation.ConversationType.NONE.getName().toLowerCase()); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.putStringArrayListExtra("invitedUsers", userIds); + intent.setPackage(context.getPackageName()); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * 检查应用音视频授权信息 检查网络连接状态 检查是否在通话中 + * + * @param context 启动的 activity + * @param mediaType 启动音视频的媒体类型 + * @return 是否允许启动通话界面 + */ + private static boolean checkEnvironment(Context context, CallMediaType mediaType) { + if (context instanceof Activity) { + boolean result = + RongCallPermissionUtil.checkPermissionByType( + context, + mediaType == CallMediaType.CALL_MEDIA_TYPE_AUDIO + ? RongCallCommon.CallMediaType.AUDIO + : RongCallCommon.CallMediaType.VIDEO); + if (!result) { + return false; + } + } + + if (isInVoipCall(context)) { + return false; + } + if (!RongIMClient.getInstance() + .getCurrentConnectionStatus() + .equals(RongIMClient.ConnectionStatusListener.ConnectionStatus.CONNECTED)) { + Toast.makeText( + context, + context.getResources().getString(R.string.rc_voip_call_network_error), + Toast.LENGTH_SHORT) + .show(); + return false; + } + return true; + } + + /** + * 是否在VOIP通话中 + * + * @param context + * @return 是否在VOIP通话中 + */ + public static boolean isInVoipCall(Context context) { + RongCallSession callSession = RongCallClient.getInstance().getCallSession(); + if (callSession != null && callSession.getStartTime() > 0) { + Toast.makeText( + context, + callSession.getMediaType() == RongCallCommon.CallMediaType.AUDIO + ? context.getResources() + .getString(R.string.rc_voip_call_audio_start_fail) + : context.getResources() + .getString(R.string.rc_voip_call_video_start_fail), + Toast.LENGTH_SHORT) + .show(); + return true; + } + return false; + } + + /** 群组成员提供者。 CallKit 本身不保存群组成员,如果在聊天中需要使用群组成员,CallKit 将调用此 Provider 获取群组成员。 */ + public interface GroupMembersProvider { + /** + * 获取群组成员列表,用户根据groupId返回对应的群组成员列表。 + * + * @param groupId 群组id + * @param result getMemberList可以同步返回,也可以异步返回。 同步返回的情况下,直接返回成员列表。 异步返回的情况下,需要在异步返回的时候调用{@link + * OnGroupMembersResult#onGotMemberList(ArrayList)} 来通知CallKit刷新列表。 + * @return 同步返回的时候返回列表,异步返回直接返回null。 + */ + ArrayList getMemberList(String groupId, OnGroupMembersResult result); + } + + /** 群组成员提供者的异步回调接口。 */ + public interface OnGroupMembersResult { + /** + * 群组成员提供者的异步回调接口。 + * + * @param members 成员列表。 + */ + void onGotMemberList(ArrayList members); + } + + /** + * 设置群组成员的提供者。 + * + *

设置后,当 {@link CallSelectMemberActivity} 界面展示群组成员时,会回调 {@link + * GroupMembersProvider#getMemberList(String, OnGroupMembersResult)}, 使用者只需要根据对应的 groupId + * 提供对应的群组成员。 如果需要异步从服务器获取群组成员,使用者可以在此方法中发起异步请求,然后返回 null 信息。 在异步请求结果返回后,根据返回的结果调用 {@link + * OnGroupMembersResult#onGotMemberList(ArrayList)} 刷新信息。 + * + * @param groupMembersProvider 群组成员提供者。 + */ + public static void setGroupMemberProvider(GroupMembersProvider groupMembersProvider) { + mGroupMembersProvider = groupMembersProvider; + } + + /** + * 获取群组成员提供者。 + * + * @return 群组成员提供者。 + */ + public static GroupMembersProvider getGroupMemberProvider() { + return mGroupMembersProvider; + } + + /** + * 设置通话时用户自定义操作监听。 + * + *

CallKit中的Activity是通过action隐式启动,如果用户想继承现有的Activity自定义操作,子类Activity在 + * AndroidManifest.xml声明后启动该Activity时会弹出提示框让用户选择,这个问题解决方式开发者可以直接把 + * callKit/AndroidManifest.xml中对应的Activity声明去掉,此Listener提供了另一种实现方案, + * RongCallCustomerHandlerListener中并没有定义很多方法,开发者如果需要,可以新增自己的方法 + */ + public static void setCustomerHandlerListener( + RongCallCustomerHandlerListener callCustomerHandlerListener) { + customerHandlerListener = callCustomerHandlerListener; + } + + /** 通话过程中用户自定义操作。 */ + public static RongCallCustomerHandlerListener getCustomerHandlerListener() { + return customerHandlerListener; + } + + public static void setRongCallMissedListener( + final RongCallMissedListener rongCallMissedListener) { + RongCallModule.setMissedCallListener(rongCallMissedListener); + } + + // TODO 由于最新CallKit中已经将 RongCallModule#mViewLoaded 默认值改为true,所以不在需要此方法 + // /** + // * 防止 voip 通话页面被会话列表、会话页面或者开发者 app 层页面覆盖。 使用 maven 接入 callkit 的开发者在 app 层主页面的 onCreate + // 调用此方法即可。 + // * 针对导入 callkit 源码的开发者,不使用会话列表和会话页面我们建议在 {@link RongCallModule#onCreate(Context)}方法中设置 + // * mViewLoaded 为 true 即可。 + // */ + // public static void onViewCreated() { + // } + + /** + * 忽略 voip 来电,不弹出来电界面,直接挂断。 + * + * @param ignore true 时忽略来电,false 恢复默认值接收来电,弹出来电界面。 此接口针对音视频会议过程中不能被 voip 打断等的细分场景 + */ + public static void ignoreIncomingCall(boolean ignore) { + RongCallModule.ignoreIncomingCall(ignore); + } + + public static void setMainPageActivityClass(String[] className) { + RongCallModule.setMainPageActivity(className); + } + + public static String getVersion() { + return BuildConfig.VERSION_NAME; + } + + public static void setKitImageEngine(GlideCallKitImageEngine kitImageEngine) { + RongCallKit.kitImageEngine = kitImageEngine; + } + + /** + * 获取自定义头像engine + * + * @return + */ + public static GlideCallKitImageEngine getKitImageEngine() { + return kitImageEngine; + } + + public static GroupMembersProvider getmGroupMembersProvider() { + return mGroupMembersProvider; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/RongCallModule.java b/callkit/src/main/java/io/rong/callkit/RongCallModule.java new file mode 100644 index 000000000..cb6c7d861 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongCallModule.java @@ -0,0 +1,485 @@ +package io.rong.callkit; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.Application; +import android.app.Application.ActivityLifecycleCallbacks; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import androidx.fragment.app.Fragment; +import cn.rongcloud.rtc.api.RCRTCAudioRouteManager; +import io.rong.callkit.util.ActivityStartCheckUtils; +import io.rong.callkit.util.CallKitUtils; +import io.rong.calllib.IRongReceivedCallListener; +import io.rong.calllib.ReportUtil; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallMissedListener; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.message.CallSTerminateMessage; +import io.rong.calllib.message.MultiCallEndMessage; +import io.rong.common.RLog; +import io.rong.imkit.IMCenter; +import io.rong.imkit.config.RongConfigCenter; +import io.rong.imkit.conversation.extension.IExtensionModule; +import io.rong.imkit.conversation.extension.RongExtension; +import io.rong.imkit.conversation.extension.component.emoticon.IEmoticonTab; +import io.rong.imkit.conversation.extension.component.plugin.IPluginModule; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.Message; +import io.rong.push.RongPushClient; +import io.rong.push.notification.PushNotificationMessage; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** Created by weiqinxiao on 16/8/15. */ +public class RongCallModule implements IExtensionModule { + private static final String TAG = "RongCallModule"; + + private RongCallSession mCallSession; + private boolean mStartForCheckPermissions; + private static boolean mViewLoaded = true; + private Context mContext; + private static RongCallMissedListener missedListener; + private static boolean ignoreIncomingCall; + private Application mApplication; + + public RongCallModule() { + RLog.i(TAG, "Constructor"); + } + + private void initMissedCallListener() { + RongCallClient.setMissedCallListener( + new RongCallMissedListener() { + @Override + public void onRongCallMissed( + RongCallSession callSession, + RongCallCommon.CallDisconnectedReason reason) { + if (!TextUtils.isEmpty(callSession.getInviterUserId())) { + long insertTime = callSession.getEndTime(); + if (insertTime == 0) { + insertTime = callSession.getStartTime(); + } + if (callSession.getConversationType() + == Conversation.ConversationType.PRIVATE) { + CallSTerminateMessage message = new CallSTerminateMessage(); + message.setReason(reason); + message.setMediaType(callSession.getMediaType()); + + String extra; + long time = + (callSession.getEndTime() - callSession.getStartTime()) + / 1000; + if (time >= 3600) { + extra = + String.format( + Locale.ROOT, + "%d:%02d:%02d", + time / 3600, + (time % 3600) / 60, + (time % 60)); + } else { + extra = + String.format( + Locale.ROOT, + "%02d:%02d", + (time % 3600) / 60, + (time % 60)); + } + message.setExtra(extra); + + String senderId = callSession.getInviterUserId(); + if (senderId.equals(callSession.getSelfUserId())) { + message.setDirection("MO"); + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType.PRIVATE, + callSession.getTargetId(), + io.rong.imlib.model.Message.SentStatus.SENT, + message, + insertTime, + null); + } else { + message.setDirection("MT"); + io.rong.imlib.model.Message.ReceivedStatus receivedStatus = + new io.rong.imlib.model.Message.ReceivedStatus(0); + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType.PRIVATE, + callSession.getTargetId(), + senderId, + CallKitUtils.getReceivedStatus(reason), + message, + insertTime, + null); + } + } else if (callSession.getConversationType() + == Conversation.ConversationType.GROUP) { + MultiCallEndMessage multiCallEndMessage = new MultiCallEndMessage(); + multiCallEndMessage.setReason(reason); + if (callSession.getMediaType() + == RongCallCommon.CallMediaType.AUDIO) { + multiCallEndMessage.setMediaType(IRongCoreEnum.MediaType.AUDIO); + } else if (callSession.getMediaType() + == RongCallCommon.CallMediaType.VIDEO) { + multiCallEndMessage.setMediaType(IRongCoreEnum.MediaType.VIDEO); + } + IMCenter.getInstance() + .insertIncomingMessage( + callSession.getConversationType(), + callSession.getTargetId(), + callSession.getCallerUserId(), + CallKitUtils.getReceivedStatus(reason), + multiCallEndMessage, + insertTime, + null); + } + } + if (missedListener != null) { + missedListener.onRongCallMissed(callSession, reason); + } + } + }); + } + + public static void setMissedCallListener(RongCallMissedListener listener) { + missedListener = listener; + } + + /** + * 启动通话界面 + * + * @param context 上下文 + * @param callSession 通话实体 + * @param startForCheckPermissions android6.0需要实时获取应用权限。 + * 当需要实时获取权限时,设置startForCheckPermissions为true, 其它情况下设置为false。 + */ + private void startVoIPActivity( + Context context, final RongCallSession callSession, boolean startForCheckPermissions) { + RLog.d( + TAG, + "startVoIPActivity.ignoreIncomingCall : " + + ignoreIncomingCall + + " , AndroidVersion :" + + Build.VERSION.SDK_INT + + " ,startForCheckPermissions : " + + startForCheckPermissions); + if (ignoreIncomingCall) { + RongCallClient.getInstance().hangUpCall(); + return; + } + ReportUtil.appStatus( + ReportUtil.TAG.RECEIVE_CALL_LISTENER, + callSession, + "state|desc", + "startVoIPActivity", + Build.VERSION.SDK_INT); + // 在 Android 10 以上版本不再允许后台运行 Activity + if (Build.VERSION.SDK_INT < 29 || isAppOnForeground(context)) { + context.startActivity(createVoIPIntent(context, callSession, startForCheckPermissions)); + } else { + onSendBroadcast(context, callSession, startForCheckPermissions); + } + mCallSession = null; + } + + private void onSendBroadcast( + Context context, RongCallSession callSession, boolean startForCheckPermissions) { + RLog.d(TAG, "onSendBroadcast"); + Intent intent = new Intent(); + intent.setPackage(context.getPackageName()); + // intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + intent.putExtra("message", transformToPushMessage(context, callSession)); + intent.putExtra("callsession", callSession); + intent.putExtra("checkPermissions", startForCheckPermissions); + intent.setAction(VoIPBroadcastReceiver.ACTION_CALLINVITEMESSAGE); + context.sendBroadcast(intent); + } + + public static Intent createVoIPIntent( + Context context, RongCallSession callSession, boolean startForCheckPermissions) { + Intent intent; + String action; + if (callSession.getConversationType().equals(Conversation.ConversationType.DISCUSSION) + || callSession.getConversationType().equals(Conversation.ConversationType.GROUP) + || callSession.getConversationType().equals(Conversation.ConversationType.NONE)) { + if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.VIDEO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO; + } + intent = new Intent(action); + intent.putExtra("callSession", callSession); + intent.putExtra("callAction", RongCallAction.ACTION_INCOMING_CALL.getName()); + if (startForCheckPermissions) { + intent.putExtra("checkPermissions", true); + } else { + intent.putExtra("checkPermissions", false); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + } else { + if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.VIDEO)) { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEVIDEO; + } else { + action = RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO; + } + intent = new Intent(action); + intent.putExtra("callSession", callSession); + intent.putExtra("callAction", RongCallAction.ACTION_INCOMING_CALL.getName()); + if (startForCheckPermissions) { + intent.putExtra("checkPermissions", true); + } else { + intent.putExtra("checkPermissions", false); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + } + return intent; + } + + /** + * 将 RongCallSession 转换为 PushNotificationMessage + * + * @param session + * @return + */ + private PushNotificationMessage transformToPushMessage( + Context context, RongCallSession session) { + PushNotificationMessage pushMsg = new PushNotificationMessage(); + // pushMsg.setPushContent(session.getMediaType() == + // RongCallCommon.CallMediaType.AUDIO ? "音频电话呼叫" : "视频电话呼叫"); + pushMsg.setPushTitle( + (String) + context.getPackageManager() + .getApplicationLabel(context.getApplicationInfo())); + pushMsg.setConversationType( + RongPushClient.ConversationType.setValue(session.getConversationType().getValue())); + pushMsg.setTargetId(session.getTargetId()); + pushMsg.setTargetUserName(""); + pushMsg.setSenderId(session.getCallerUserId()); + pushMsg.setSenderName(""); + pushMsg.setObjectName("RC:VCInvite"); + pushMsg.setPushFlag("false"); + pushMsg.setToId(RongIMClient.getInstance().getCurrentUserId()); + pushMsg.setSourceType(PushNotificationMessage.PushSourceType.LOCAL_MESSAGE); + // pushMsg.setPushId(session.getUId()); + return pushMsg; + } + + /** + * 判断应用是否处于前台 + * + * @param context + * @return + */ + private boolean isAppOnForeground(Context context) { + if (context == null) return false; + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + List appProcesses = + activityManager.getRunningAppProcesses(); + if (appProcesses == null) return false; + String apkName = context.getPackageName(); + + for (ActivityManager.RunningAppProcessInfo app : appProcesses) { + if (TextUtils.equals(apkName, app.processName) + && ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + == app.importance) return true; + } + return false; + } + + public static void ignoreIncomingCall(boolean ignore) { + ignoreIncomingCall = ignore; + } + + @Override + public void onInit(Context context, String appKey) { + RLog.d(TAG, "onInit"); + mContext = context.getApplicationContext(); + registerLifecycleCallbacks(mContext); + RongConfigCenter.conversationConfig().addMessageProvider(new CallEndMessageItemProvider()); + RongConfigCenter.conversationConfig().addMessageProvider(new MultiCallEndMessageProvider()); + initMissedCallListener(); + + IRongReceivedCallListener callListener = + new IRongReceivedCallListener() { + @Override + public void onReceivedCall(final RongCallSession callSession) { + ReportUtil.appStatus( + ReportUtil.TAG.RECEIVED_CALL, + "mViewLoaded|session", + mViewLoaded, + callSession); + RLog.d(TAG, "onReceivedCall.mViewLoaded :" + mViewLoaded); + if (mViewLoaded) { + startVoIPActivity(mContext, callSession, false); + } else { + mCallSession = callSession; + } + RCRTCAudioRouteManager.getInstance().init(mContext.getApplicationContext()); + } + + @Override + public void onCheckPermission(RongCallSession callSession) { + ReportUtil.appStatus( + ReportUtil.TAG.CHECK_PERMISSION, + "mViewLoaded|session", + mViewLoaded, + callSession); + RLog.d(TAG, "onCheckPermissions.mViewLoaded : " + mViewLoaded); + mCallSession = callSession; + if (mViewLoaded) { + startVoIPActivity(mContext, callSession, true); + } else { + mStartForCheckPermissions = true; + } + } + }; + + RongCallClient.setReceivedCallListener(callListener); + ActivityStartCheckUtils.getInstance().registerActivityLifecycleCallbacks(context); + IMCenter.getInstance() + .addConnectStatusListener( + new RongIMClient.ConnectCallback() { + @Override + public void onSuccess(String t) { + if (RongCallClient.getInstance() != null) { + RongCallClient.getInstance() + .setVoIPCallListener(RongCallProxy.getInstance()); + } + } + + @Override + public void onError(RongIMClient.ConnectionErrorCode e) { + if (RongCallClient.getInstance() != null) { + RongCallClient.getInstance() + .setVoIPCallListener(RongCallProxy.getInstance()); + } + } + + @Override + public void onDatabaseOpened(RongIMClient.DatabaseOpenStatus code) {} + }); + } + + private void registerLifecycleCallbacks(Context context) { + RLog.d(TAG, "registerLifecycleCallbacks"); + mApplication = (Application) context; + + if (mApplication == null) { + return; + } + + mApplication.registerActivityLifecycleCallbacks(myActivityLifecycleCallbacks); + } + + private ActivityLifecycleCallbacks myActivityLifecycleCallbacks = + new ActivityLifecycleCallbacks() { + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + RLog.d(TAG, "onActivityCreated ---- : " + activity); + + if (mActivities == null || mActivities.size() == 0) { + RLog.d(TAG, "onActivityCreated . mainPageClass is empty."); + return; + } + String className1 = activity.getClass().getName(); + mActivities.remove(className1); + if (mActivities.size() == 0) { + retryStartVoIPActivity(); + } + } + + @Override + public void onActivityStarted(Activity activity) {} + + @Override + public void onActivityResumed(Activity activity) {} + + @Override + public void onActivityPaused(Activity activity) {} + + @Override + public void onActivityStopped(Activity activity) {} + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} + + @Override + public void onActivityDestroyed(Activity activity) {} + }; + + private void retryStartVoIPActivity() { + RLog.i( + TAG, + "Find the exact class, change mViewLoaded as true . mCallSession ==null ?" + + (mCallSession == null)); + mViewLoaded = true; + if (mCallSession != null) { + startVoIPActivity(mContext, mCallSession, mStartForCheckPermissions); + mStartForCheckPermissions = false; + } + } + + @Override + public void onAttachedToExtension(Fragment fragment, RongExtension extension) { + RLog.d(TAG, "onAttachedToExtension"); + } + + @Override + public void onDetachedFromExtension() { + RLog.d(TAG, "onDetachedFromExtension"); + } + + @Override + public void onReceivedMessage(Message message) {} + + @Override + public List getPluginModules(Conversation.ConversationType conversationType) { + RLog.d(TAG, "getPluginModules"); + List pluginModules = new ArrayList<>(); + try { + if (RongCallClient.getInstance().isVoIPEnabled(mContext)) { + pluginModules.add(new AudioPlugin()); + pluginModules.add(new VideoPlugin()); + } + } catch (Exception e) { + e.printStackTrace(); + RLog.i(TAG, "getPlugins()->Error :" + e.getMessage()); + } + return pluginModules; + } + + @Override + public List getEmoticonTabs() { + return null; + } + + @Override + public void onDisconnect() { + RLog.d(TAG, "onDisconnect"); + } + + private static ArrayList mActivities; + + /** 设置可能会覆盖音视频通话页面的类,比如主页面。设置后,如果此页面尚未打开,即使收到音视频呼叫,也会暂缓唤起页面,会再设置的页面启动成功后,再尝试启动音视频通话页面。 */ + public static void setMainPageActivity(String[] className) { + if (className != null && className.length > 0) { + int length = className.length; + RLog.i(TAG, "setMainPageActivity.length :" + length); + mActivities = new ArrayList<>(); + mViewLoaded = false; + for (int i = 0; i < length; i++) { + mActivities.add(className[i]); + } + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/RongCallProxy.java b/callkit/src/main/java/io/rong/callkit/RongCallProxy.java new file mode 100644 index 000000000..5158d533f --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongCallProxy.java @@ -0,0 +1,422 @@ +package io.rong.callkit; + +import android.text.TextUtils; +import android.view.SurfaceView; +import cn.rongcloud.rtc.api.RCRTCAudioRouteManager; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.IncomingCallExtraHandleUtil; +import io.rong.calllib.IRongCallListener; +import io.rong.calllib.ReportUtil; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallCommon.CallMediaType; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.message.CallSTerminateMessage; +import io.rong.calllib.message.MultiCallEndMessage; +import io.rong.common.RLog; +import io.rong.imkit.IMCenter; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.model.Conversation; +import java.util.HashMap; +import java.util.Locale; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +/** Created by jiangecho on 2016/10/27. */ +public class RongCallProxy implements IRongCallListener { + + private static final String TAG = "RongCallProxy"; + private IRongCallListener mCallListener; + private Queue mCachedCallQueue; + private static RongCallProxy mInstance; + + private RongCallProxy() { + mCachedCallQueue = new LinkedBlockingQueue<>(); + } + + public static synchronized RongCallProxy getInstance() { + if (mInstance == null) { + mInstance = new RongCallProxy(); + } + return mInstance; + } + + public void setCallListener(IRongCallListener listener) { + RLog.d(TAG, "setCallListener listener = " + listener); + this.mCallListener = listener; + // if (listener != null) { + // CallDisconnectedInfo callDisconnectedInfo = mCachedCallQueue.poll(); + // if (callDisconnectedInfo != null) { + // listener.onCallDisconnected(callDisconnectedInfo.mCallSession, + // callDisconnectedInfo.mReason); + // } + // } + } + + @Override + public void onCallIncoming(RongCallSession callSession, SurfaceView localVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callSession, + "state|desc", + "onCallIncoming", + getDescription()); + if (mCallListener != null) { + mCallListener.onCallIncoming(callSession, localVideo); + } + if (RongCallClient.getInstance().getContext() != null) { + RCRTCAudioRouteManager.getInstance() + .init(RongCallClient.getInstance().getContext().getApplicationContext()); + } + } + + @Override + public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callSession, + "state|desc", + "onCallOutgoing", + getDescription()); + if (mCallListener != null) { + mCallListener.onCallOutgoing(callSession, localVideo); + } + if (RongCallClient.getInstance().getContext() != null) { + RCRTCAudioRouteManager.getInstance() + .init(RongCallClient.getInstance().getContext().getApplicationContext()); + } + } + + @Override + public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callSession, + "state|desc", + "onCallConnected", + getDescription()); + if (mCallListener != null) { + mCallListener.onCallConnected(callSession, localVideo); + } + } + + @Override + public void onCallDisconnected( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + RLog.d(TAG, "RongCallProxy onCallDisconnected mCallListener = " + mCallListener); + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + callSession, + "state|reason|desc", + "onCallDisconnected", + reason.getValue(), + getDescription()); + if (mCallListener != null) { + mCallListener.onCallDisconnected(callSession, reason); + } else if (!IncomingCallExtraHandleUtil.needNotify()) { + mCachedCallQueue.offer(new CallDisconnectedInfo(callSession, reason)); + } else { // android 10 后台来电,被叫端不响应,主叫挂断时 mCallListener 为空 ,需要生成通话记录 + insertCallLogMessage(callSession, reason); + } + // 取消耳机监听 + RCRTCAudioRouteManager.getInstance().unInit(); + } + + @Override + public void onRemoteUserRinging(String userId) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserRinging", + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserRinging(userId); + } + } + + @Override + public void onRemoteUserAccept(String userId, CallMediaType mediaType) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserAccept", + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserAccept(userId, mediaType); + } + } + + @Override + public void onRemoteUserJoined( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserJoined", + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserJoined(userId, mediaType, userType, remoteVideo); + } + } + + @Override + public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onRemoteUserInvited", + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserInvited(userId, mediaType); + } + } + + @Override + public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|reason|desc", + userId, + "onRemoteUserLeft", + reason.getValue(), + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserLeft(userId, reason); + } + } + + @Override + public void onMediaTypeChanged( + String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|mediaType|desc", + userId, + "onMediaTypeChanged", + mediaType.getValue(), + getDescription()); + if (mCallListener != null) { + mCallListener.onMediaTypeChanged(userId, mediaType, video); + } + } + + @Override + public void onError(RongCallCommon.CallErrorCode errorCode) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "state|code|desc", + "onError", + errorCode.getValue(), + getDescription()); + if (mCallListener != null) { + mCallListener.onError(errorCode); + } + } + + @Override + public void onRemoteCameraDisabled(String userId, boolean disabled) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|disabled|desc", + userId, + "onRemoteCameraDisabled", + disabled, + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteCameraDisabled(userId, disabled); + } + } + + @Override + public void onRemoteMicrophoneDisabled(String userId, boolean disabled) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|disabled|desc", + userId, + "onRemoteMicrophoneDisabled", + disabled, + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteMicrophoneDisabled(userId, disabled); + } + } + + @Override + public void onNetworkSendLost(int lossRate, int delay) { + if (mCallListener != null) { + mCallListener.onNetworkSendLost(lossRate, delay); + } + } + + @Override + public void onFirstRemoteVideoFrame(String userId, int height, int width) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onFirstRemoteVideoFrame", + getDescription()); + if (mCallListener != null) { + mCallListener.onFirstRemoteVideoFrame(userId, height, width); + } + } + + @Override + public void onFirstRemoteAudioFrame(String userId) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|desc", + userId, + "onFirstRemoteAudioFrame", + getDescription()); + if (mCallListener != null) { + mCallListener.onFirstRemoteAudioFrame(userId); + } + } + + @Override + public void onAudioLevelSend(String audioLevel) { + if (mCallListener != null) { + mCallListener.onAudioLevelSend(audioLevel); + } + } + + public void onRemoteUserPublishVideoStream( + String userId, String streamId, String tag, SurfaceView surfaceView) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|streamId|desc", + userId, + "onRemoteUserPublishVideoStream", + streamId, + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserPublishVideoStream(userId, streamId, tag, surfaceView); + } + } + + @Override + public void onAudioLevelReceive(HashMap audioLevel) { + if (mCallListener != null) { + mCallListener.onAudioLevelReceive(audioLevel); + } + } + + public void onRemoteUserUnpublishVideoStream(String userId, String streamId, String tag) { + ReportUtil.appStatus( + ReportUtil.TAG.CALL_LISTENER, + "userId|state|streamId|desc", + userId, + "onRemoteUserUnpublishVideoStream", + streamId, + getDescription()); + if (mCallListener != null) { + mCallListener.onRemoteUserUnpublishVideoStream(userId, streamId, tag); + } + } + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) { + if (mCallListener != null) { + mCallListener.onNetworkReceiveLost(userId, lossRate); + } + } + + private static class CallDisconnectedInfo { + RongCallSession mCallSession; + RongCallCommon.CallDisconnectedReason mReason; + + public CallDisconnectedInfo( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + this.mCallSession = callSession; + this.mReason = reason; + } + } + + private String getDescription() { + if (mCallListener != null) { + return mCallListener.getClass().getSimpleName(); + } + return "no callListener set"; + } + + private void insertCallLogMessage( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + if (!TextUtils.isEmpty(callSession.getInviterUserId())) { + long insertTime = callSession.getEndTime(); + if (insertTime == 0) { + insertTime = callSession.getStartTime(); + } + if (callSession.getConversationType() == Conversation.ConversationType.PRIVATE) { + CallSTerminateMessage message = new CallSTerminateMessage(); + message.setReason(reason); + message.setMediaType(callSession.getMediaType()); + + String extra; + long time = (callSession.getEndTime() - callSession.getStartTime()) / 1000; + if (time >= 3600) { + extra = + String.format( + Locale.ROOT, + "%d:%02d:%02d", + time / 3600, + (time % 3600) / 60, + (time % 60)); + } else { + extra = + String.format( + Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60)); + } + message.setExtra(extra); + + String senderId = callSession.getInviterUserId(); + if (senderId.equals(callSession.getSelfUserId())) { + message.setDirection("MO"); + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType.PRIVATE, + callSession.getTargetId(), + io.rong.imlib.model.Message.SentStatus.SENT, + message, + insertTime, + null); + } else { + message.setDirection("MT"); + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType.PRIVATE, + callSession.getTargetId(), + senderId, + CallKitUtils.getReceivedStatus(reason), + message, + insertTime, + null); + } + } else if (callSession.getConversationType() == Conversation.ConversationType.GROUP) { + MultiCallEndMessage multiCallEndMessage = new MultiCallEndMessage(); + multiCallEndMessage.setReason(reason); + if (callSession.getMediaType() == RongCallCommon.CallMediaType.AUDIO) { + multiCallEndMessage.setMediaType(IRongCoreEnum.MediaType.AUDIO); + } else if (callSession.getMediaType() == RongCallCommon.CallMediaType.VIDEO) { + multiCallEndMessage.setMediaType(IRongCoreEnum.MediaType.VIDEO); + } + IMCenter.getInstance() + .insertIncomingMessage( + callSession.getConversationType(), + callSession.getTargetId(), + callSession.getCallerUserId(), + CallKitUtils.getReceivedStatus(reason), + multiCallEndMessage, + insertTime, + null); + } + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/RongIncomingCallService.java b/callkit/src/main/java/io/rong/callkit/RongIncomingCallService.java new file mode 100644 index 000000000..23ca4e65d --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongIncomingCallService.java @@ -0,0 +1,317 @@ +package io.rong.callkit; + +import android.annotation.SuppressLint; +import android.app.KeyguardManager; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.os.PowerManager; +import android.os.SystemClock; +import android.view.View; +import androidx.annotation.RequiresApi; +import androidx.core.app.NotificationCompat; +import io.rong.callkit.util.CallRingingUtil; +import io.rong.callkit.util.IncomingCallExtraHandleUtil; +import io.rong.callkit.util.RingingMode; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallSession; +import io.rong.common.RLog; +import io.rong.push.notification.PushNotificationMessage; +import java.util.concurrent.atomic.AtomicBoolean; + +/** @author gusd @Date 2021/09/01 */ +public class RongIncomingCallService { + private static final String TAG = "IncomingCallService"; + public static final int ACCEPT_REQUEST_CODE = 145679; + public static final int HANGUP_REQUEST_CODE = 145678; + private static int notificationId = 4000; + + public static final String KEY_MESSAGE = "message"; + public static final String KEY_CALL_SESSION = "callsession"; + public static final String KEY_CHECK_PERMISSIONS = "checkPermissions"; + public static final String KEY_NEED_AUTO_ANSWER = "needAutoAnswer"; + + /** 该服务最长存活时间,60 秒 */ + private static final long SERVICE_MAX_ALIVE_TIME = 60 * 1000L; + + private static final String TAG_KILL_INCOMING_SERVICE = "TAG_KILL_INCOMING_SERVICE"; + + public static final String ACTION_CALLINVITEMESSAGE_CLICKED = + "action.push.CallInviteMessage.CLICKED"; + + private Handler mHandler; + private AtomicBoolean isRinging = new AtomicBoolean(false); + + private RongIncomingCallService() {} + + public static RongIncomingCallService getInstance() { + return RongIncomingCallHolder.instance; + } + + private static class RongIncomingCallHolder { + static RongIncomingCallService instance = new RongIncomingCallService(); + } + + public boolean isRinging() { + return isRinging.get(); + } + + @RequiresApi(api = Build.VERSION_CODES.M) + public void startRing(final Context context, Intent intent) { + RLog.d(TAG, "onStartCommand: "); + if (isRinging.get()) { + return; + } + + PushNotificationMessage message = intent.getParcelableExtra(KEY_MESSAGE); + RongCallSession callSession = intent.getParcelableExtra(KEY_CALL_SESSION); + boolean checkPermission = intent.getBooleanExtra(KEY_CHECK_PERMISSIONS, false); + if (message == null || callSession == null) { + return; + } + RLog.d(TAG, "onStartCommand : " + "callId = " + callSession.getCallId()); + + mHandler = new Handler(Looper.myLooper()); + mHandler.postAtTime( + new Runnable() { + @Override + public void run() { + stopRinging(context); + } + }, + TAG_KILL_INCOMING_SERVICE, + SystemClock.uptimeMillis() + SERVICE_MAX_ALIVE_TIME); + + wakeUpAndUnlock(context); + + try { + PendingIntent answerPendingIntent = + createAnswerIntent( + context, + message, + callSession, + checkPermission, + IncomingCallExtraHandleUtil.VOIP_REQUEST_CODE, + false); + PendingIntent hangupPendingIntent = createHangupIntent(context, callSession); + PendingIntent openAppIntent = + createOpenAppPendingIntent( + context, + message, + callSession, + checkPermission, + IncomingCallExtraHandleUtil.VOIP_REQUEST_CODE, + false); + CallRingingUtil.getInstance().createNotificationChannel(context); + + int smallIcon = + context.getResources() + .getIdentifier( + "notification_small_icon", + "drawable", + context.getPackageName()); + if (smallIcon <= 0) { + smallIcon = context.getApplicationInfo().icon; + } + androidx.media.app.NotificationCompat.MediaStyle mediaStyle = + new androidx.media.app.NotificationCompat.MediaStyle(); + mediaStyle.setShowCancelButton(false); + mediaStyle.setCancelButtonIntent(hangupPendingIntent); + mediaStyle.setShowActionsInCompactView(0, 1); + + NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder( + context, + CallRingingUtil.getInstance().getNotificationChannelId()) + .setContentText(message.getPushContent()) + .setContentTitle(message.getPushTitle()) + .setSmallIcon(smallIcon) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setCategory(NotificationCompat.CATEGORY_CALL) + .setAutoCancel(true) + .setOngoing(true) + .setStyle(mediaStyle) + .setContentIntent(openAppIntent) + .setFullScreenIntent(openAppIntent, true); + + int notificationHangupIcon = CallRingingUtil.getInstance().getNotificationHangupIcon(); + if (notificationHangupIcon != View.NO_ID && notificationHangupIcon != 0) { + notificationBuilder.addAction( + R.drawable.rc_voip_notification_hangup, + context.getString(R.string.rc_voip_hangup), + hangupPendingIntent); + } + + int notificationAnswerIcon = CallRingingUtil.getInstance().getNotificationAnswerIcon(); + if (notificationAnswerIcon != View.NO_ID && notificationAnswerIcon != 0) { + notificationBuilder.addAction( + R.drawable.rc_voip_notification_answer, + context.getString(R.string.rc_voip_answer), + answerPendingIntent); + } + + Notification notification = notificationBuilder.build(); + + NotificationManager notificationManager = + context.getSystemService(NotificationManager.class); + if (notificationManager != null) { + notificationManager.notify(++notificationId, notification); + } + CallRingingUtil.getInstance().startRinging(context, RingingMode.Incoming); + isRinging.set(true); + } catch (Exception e) { + RLog.e(TAG, "onStartCommand = " + e.getMessage()); + e.printStackTrace(); + } + } + + public void stopRinging(Context context) { + isRinging.set(false); + CallRingingUtil.getInstance().stopRinging(); + try { + NotificationManager notificationManager = null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + notificationManager = context.getSystemService(NotificationManager.class); + } + if (notificationManager != null) { + notificationManager.cancel(notificationId); + } + } catch (Exception e) { + e.printStackTrace(); + } + Handler handler = mHandler; + if (handler != null) { + handler.removeCallbacksAndMessages(TAG_KILL_INCOMING_SERVICE); + } + } + + private PendingIntent createOpenAppPendingIntent( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions, + int requestCode, + boolean isMulti) { + Intent intent = + createOpenAppIntent( + context, message, callSession, checkPermissions, requestCode, isMulti); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return PendingIntent.getActivity( + context, 2314412, intent, PendingIntent.FLAG_IMMUTABLE); + } else { + return PendingIntent.getBroadcast( + context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + } + + private Intent createOpenAppIntent( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions, + int requestCode, + boolean isMulti) { + return createIntentForAndroidS(context, callSession, checkPermissions); + } + + private PendingIntent createAnswerIntent( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions, + int requestCode, + boolean isMulti) { + Intent intent = + createOpenAppIntent( + context, message, callSession, checkPermissions, requestCode, isMulti); + intent.putExtra(KEY_NEED_AUTO_ANSWER, callSession.getCallId()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return PendingIntent.getActivity( + context, 12345664, intent, PendingIntent.FLAG_IMMUTABLE); + } else { + intent.setClass(context, VoIPBroadcastReceiver.class); + return PendingIntent.getBroadcast( + context, ACCEPT_REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + } + + private Intent createIntentForAndroidS( + Context context, RongCallSession callSession, boolean checkPermissions) { + Intent intent; + // 如果进程被杀 RongCallClient.getInstance() 返回Null + if (RongCallClient.getInstance() != null + && RongCallClient.getInstance().getCallSession() != null + && callSession != null) { + intent = RongCallModule.createVoIPIntent(context, callSession, checkPermissions); + io.rong.push.common.RLog.d(TAG, "handleNotificationClickEvent: start call activity"); + } else { + intent = createConversationListIntent(context); + io.rong.push.common.RLog.d( + TAG, "handleNotificationClickEvent: start conversation activity"); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + return intent; + } + + private static Intent createConversationListIntent(Context context) { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri uri = + Uri.parse("rong://" + context.getPackageName()) + .buildUpon() + .appendPath("conversationlist") + .build(); + intent.setData(uri); + intent.setPackage(context.getPackageName()); + return intent; + } + + private PendingIntent createHangupIntent(Context context, RongCallSession callSession) { + Intent hangupIntent = new Intent(); + hangupIntent.setAction(VoIPBroadcastReceiver.ACTION_CALL_HANGUP_CLICKED); + hangupIntent.putExtra(KEY_CALL_SESSION, callSession); + hangupIntent.setPackage(context.getPackageName()); + hangupIntent.setClass(context, VoIPBroadcastReceiver.class); + // KNOTE: 2021/9/29 PendingIntent + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return PendingIntent.getBroadcast( + context, + HANGUP_REQUEST_CODE, + hangupIntent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + return PendingIntent.getBroadcast( + context, HANGUP_REQUEST_CODE, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } + } + + // 唤醒屏幕并解锁 + public void wakeUpAndUnlock(Context context) { + try { + KeyguardManager km = + (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); + KeyguardManager.KeyguardLock kl = km.newKeyguardLock("unLock"); + // 获取电源管理器对象 + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + // 获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是LogCat里用的Tag + @SuppressLint("InvalidWakeLockTag") + PowerManager.WakeLock wl = + pm.newWakeLock( + PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, + "bright"); + // 点亮屏幕 + wl.acquire(5000); + // 释放 + wl.release(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/RongVoIPIntent.java b/callkit/src/main/java/io/rong/callkit/RongVoIPIntent.java new file mode 100644 index 000000000..9c1df929d --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/RongVoIPIntent.java @@ -0,0 +1,19 @@ +package io.rong.callkit; + +/** Created by weiqinxiao on 16/3/18. */ +public class RongVoIPIntent { + public static final String RONG_INTENT_VOIP_CATEGORY = "io.rong.intent.category.voip"; + + public static final String RONG_INTENT_ACTION_VOIP_MULTIAUDIO = + "io.rong.intent.action.voip.MULTIAUDIO"; + public static final String RONG_INTENT_ACTION_VOIP_MULTIVIDEO = + "io.rong.intent.action.voip.MULTIVIDEO"; + public static final String RONG_INTENT_ACTION_VOIP_SINGLEAUDIO = + "io.rong.intent.action.voip.SINGLEAUDIO"; + public static final String RONG_INTENT_ACTION_VOIP_SINGLEVIDEO = + "io.rong.intent.action.voip.SINGLEVIDEO"; + public static final String RONG_INTENT_ACTION_VOIP_INIT = "io.rong.intent.action.SDK_INIT"; + public static final String RONG_INTENT_ACTION_VOIP_UI_READY = "io.rong.intent.action.UI_READY"; + public static final String RONG_INTENT_ACTION_VOIP_CONNECTED = + "io.rong.intent.action.SDK_CONNECTED"; +} diff --git a/callkit/src/main/java/io/rong/callkit/SingleCallActivity.java b/callkit/src/main/java/io/rong/callkit/SingleCallActivity.java new file mode 100644 index 000000000..f578e6382 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/SingleCallActivity.java @@ -0,0 +1,1336 @@ +package io.rong.callkit; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.media.SoundPool; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.yunbao.common.utils.ToastUtil; + +import cn.rongcloud.rtc.api.RCRTCEngine; +import cn.rongcloud.rtc.audioroute.RCAudioRouteType; +import cn.rongcloud.rtc.utils.FinLog; +import io.rong.callkit.util.BluetoothUtil; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.DefaultPushConfig; +import io.rong.callkit.util.GlideUtils; +import io.rong.callkit.util.HeadsetInfo; +import io.rong.callkit.util.RingingMode; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.calllib.CallUserProfile; +import io.rong.calllib.ReportUtil; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallCommon.RoomType; +import io.rong.calllib.RongCallSession; +import io.rong.calllib.StartIncomingPreviewCallback; +import io.rong.calllib.message.CallSTerminateMessage; +import io.rong.common.RLog; +import io.rong.imkit.IMCenter; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class SingleCallActivity extends BaseCallActivity implements Handler.Callback { + private static final String TAG = "VoIPSingleActivity"; + private static final int LOSS_RATE_ALARM = 20; + private LayoutInflater inflater; + private RongCallSession callSession; + private RelativeLayout mLPreviewContainer; + private FrameLayout mSPreviewContainer; + private FrameLayout mButtonContainer; + private LinearLayout mUserInfoContainer; + private TextView mConnectionStateTextView; + private Boolean isInformationShow = false; + private SurfaceView mLocalVideo = null; + private boolean muted = false; + private boolean handFree = false; + private boolean startForCheckPermissions = false; + private boolean isReceiveLost = false; + private boolean isSendLost = false; + private SoundPool mSoundPool = null; + + private int EVENT_FULL_SCREEN = 1; + + private String targetId = null; + private RongCallCommon.CallMediaType mediaType; + + @Override + public final boolean handleMessage(Message msg) { + if (msg.what == EVENT_FULL_SCREEN) { + hideVideoCallInformation(); + return true; + } + return false; + } + + @Override + @TargetApi(23) + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.rc_voip_activity_single_call); + RLog.i( + "AudioPlugin", + "savedInstanceState != null=" + + (savedInstanceState != null) + + ",,,RongCallClient.getInstance() == null" + + (RongCallClient.getInstance() == null)); + if (savedInstanceState != null && RongCallClient.getInstance() == null) { + // 音视频请求权限时,用户在设置页面取消权限,导致应用重启,退出当前activity. + RLog.i("AudioPlugin", "音视频请求权限时,用户在设置页面取消权限,导致应用重启,退出当前activity"); + finish(); + return; + } + Intent intent = getIntent(); + mLPreviewContainer = (RelativeLayout) findViewById(R.id.rc_voip_call_large_preview); + mSPreviewContainer = (FrameLayout) findViewById(R.id.rc_voip_call_small_preview); + mButtonContainer = (FrameLayout) findViewById(R.id.rc_voip_btn); + mUserInfoContainer = (LinearLayout) findViewById(R.id.rc_voip_user_info); + mConnectionStateTextView = findViewById(R.id.rc_tv_connection_state); + + if (CallKitUtils.findConfigurationLanguage(SingleCallActivity.this, "ar")) { + // android:layout_gravity="right|top" + FrameLayout.LayoutParams params = (LayoutParams) mSPreviewContainer.getLayoutParams(); + params.gravity = Gravity.LEFT | Gravity.TOP; + mSPreviewContainer.setLayoutParams(params); + } + + startForCheckPermissions = intent.getBooleanExtra("checkPermissions", false); + RongCallAction callAction = RongCallAction.valueOf(intent.getStringExtra("callAction")); + + String receivedCallId = ""; + if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) { + if (intent.getAction().equals(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO)) { + mediaType = RongCallCommon.CallMediaType.AUDIO; + } else { + mediaType = RongCallCommon.CallMediaType.VIDEO; + } + } else if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + callSession = intent.getParcelableExtra("callSession"); + mediaType = callSession.getMediaType(); + receivedCallId = callSession.getCallId(); + // 正常在收到呼叫后,RongCallClient 和 CallSession均不会为空 + if (RongCallClient.getInstance() == null + || RongCallClient.getInstance().getCallSession() == null) { + // 如果为空 表示通话已经结束 但依然启动了本页面,这样会导致页面无法销毁问题 + // 所以 需要在这里 finish 结束当前页面 推荐开发者在结束当前页面前跳转至APP主页或者其他页面 + RLog.e( + TAG, + "SingleCallActivity#onCreate()->RongCallClient or CallSession is empty---->finish()"); + finish(); + return; + } + } else { + callSession = RongCallClient.getInstance().getCallSession(); + if (callSession != null) { + mediaType = callSession.getMediaType(); + receivedCallId = callSession.getCallId(); + } + } + if (!RongCallClient.getInstance().canCallContinued(receivedCallId)) { + RLog.w(TAG, "Already received hangup message before, finish current activity"); + ReportUtil.libStatus(ReportUtil.TAG.ACTIVITYFINISH, "reason", "canCallContinued not"); + finish(); + return; + } + if (mediaType != null) { + inflater = LayoutInflater.from(this); + initView(mediaType, callAction); + + if (requestCallPermissions(mediaType, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)) { + setupIntent(); + } + } else { + RLog.w(TAG, "remote already hangup, finish current activity"); + setShouldShowFloat(false); + CallFloatBoxView.hideFloatBox(); + finish(); + } + } + + @Override + protected void onNewIntent(Intent intent) { + startForCheckPermissions = intent.getBooleanExtra("checkPermissions", false); + RongCallAction callAction = RongCallAction.valueOf(intent.getStringExtra("callAction")); + if (callAction == null) { + return; + } + if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) { + if (intent.getAction().equals(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO)) { + mediaType = RongCallCommon.CallMediaType.AUDIO; + } else { + mediaType = RongCallCommon.CallMediaType.VIDEO; + } + } else if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + callSession = intent.getParcelableExtra("callSession"); + mediaType = callSession.getMediaType(); + } else { + callSession = RongCallClient.getInstance().getCallSession(); + mediaType = callSession.getMediaType(); + } + super.onNewIntent(intent); + + if (requestCallPermissions(mediaType, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)) { + setupIntent(); + } + } + + @TargetApi(23) + @Override + public void onRequestPermissionsResult( + int requestCode, String[] permissions, int[] grantResults) { + switch (requestCode) { + case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: + if (RongCallPermissionUtil.checkPermissionByType(this, mediaType)) { + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionGranted(); + } else { + setupIntent(); + } + } else { + StringBuilder builder = new StringBuilder(); + for (String str : permissions) { + if (str.equals("android.permission.CAMERA")) { + builder.append(getString(R.string.rc_android_permission_CAMERA)); + } else if (str.equals("android.permission.RECORD_AUDIO")) { + builder.append(getString(R.string.rc_android_permission_RECORD_AUDIO)); + } else if (str.equals("android.permission.BLUETOOTH_CONNECT")) { + builder.append( + getString(R.string.rc_android_permission_BLUETOOTH_CONNECT)); + } + builder.append(","); + } + + String rets = + builder.length() > 0 ? builder.substring(0, builder.length() - 1) : ""; + String msg = + String.format( + "%s (%s)", + getString(R.string.rc_permission_grant_needed), rets); + Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); + if (startForCheckPermissions) { + startForCheckPermissions = false; + RongCallClient.getInstance().onPermissionDenied(); + } else { + RLog.i("AudioPlugin", "--onRequestPermissionsResult--finish"); + finish(); + } + } + break; + default: + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS) { + if (RongCallPermissionUtil.checkPermissionByType(this, mediaType)) { + if (startForCheckPermissions) { + RongCallClient.getInstance().onPermissionGranted(); + } else { + setupIntent(); + } + } else { + if (startForCheckPermissions) { + RongCallClient.getInstance().onPermissionDenied(); + } else { + RLog.i("AudioPlugin", "onActivityResult finish"); + finish(); + } + } + + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + + private void setupIntent() { + RongCallCommon.CallMediaType mediaType; + Intent intent = getIntent(); + RongCallAction callAction = RongCallAction.valueOf(intent.getStringExtra("callAction")); + // if (callAction.equals(RongCallAction.ACTION_RESUME_CALL)) { + // return; + // } + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + callSession = intent.getParcelableExtra("callSession"); + mediaType = callSession.getMediaType(); + targetId = callSession.getInviterUserId(); + RongCallClient.getInstance() + .startIncomingPreview( + new StartIncomingPreviewCallback() { + @Override + public void onDone(boolean isFront, SurfaceView localVideo) { + if (callSession + .getMediaType() + .equals(RongCallCommon.CallMediaType.VIDEO)) { + mLPreviewContainer.setVisibility(View.VISIBLE); + localVideo.setTag(callSession.getSelfUserId()); + mLPreviewContainer.addView(localVideo, mLargeLayoutParams); + } + } + + @Override + public void onError(int errorCode) {} + }); + } else if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) { + if (intent.getAction().equals(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO)) { + mediaType = RongCallCommon.CallMediaType.AUDIO; + } else { + mediaType = RongCallCommon.CallMediaType.VIDEO; + } + Conversation.ConversationType conversationType = + Conversation.ConversationType.valueOf( + intent.getStringExtra("conversationType").toUpperCase(Locale.US)); + targetId = intent.getStringExtra("targetId"); + RongCallCommon.RoomType roomType = RongCallCommon.RoomType.NORMAL; + if (intent.hasExtra("roomType")) { + try { + roomType = (RoomType) intent.getSerializableExtra("roomType"); + } catch (Exception e) { + e.printStackTrace(); + } + } + List userIds = new ArrayList<>(); + userIds.add(targetId); + + RongCallClient.setPushConfig( + DefaultPushConfig.getInviteConfig( + this, mediaType == RongCallCommon.CallMediaType.AUDIO, true, ""), + DefaultPushConfig.getHangupConfig(this, true, "")); + + if (isCrossCall(targetId)) { + roomType = RongCallCommon.RoomType.CROSS; + } else { + roomType = RongCallCommon.RoomType.NORMAL; + } + FinLog.i(TAG, "call type: " + roomType.name() + " targetId" + targetId); + + if (roomType == RongCallCommon.RoomType.NORMAL) { + RongCallClient.getInstance() + .startCall(conversationType, targetId, userIds, null, mediaType, null); + } else { + RongCallClient.getInstance() + .startCrossCall(conversationType, targetId, userIds, null, mediaType, null); + } + } else { // resume call + callSession = RongCallClient.getInstance().getCallSession(); + mediaType = callSession.getMediaType(); + } + + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + handFree = false; + } else if (mediaType.equals(RongCallCommon.CallMediaType.VIDEO)) { + handFree = true; + } + + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); + if (userInfo != null) { + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO) + || callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + ImageView userPortrait = + (ImageView) mUserInfoContainer.findViewById(R.id.rc_voip_user_portrait); + if (userPortrait != null && userInfo.getPortraitUri() != null) { + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + } + TextView userName = + (TextView) mUserInfoContainer.findViewById(R.id.rc_voip_user_name); + userName.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + } + } + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL) && userInfo != null) { + ImageView iv_icoming_backgroud = + (ImageView) mUserInfoContainer.findViewById(R.id.iv_icoming_backgroud); + if (iv_icoming_backgroud != null) { + iv_icoming_backgroud.setVisibility(View.VISIBLE); + GlideUtils.showBlurTransformation( + SingleCallActivity.this, iv_icoming_backgroud, userInfo.getPortraitUri()); + } + } + createPickupDetector(); + } + + private boolean isCrossCall(String targetId) { + if (!TextUtils.isEmpty(targetId) && targetId.contains("_")) { + String[] pairs = targetId.split("_"); + if (pairs.length == 2 && pairs[0].length() == 13) { + return true; + } + } + return false; + } + + @Override + protected void onResume() { + super.onResume(); + RLog.d(TAG, "---single activity onResume---"); + if (pickupDetector != null && mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + pickupDetector.register(this); + } + } + + @Override + protected void onPause() { + super.onPause(); + RLog.d(TAG, "---single activity onPause---"); + if (pickupDetector != null) { + pickupDetector.unRegister(); + } + } + + private void initView(RongCallCommon.CallMediaType mediaType, RongCallAction callAction) { + RelativeLayout buttonLayout = + (RelativeLayout) + inflater.inflate( + R.layout.rc_voip_call_bottom_connected_button_layout, null); + RelativeLayout userInfoLayout = null; + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + userInfoLayout = + (RelativeLayout) + inflater.inflate(R.layout.rc_voip_audio_call_user_info_incoming, null); + userInfoLayout.findViewById(R.id.iv_large_preview_Mask).setVisibility(View.VISIBLE); + } else { + // 单人视频 or 拨打 界面 + userInfoLayout = + (RelativeLayout) inflater.inflate(R.layout.rc_voip_audio_call_user_info, null); + TextView callInfo = + (TextView) userInfoLayout.findViewById(R.id.rc_voip_call_remind_info); + CallKitUtils.textViewShadowLayer(callInfo, SingleCallActivity.this); + } + + if (callAction.equals(RongCallAction.ACTION_RESUME_CALL) && CallKitUtils.isDial) { + try { + ImageView button = buttonLayout.findViewById(R.id.rc_voip_call_mute_btn); + button.setEnabled(false); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) { + RelativeLayout layout = buttonLayout.findViewById(R.id.rc_voip_call_mute); + layout.setVisibility(View.VISIBLE); + ImageView button = buttonLayout.findViewById(R.id.rc_voip_call_mute_btn); + button.setEnabled(true); + buttonLayout.findViewById(R.id.rc_voip_handfree).setVisibility(View.VISIBLE); + } + + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + findViewById(R.id.rc_voip_call_information) + .setBackgroundColor(getResources().getColor(R.color.rc_voip_background_color)); + mLPreviewContainer.setVisibility(View.GONE); + mSPreviewContainer.setVisibility(View.GONE); + + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + buttonLayout = + (RelativeLayout) + inflater.inflate( + R.layout.rc_voip_call_bottom_incoming_button_layout, null); + ImageView iv_answerBtn = + (ImageView) buttonLayout.findViewById(R.id.rc_voip_call_answer_btn); + iv_answerBtn.setBackground( + CallKitUtils.BackgroundDrawable( + R.drawable.rc_voip_audio_answer_selector_new, + SingleCallActivity.this)); + + TextView callInfo = + (TextView) userInfoLayout.findViewById(R.id.rc_voip_call_remind_info); + CallKitUtils.textViewShadowLayer(callInfo, SingleCallActivity.this); + callInfo.setText(R.string.rc_voip_audio_call_inviting); + onIncomingCallRinging(callSession); + } + } else if (mediaType.equals(RongCallCommon.CallMediaType.VIDEO)) { + if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + findViewById(R.id.rc_voip_call_information) + .setBackgroundColor(getResources().getColor(android.R.color.transparent)); + buttonLayout = + (RelativeLayout) + inflater.inflate( + R.layout.rc_voip_call_bottom_incoming_button_layout, null); + ImageView iv_answerBtn = + (ImageView) buttonLayout.findViewById(R.id.rc_voip_call_answer_btn); + iv_answerBtn.setBackground( + CallKitUtils.BackgroundDrawable( + R.drawable.rc_voip_vedio_answer_selector_new, + SingleCallActivity.this)); + + TextView callInfo = + (TextView) userInfoLayout.findViewById(R.id.rc_voip_call_remind_info); + CallKitUtils.textViewShadowLayer(callInfo, SingleCallActivity.this); + callInfo.setText(R.string.rc_voip_video_call_inviting); + onIncomingCallRinging(callSession); + } + } + mButtonContainer.removeAllViews(); + mButtonContainer.addView(buttonLayout); + mUserInfoContainer.removeAllViews(); + mUserInfoContainer.addView(userInfoLayout); + } + + @Override + public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) { + super.onCallOutgoing(callSession, localVideo); + this.callSession = callSession; + try { + UserInfo InviterUserIdInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); + UserInfo SelfUserInfo = + RongUserInfoManager.getInstance().getUserInfo(callSession.getSelfUserId()); + if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.VIDEO)) { + mLPreviewContainer.setVisibility(View.VISIBLE); + localVideo.setTag(callSession.getSelfUserId()); + mLPreviewContainer.addView(localVideo, mLargeLayoutParams); + if (null != SelfUserInfo && null != SelfUserInfo.getName()) { + // 单人视频 + TextView callkit_voip_user_name_signleVideo = + (TextView) + mUserInfoContainer.findViewById( + R.id.callkit_voip_user_name_signleVideo); + // topUserName = SelfUserInfo.getName(); + callkit_voip_user_name_signleVideo.setText( + CallKitUtils.nickNameRestrict(SelfUserInfo.getName())); + } + } else if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.AUDIO)) { + if (null != InviterUserIdInfo && null != InviterUserIdInfo.getPortraitUri()) { + ImageView iv_icoming_backgroud = + mUserInfoContainer.findViewById(R.id.iv_icoming_backgroud); + GlideUtils.showBlurTransformation( + SingleCallActivity.this, + iv_icoming_backgroud, + InviterUserIdInfo.getPortraitUri()); + iv_icoming_backgroud.setVisibility(View.VISIBLE); + mUserInfoContainer + .findViewById(R.id.iv_large_preview_Mask) + .setVisibility(View.VISIBLE); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + callRinging(RingingMode.Outgoing); + } + + @Override + public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) { + super.onCallConnected(callSession, localVideo); + this.callSession = callSession; + RLog.d(TAG, "onCallConnected----mediaType=" + callSession.getMediaType().getValue()); + if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.AUDIO)) { + findViewById(R.id.rc_voip_call_minimize).setVisibility(View.VISIBLE); + RelativeLayout btnLayout = + (RelativeLayout) + inflater.inflate( + R.layout.rc_voip_call_bottom_connected_button_layout, null); + ImageView button = btnLayout.findViewById(R.id.rc_voip_call_mute_btn); + button.setEnabled(true); + mButtonContainer.removeAllViews(); + mButtonContainer.addView(btnLayout); + RCRTCEngine.getInstance().enableSpeaker(handFree); + } else { + mConnectionStateTextView.setVisibility(View.VISIBLE); + mConnectionStateTextView.setText(R.string.rc_voip_connecting); + // 二人视频通话接通后 mUserInfoContainer 中更换为无头像的布局 + mUserInfoContainer.removeAllViews(); + inflater.inflate(R.layout.rc_voip_video_call_user_info, mUserInfoContainer); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); + if (userInfo != null) { + TextView userName = mUserInfoContainer.findViewById(R.id.rc_voip_user_name); + userName.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + // userName.setShadowLayer(16F, 0F, 2F, + // getResources().getColor(R.color.rc_voip_reminder_shadow));//callkit_shadowcolor + CallKitUtils.textViewShadowLayer(userName, SingleCallActivity.this); + } + mLocalVideo = localVideo; + mLocalVideo.setTag(callSession.getSelfUserId()); + RCRTCEngine.getInstance().enableSpeaker(true); + } + TextView tv_rc_voip_call_remind_info = + (TextView) mUserInfoContainer.findViewById(R.id.rc_voip_call_remind_info); + CallKitUtils.textViewShadowLayer(tv_rc_voip_call_remind_info, SingleCallActivity.this); + tv_rc_voip_call_remind_info.setVisibility(View.GONE); + TextView remindInfo = null; + if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.AUDIO)) { + remindInfo = mUserInfoContainer.findViewById(R.id.tv_setupTime); + } else { + remindInfo = mUserInfoContainer.findViewById(R.id.tv_setupTime_video); + } + if (remindInfo == null) { + remindInfo = tv_rc_voip_call_remind_info; + } + setupTime(remindInfo); + + RongCallClient.getInstance().setEnableLocalAudio(!muted); + View muteV = mButtonContainer.findViewById(R.id.rc_voip_call_mute); + if (muteV != null) { + muteV.setSelected(muted); + } + + stopRing(); + } + + protected void resetHandFreeStatus(RCAudioRouteType type) { + ImageView handFreeV = null; + if (null != mButtonContainer) { + handFreeV = mButtonContainer.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + if (type == RCAudioRouteType.HEADSET || type == RCAudioRouteType.HEADSET_BLUETOOTH) { + // 耳机态下不在将扬声器设为关闭 + // handFreeV.setSelected(false); + } else { + // 非耳机状态 + handFreeV.setSelected(type == RCAudioRouteType.SPEAKER_PHONE); + } + } + } + + @Override + protected void onDestroy() { + RLog.d(TAG, "---single activity onDestroy---"); + stopRing(); + super.onDestroy(); + } + + private RongCallCommon.CallMediaType remoteMediaType; + int userType; + SurfaceView remoteVideo; + String remoteUserId; + /** 远端首帧是否到来, 音频帧跟视频帧其中一个到来就更改该标记, 从而更新连接状态 */ + boolean isFirstRemoteFrame = false; + + @Override + public void onRemoteUserJoined( + final String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + super.onRemoteUserJoined(userId, mediaType, userType, remoteVideo); + RLog.v( + TAG, + "onRemoteUserJoined userID=" + + userId + + ",mediaType=" + + mediaType.name() + + " , userType=" + + (userType == 1 ? "Normal" : "Observer")); + this.remoteMediaType = mediaType; + this.userType = userType; + this.remoteVideo = remoteVideo; + this.remoteUserId = userId; + } + + @Override + public void onFirstRemoteAudioFrame(String userId) { + super.onFirstRemoteAudioFrame(userId); + RLog.v(TAG, "onFirstRemoteAudioFrame "); + if (!isFirstRemoteFrame) { + changeToConnectedState(userId, remoteMediaType, userType, remoteVideo); + isFirstRemoteFrame = true; + } + } + + @Override + public void onRemoteUserPublishVideoStream( + String userId, String streamId, String tag, SurfaceView surfaceView) { + super.onRemoteUserPublishVideoStream(userId, streamId, tag, surfaceView); + RLog.v(TAG, "onRemoteUserPublishVideoStream userID=" + userId + ",streamId=" + streamId); + this.remoteVideo = surfaceView; + addRemoteVideoView(userId, remoteVideo); + } + + private void changeToConnectedState( + String userId, + RongCallCommon.CallMediaType mediaType, + int userType, + SurfaceView remoteVideo) { + mConnectionStateTextView.setVisibility(View.GONE); + if (RongCallCommon.CallMediaType.VIDEO.equals(mediaType)) { + if (remoteVideo != null) { + addRemoteVideoView(userId, remoteVideo); + } + mSPreviewContainer.setVisibility(View.VISIBLE); + mSPreviewContainer.removeAllViews(); + RLog.d(TAG, "onRemoteUserJoined mLocalVideo != null=" + (mLocalVideo != null)); + if (mLocalVideo != null) { + mLocalVideo.setZOrderMediaOverlay(true); + mLocalVideo.setZOrderOnTop(true); + mSPreviewContainer.addView(mLocalVideo); + } + /** 小窗口点击事件 * */ + mSPreviewContainer.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + try { + final SurfaceView fromView = + (SurfaceView) mSPreviewContainer.getChildAt(0); + SurfaceView toView = (SurfaceView) mLPreviewContainer.getChildAt(0); + fromView.setVisibility(View.INVISIBLE); + + mLPreviewContainer.removeAllViews(); + mSPreviewContainer.removeAllViews(); + fromView.setZOrderOnTop(false); + fromView.setZOrderMediaOverlay(false); + mLPreviewContainer.addView(fromView, mLargeLayoutParams); + toView.setZOrderOnTop(true); + toView.setZOrderMediaOverlay(true); + mSPreviewContainer.addView(toView); + mSPreviewContainer.postDelayed( + new Runnable() { + @Override + public void run() { + fromView.setVisibility(View.VISIBLE); + } + }, + 30); + if (null != fromView.getTag() + && !TextUtils.isEmpty(fromView.getTag().toString())) { + UserInfo userInfo = + RongUserInfoManager.getInstance() + .getUserInfo(fromView.getTag().toString()); + TextView userName = + (TextView) + mUserInfoContainer.findViewById( + R.id.rc_voip_user_name); + // topUserName = + // userInfo.getName(); + userName.setText( + CallKitUtils.nickNameRestrict(userInfo.getName())); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + mButtonContainer.setVisibility(View.GONE); + mUserInfoContainer.setVisibility(View.GONE); + } + } + + /** + * 当前的布局中是否包含了 RemoteVideoView + * + * @param remoteVideo + * @return + */ + protected boolean hasRemoteVideoView(SurfaceView remoteVideo) { + int count = mLPreviewContainer.getChildCount(); + if (count == 0) { + return false; + } + for (int i = 0; i < count; i++) { + View view = mLPreviewContainer.getChildAt(i); + if (view == remoteVideo) { + return true; + } + } + return false; + } + + private void addRemoteVideoView(String userId, SurfaceView remoteVideo) { + if (remoteVideo == null) { + RLog.e(TAG, "addRemoteVideoView: remoteVideo is null!"); + return; + } + if (hasRemoteVideoView(remoteVideo)) { + RLog.v(TAG, "onRemoteUserJoined hasRemoteVideoView"); + return; + } + + if (remoteVideo.getParent() != null) { + RLog.v(TAG, "onRemoteUserJoined remoteVideo.getParent() != null"); + return; + } + + findViewById(R.id.rc_voip_call_information) + .setBackgroundColor(getResources().getColor(android.R.color.transparent)); + mLPreviewContainer.setVisibility(View.VISIBLE); + mLPreviewContainer.removeAllViews(); + remoteVideo.setTag(userId); + RLog.v(TAG, "onRemoteUserJoined mLPreviewContainer.addView(remoteVideo)"); + mLPreviewContainer.addView(remoteVideo, mLargeLayoutParams); + mLPreviewContainer.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + RLog.v(TAG, "setOnClickListener. isInformationShow : " + isInformationShow); + if (isInformationShow) { + hideVideoCallInformation(); + } else { + showVideoCallInformation(); + handler.sendEmptyMessageDelayed(EVENT_FULL_SCREEN, 5 * 1000); + } + } + }); + } + + /** + * 当通话中的某一个参与者切换通话类型,例如由 audio 切换至 video,回调 onMediaTypeChanged。 + * + * @param userId 切换者的 userId。 + * @param mediaType 切换者,切换后的媒体类型。 + * @param video 切换着,切换后的 camera 信息,如果由 video 切换至 audio,则为 null。 + */ + @Override + public void onMediaTypeChanged( + String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) { + if (callSession.getSelfUserId().equals(userId)) { + showShortToast(getString(R.string.rc_voip_switched_to_audio)); + } else { + if (callSession.getMediaType() != RongCallCommon.CallMediaType.AUDIO) { + RongCallClient.getInstance() + .changeCallMediaType(RongCallCommon.CallMediaType.AUDIO); + callSession.setMediaType(RongCallCommon.CallMediaType.AUDIO); + showShortToast(getString(R.string.rc_voip_remote_switched_to_audio)); + } + } + initAudioCallView(); + handler.removeMessages(EVENT_FULL_SCREEN); + mButtonContainer.findViewById(R.id.rc_voip_call_mute).setSelected(muted); + } + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) { + // RLog.d(TAG, "onNetworkReceiveLost : userId =" + userId + " lossRate=" + + // lossRate); + isReceiveLost = lossRate > LOSS_RATE_ALARM; + handler.post( + new Runnable() { + @Override + public void run() { + refreshConnectionState(); + } + }); + } + + @Override + public void onNetworkSendLost(int lossRate, int delay) { + // RLog.d(TAG, "onNetworkSendLost : rate =" + lossRate + " delay=" + delay); + isSendLost = lossRate > LOSS_RATE_ALARM; + handler.post( + new Runnable() { + @Override + public void run() { + refreshConnectionState(); + } + }); + } + + @Override + public void onFirstRemoteVideoFrame(String userId, int height, int width) { + RLog.d(TAG, "onFirstRemoteVideoFrame for user::" + userId); + if (userId.equals(remoteUserId)) { + // mConnectionStateTextView.setVisibility(View.GONE); + if (!isFirstRemoteFrame) { + changeToConnectedState(userId, remoteMediaType, userType, remoteVideo); + isFirstRemoteFrame = true; + } + } + } + + /** 视频转语音 * */ + private void initAudioCallView() { + mLPreviewContainer.removeAllViews(); + mLPreviewContainer.setVisibility(View.GONE); + mSPreviewContainer.removeAllViews(); + mSPreviewContainer.setVisibility(View.GONE); + // 显示全屏底色 + findViewById(R.id.rc_voip_call_information) + .setBackgroundColor(getResources().getColor(R.color.rc_voip_background_color)); + findViewById(R.id.rc_voip_audio_chat).setVisibility(View.GONE); // 隐藏语音聊天按钮 + + View userInfoView = inflater.inflate(R.layout.rc_voip_audio_call_user_info_incoming, null); + TextView tv_rc_voip_call_remind_info = + (TextView) userInfoView.findViewById(R.id.rc_voip_call_remind_info); + tv_rc_voip_call_remind_info.setVisibility(View.GONE); + + TextView timeView = (TextView) userInfoView.findViewById(R.id.tv_setupTime); + setupTime(timeView); + + mUserInfoContainer.removeAllViews(); + mUserInfoContainer.addView(userInfoView); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); + if (userInfo != null) { + TextView userName = (TextView) mUserInfoContainer.findViewById(R.id.rc_voip_user_name); + userName.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + if (callSession.getMediaType().equals(RongCallCommon.CallMediaType.AUDIO)) { + ImageView userPortrait = + (ImageView) mUserInfoContainer.findViewById(R.id.rc_voip_user_portrait); + if (userPortrait != null) { + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + // Glide.with(this) + // .load(userInfo.getPortraitUri()) + // .placeholder(R.drawable.rc_default_portrait) + // .apply(RequestOptions.bitmapTransform(new + // CircleCrop())) + // .into(userPortrait); + } + } else { // 单人视频接听layout + ImageView iv_large_preview = mUserInfoContainer.findViewById(R.id.iv_large_preview); + iv_large_preview.setVisibility(View.VISIBLE); + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + iv_large_preview); + } + } + mUserInfoContainer.setVisibility(View.VISIBLE); + mUserInfoContainer.findViewById(R.id.rc_voip_call_minimize).setVisibility(View.VISIBLE); + + View button = inflater.inflate(R.layout.rc_voip_call_bottom_connected_button_layout, null); + mButtonContainer.removeAllViews(); + mButtonContainer.addView(button); + mButtonContainer.setVisibility(View.VISIBLE); + // 视频转音频时默认不开启免提 + handFree = false; + RongCallClient.getInstance().setEnableSpeakerphone(false); + View handFreeV = mButtonContainer.findViewById(R.id.rc_voip_handfree); + handFreeV.setSelected(handFree); + + ImageView iv_large_preview_Mask = + (ImageView) userInfoView.findViewById(R.id.iv_large_preview_Mask); + iv_large_preview_Mask.setVisibility(View.VISIBLE); + + /** 视频切换成语音 全是语音界面的ui* */ + ImageView iv_large_preview = mUserInfoContainer.findViewById(R.id.iv_icoming_backgroud); + + if (null != userInfo + && callSession.getMediaType().equals(RongCallCommon.CallMediaType.AUDIO)) { + GlideUtils.showBlurTransformation( + SingleCallActivity.this, iv_large_preview, userInfo.getPortraitUri()); + iv_large_preview.setVisibility(View.VISIBLE); + } + + if (pickupDetector != null) { + pickupDetector.register(this); + } + } + + public void onHangupBtnClick(View view) { + // unRegisterHeadsetplugReceiver(); + RongCallSession session = RongCallClient.getInstance().getCallSession(); + if (session == null || isFinishing) { + finish(); + RLog.e( + TAG, + "hangup call error: callSession=" + + (callSession == null) + + ",isFinishing=" + + isFinishing); + return; + } + RongCallClient.getInstance().hangUpCall(session.getCallId()); + stopRing(); + } + + public void onReceiveBtnClick(View view) { + RongCallSession session = RongCallClient.getInstance().getCallSession(); + if (session == null || isFinishing) { + RLog.e( + TAG, + "hangup call error: callSession=" + + (callSession == null) + + ",isFinishing=" + + isFinishing); + finish(); + return; + } + RongCallClient.getInstance().acceptCall(session.getCallId()); + } + + public void hideVideoCallInformation() { + isInformationShow = false; + mUserInfoContainer.setVisibility(View.GONE); + mButtonContainer.setVisibility(View.GONE); + findViewById(R.id.rc_voip_audio_chat).setVisibility(View.GONE); + } + + public void showVideoCallInformation() { + isInformationShow = true; + mUserInfoContainer.setVisibility(View.VISIBLE); + + mUserInfoContainer.findViewById(R.id.rc_voip_call_minimize).setVisibility(View.VISIBLE); + mButtonContainer.setVisibility(View.VISIBLE); + RelativeLayout btnLayout = + (RelativeLayout) + inflater.inflate( + R.layout.rc_voip_call_bottom_connected_button_layout, null); + btnLayout.findViewById(R.id.rc_voip_call_mute).setSelected(muted); + btnLayout.findViewById(R.id.rc_voip_handfree).setVisibility(View.GONE); + btnLayout.findViewById(R.id.rc_voip_camera).setVisibility(View.VISIBLE); + mButtonContainer.removeAllViews(); + mButtonContainer.addView(btnLayout); + View view = findViewById(R.id.rc_voip_audio_chat); + // view.setVisibility(View.VISIBLE); + view.setVisibility(View.GONE); // 隐藏语音聊天按钮 + view.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (RongIMClient.getInstance().getCurrentConnectionStatus() + == RongIMClient.ConnectionStatusListener.ConnectionStatus + .CONNECTED) { + RongCallClient.getInstance() + .changeCallMediaType(RongCallCommon.CallMediaType.AUDIO); + callSession.setMediaType(RongCallCommon.CallMediaType.AUDIO); + initAudioCallView(); + } else { + showShortToast(getString(R.string.rc_voip_im_connection_abnormal)); + } + } + }); + } + + public void onHandFreeButtonClick(View view) { + CallKitUtils.speakerphoneState = !view.isSelected(); + RongCallClient.getInstance() + .setEnableSpeakerphone(!view.isSelected()); // true:打开免提 false:关闭免提 + view.setSelected(!view.isSelected()); + handFree = view.isSelected(); + } + + public void onMuteButtonClick(View view) { + RongCallClient.getInstance().setEnableLocalAudio(view.isSelected()); + view.setSelected(!view.isSelected()); + muted = view.isSelected(); + } + + @Override + public void onCallDisconnected( + RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + super.onCallDisconnected(callSession, reason); + + String senderId; + String extra = ""; + + isFinishing = true; + if (callSession == null) { + RLog.e(TAG, "onCallDisconnected. callSession is null!"); + postRunnableDelay( + new Runnable() { + @Override + public void run() { + finish(); + } + }); + return; + } + senderId = callSession.getInviterUserId(); + long time = getTime(callSession.getActiveTime()); + if (time > 0) { + if (time >= 3600) { + extra = + String.format( + Locale.ROOT, + "%d:%02d:%02d", + time / 3600, + (time % 3600) / 60, + (time % 60)); + } else { + extra = String.format(Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60)); + } + } + cancelTime(); + + if (!TextUtils.isEmpty(senderId)) { + CallSTerminateMessage message = new CallSTerminateMessage(); + message.setReason(reason); + message.setMediaType(callSession.getMediaType()); + message.setExtra(extra); + long serverTime = + System.currentTimeMillis() - RongIMClient.getInstance().getDeltaTime(); + if (senderId.equals(callSession.getSelfUserId())) { + message.setDirection("MO"); + IMCenter.getInstance() + .insertOutgoingMessage( + Conversation.ConversationType.PRIVATE, + callSession.getTargetId(), + io.rong.imlib.model.Message.SentStatus.SENT, + message, + serverTime, + null); + } else { + message.setDirection("MT"); + IMCenter.getInstance() + .insertIncomingMessage( + Conversation.ConversationType.PRIVATE, + callSession.getTargetId(), + senderId, + CallKitUtils.getReceivedStatus(reason), + message, + serverTime, + null); + } + } + postRunnableDelay( + new Runnable() { + @Override + public void run() { + finish(); + } + }); + } + + private Runnable mCheckConnectionStableTask = + new Runnable() { + @Override + public void run() { + boolean isConnectionStable = !isSendLost && !isReceiveLost; + if (isConnectionStable) { + mConnectionStateTextView.setVisibility(View.GONE); + } + } + }; + + private void refreshConnectionState() { + if (isSendLost || isReceiveLost) { + if (mConnectionStateTextView.getVisibility() == View.GONE) { + mConnectionStateTextView.setText(R.string.rc_voip_unstable_call_connection); + mConnectionStateTextView.setVisibility(View.VISIBLE); + if (mSoundPool != null) { + mSoundPool.release(); + } + mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); + mSoundPool.load(this, R.raw.voip_network_error_sound, 0); + mSoundPool.setOnLoadCompleteListener( + new SoundPool.OnLoadCompleteListener() { + @Override + public void onLoadComplete( + SoundPool soundPool, int sampleId, int status) { + soundPool.play(sampleId, 1F, 1F, 0, 0, 1F); + } + }); + } + mConnectionStateTextView.removeCallbacks(mCheckConnectionStableTask); + mConnectionStateTextView.postDelayed(mCheckConnectionStableTask, 3000); + } + } + + @Override + public void onRestoreFloatBox(Bundle bundle) { + super.onRestoreFloatBox(bundle); + RLog.d(TAG, "---single activity onRestoreFloatBox---"); + if (bundle == null) return; + muted = bundle.getBoolean("muted"); + handFree = bundle.getBoolean("handFree"); + // topUserName=bundle.getString(EXTRA_BUNDLE_KEY_USER_TOP_NAME); + + setShouldShowFloat(true); + callSession = RongCallClient.getInstance().getCallSession(); + if (callSession == null) { + setShouldShowFloat(false); + finish(); + return; + } + RongCallCommon.CallMediaType mediaType = callSession.getMediaType(); + RongCallAction callAction = + RongCallAction.valueOf(getIntent().getStringExtra("callAction")); + inflater = LayoutInflater.from(this); + initView(mediaType, callAction); + targetId = callSession.getTargetId(); + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); + if (userInfo != null) { + TextView userName = (TextView) mUserInfoContainer.findViewById(R.id.rc_voip_user_name); + userName.setText(CallKitUtils.nickNameRestrict(userInfo.getName())); + if (mediaType.equals(RongCallCommon.CallMediaType.AUDIO)) { + ImageView userPortrait = + (ImageView) mUserInfoContainer.findViewById(R.id.rc_voip_user_portrait); + if (userPortrait != null) { + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + } + } else if (mediaType.equals(RongCallCommon.CallMediaType.VIDEO)) { + if (null != callAction && callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) { + ImageView iv_large_preview = + mUserInfoContainer.findViewById(R.id.iv_large_preview); + iv_large_preview.setVisibility(View.VISIBLE); + Uri imgUri = userInfo == null ? null : userInfo.getPortraitUri(); + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + imgUri, + R.drawable.rc_default_portrait, + iv_large_preview); + } + } + } + SurfaceView localVideo = null; + SurfaceView remoteVideo = null; + String remoteUserId = null; + for (CallUserProfile profile : callSession.getParticipantProfileList()) { + if (profile.getUserId().equals(RongIMClient.getInstance().getCurrentUserId())) { + localVideo = profile.getVideoView(); + } else { + remoteVideo = profile.getVideoView(); + remoteUserId = profile.getUserId(); + } + } + if (localVideo != null && localVideo.getParent() != null) { + ((ViewGroup) localVideo.getParent()).removeView(localVideo); + } + onCallOutgoing(callSession, localVideo); + if (!(boolean) bundle.get("isDial")) { + onCallConnected(callSession, localVideo); + } + if (remoteVideo != null) { + if (remoteVideo.getParent() != null) { + ((ViewGroup) remoteVideo.getParent()).removeView(remoteVideo); + } + changeToConnectedState(remoteUserId, mediaType, 1, remoteVideo); + } + } + + @Override + public String onSaveFloatBoxState(Bundle bundle) { + super.onSaveFloatBoxState(bundle); + callSession = RongCallClient.getInstance().getCallSession(); + if (callSession == null) { + return null; + } + bundle.putBoolean("muted", muted); + bundle.putBoolean("handFree", handFree); + bundle.putInt("mediaType", callSession.getMediaType().getValue()); + // bundle.putString(EXTRA_BUNDLE_KEY_USER_TOP_NAME, topUserName); + return getIntent().getAction(); + } + + public void onMinimizeClick(View view) { + super.onMinimizeClick(view); + } + + public void onSwitchCameraClick(View view) { + RongCallClient.getInstance().switchCamera(); + } + + @Override + public void onBackPressed() { + return; + // List participantProfiles = + // callSession.getParticipantProfileList(); + // RongCallCommon.CallStatus callStatus = null; + // for (CallUserProfile item : participantProfiles) { + // if (item.getUserId().equals(callSession.getSelfUserId())) { + // callStatus = item.getCallStatus(); + // break; + // } + // } + // if (callStatus != null && callStatus.equals(RongCallCommon.CallStatus.CONNECTED)) + // { + // super.onBackPressed(); + // } else { + // RongCallClient.getInstance().hangUpCall(callSession.getCallId()); + // } + } + + @Override + public void onUserUpdate(UserInfo info) { + if (isFinishing()) { + return; + } + if (targetId != null && targetId.equals(info.getUserId())) { + TextView userName = (TextView) mUserInfoContainer.findViewById(R.id.rc_voip_user_name); + if (info.getName() != null) + userName.setText(CallKitUtils.nickNameRestrict(info.getName())); + + ImageView userPortrait = + (ImageView) mUserInfoContainer.findViewById(R.id.rc_voip_user_portrait); + if (userPortrait != null + && info.getPortraitUri() != null + && userPortrait.getVisibility() == View.VISIBLE) { + RongCallKit.getKitImageEngine() + .loadPortrait( + getBaseContext(), + info.getPortraitUri(), + R.drawable.rc_default_portrait, + userPortrait); + } + } + } + + public void onHeadsetPlugUpdate(HeadsetInfo headsetInfo) { + if (headsetInfo == null || !BluetoothUtil.isForground(SingleCallActivity.this)) { + RLog.v(TAG, "SingleCallActivity 不在前台!"); + return; + } + RLog.v( + TAG, + "Insert=" + + headsetInfo.isInsert() + + ",headsetInfo.getType=" + + headsetInfo.getType().getValue()); + try { + if (headsetInfo.isInsert()) { + RongCallClient.getInstance().setEnableSpeakerphone(false); + ImageView handFreeV = null; + if (null != mButtonContainer) { + handFreeV = mButtonContainer.findViewById(R.id.rc_voip_handfree_btn); + } + if (handFreeV != null) { + handFreeV.setSelected(false); + handFreeV.setEnabled(false); + handFreeV.setClickable(false); + } + if (headsetInfo.getType() == HeadsetInfo.HeadsetType.BluetoothA2dp) { + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + am.setMode(AudioManager.MODE_IN_COMMUNICATION); + am.startBluetoothSco(); + am.setBluetoothScoOn(true); + am.setSpeakerphoneOn(false); + } + } else { + if (headsetInfo.getType() == HeadsetInfo.HeadsetType.WiredHeadset + && BluetoothUtil.hasBluetoothA2dpConnected()) { + return; + } + RongCallClient.getInstance().setEnableSpeakerphone(true); + ImageView handFreeV = mButtonContainer.findViewById(R.id.rc_voip_handfree_btn); + if (handFreeV != null) { + handFreeV.setSelected(true); + handFreeV.setEnabled(true); + handFreeV.setClickable(true); + } + } + } catch (Exception e) { + e.printStackTrace(); + RLog.d(TAG, "SingleCallActivity->onHeadsetPlugUpdate Error=" + e.getMessage()); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/VideoPlugin.java b/callkit/src/main/java/io/rong/callkit/VideoPlugin.java new file mode 100644 index 000000000..c279a15a0 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/VideoPlugin.java @@ -0,0 +1,189 @@ +package io.rong.callkit; + +import static io.rong.callkit.BaseCallActivity.REQUEST_CODE_ADD_MEMBER; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import io.rong.callkit.util.CallKitUtils; +import io.rong.callkit.util.RongCallPermissionUtil; +import io.rong.callkit.util.permission.PermissionType; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.common.RLog; +import io.rong.imkit.conversation.extension.RongExtension; +import io.rong.imkit.conversation.extension.component.plugin.IPluginModule; +import io.rong.imkit.conversation.extension.component.plugin.IPluginRequestPermissionResultCallback; +import io.rong.imlib.IRongCoreCallback; +import io.rong.imlib.IRongCoreEnum; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.discussion.base.RongDiscussionClient; +import io.rong.imlib.discussion.model.Discussion; +import io.rong.imlib.model.Conversation; +import java.util.ArrayList; +import java.util.Locale; + +/** Created by weiqinxiao on 16/8/16. */ +public class VideoPlugin implements IPluginModule, IPluginRequestPermissionResultCallback { + private static final String TAG = "VideoPlugin"; + private ArrayList allMembers; + private Context context; + + private Conversation.ConversationType conversationType; + private String targetId; + + @Override + public Drawable obtainDrawable(Context context) { + return context.getResources().getDrawable(R.drawable.rc_ic_video_selector); + } + + @Override + public String obtainTitle(Context context) { + return context.getString(R.string.rc_voip_video); + } + + @Override + public void onClick(Fragment currentFragment, RongExtension extension, int index) { + context = currentFragment.getActivity().getApplicationContext(); + conversationType = extension.getConversationType(); + targetId = extension.getTargetId(); + + PermissionType[] audioCallPermissions = + RongCallPermissionUtil.getVideoCallPermissions(context); + String[] permissions = new String[audioCallPermissions.length]; + for (int i = 0; i < audioCallPermissions.length; i++) { + permissions[i] = audioCallPermissions[i].getPermissionName(); + } + if (RongCallPermissionUtil.checkPermissions(currentFragment.getActivity(), permissions)) { + startVideoActivity(extension); + } else { + extension.requestPermissionForPluginResult( + permissions, + IPluginRequestPermissionResultCallback.REQUEST_CODE_PERMISSION_PLUGIN, + this); + } + } + + private void startVideoActivity(final RongExtension extension) { + + RongCallSession profile = RongCallClient.getInstance().getCallSession(); + if (profile != null && profile.getStartTime() > 0) { + Toast.makeText( + context, + profile.getMediaType() == RongCallCommon.CallMediaType.AUDIO + ? context.getString(R.string.rc_voip_call_audio_start_fail) + : context.getString(R.string.rc_voip_call_video_start_fail), + Toast.LENGTH_SHORT) + .show(); + return; + } + if (!CallKitUtils.isNetworkAvailable(context)) { + Toast.makeText( + context, + context.getString(R.string.rc_voip_call_network_error), + Toast.LENGTH_SHORT) + .show(); + return; + } + if (conversationType.equals(Conversation.ConversationType.PRIVATE)) { + Intent intent = new Intent(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEVIDEO); + intent.putExtra("conversationType", conversationType.getName().toLowerCase(Locale.US)); + intent.putExtra("targetId", targetId); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + context.getApplicationContext().startActivity(intent); + } else if (conversationType.equals(Conversation.ConversationType.DISCUSSION)) { + RongDiscussionClient.getInstance() + .getDiscussion( + targetId, + new IRongCoreCallback.ResultCallback() { + @Override + public void onSuccess(Discussion discussion) { + + Intent intent = + new Intent(context, CallSelectMemberActivity.class); + allMembers = (ArrayList) discussion.getMemberIdList(); + intent.putStringArrayListExtra("allMembers", allMembers); + String myId = RongIMClient.getInstance().getCurrentUserId(); + ArrayList invited = new ArrayList<>(); + invited.add(myId); + intent.putStringArrayListExtra("invitedMembers", invited); + intent.putExtra( + "conversationType", conversationType.getValue()); + intent.putExtra( + "mediaType", + RongCallCommon.CallMediaType.VIDEO.getValue()); + extension.startActivityForPluginResult( + intent, 110, VideoPlugin.this); + } + + @Override + public void onError(IRongCoreEnum.CoreErrorCode e) { + RLog.d(TAG, "get discussion errorCode = " + e.getValue()); + } + }); + } else if (conversationType.equals(Conversation.ConversationType.GROUP)) { + Intent intent = new Intent(context, CallSelectMemberActivity.class); + String myId = RongIMClient.getInstance().getCurrentUserId(); + ArrayList invited = new ArrayList<>(); + invited.add(myId); + intent.putStringArrayListExtra("invitedMembers", invited); + intent.putExtra("groupId", targetId); + intent.putExtra("conversationType", conversationType.getValue()); + intent.putExtra("mediaType", RongCallCommon.CallMediaType.VIDEO.getValue()); + extension.startActivityForPluginResult(intent, 110, this); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode != Activity.RESULT_OK) { + return; + } + + if (requestCode == REQUEST_CODE_ADD_MEMBER) { + if (resultCode == Activity.RESULT_OK) { + if (data.getBooleanExtra("remote_hangup", false)) { + RLog.d(TAG, "Remote exit, end the call."); + return; + } + } + } + + Intent intent = new Intent(RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO); + ArrayList userIds = data.getStringArrayListExtra("invited"); + ArrayList observerIds = data.getStringArrayListExtra("observers"); + userIds.add(RongIMClient.getInstance().getCurrentUserId()); + intent.putExtra("conversationType", conversationType.getName().toLowerCase(Locale.US)); + intent.putExtra("targetId", targetId); + intent.putExtra("callAction", RongCallAction.ACTION_OUTGOING_CALL.getName()); + intent.putStringArrayListExtra("invitedUsers", userIds); + intent.putStringArrayListExtra("observerUsers", observerIds); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + context.getApplicationContext().startActivity(intent); + } + + @Override + public boolean onRequestPermissionResult( + Fragment fragment, + RongExtension extension, + int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + Context context = fragment.getContext(); + if (RongCallPermissionUtil.checkPermissions(context, permissions)) { + startVideoActivity(extension); + } else { + RongCallPermissionUtil.showRequestPermissionFailedAlter( + context, permissions, grantResults); + } + return true; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/VoIPBroadcastReceiver.java b/callkit/src/main/java/io/rong/callkit/VoIPBroadcastReceiver.java new file mode 100644 index 000000000..08013ce79 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/VoIPBroadcastReceiver.java @@ -0,0 +1,526 @@ +package io.rong.callkit; + +import static android.content.Context.NOTIFICATION_SERVICE; + +import android.annotation.SuppressLint; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import androidx.core.app.NotificationCompat; +import io.rong.callkit.util.CallRingingUtil; +import io.rong.callkit.util.IncomingCallExtraHandleUtil; +import io.rong.callkit.util.RingingMode; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.common.fwlog.FwLog; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imlib.model.AndroidConfig; +import io.rong.imlib.model.Conversation.ConversationType; +import io.rong.imlib.model.Group; +import io.rong.imlib.model.MessagePushConfig; +import io.rong.imlib.model.UserInfo; +import io.rong.push.common.PushConst; +import io.rong.push.common.RLog; +import io.rong.push.notification.PushNotificationMessage; +import io.rong.push.notification.RongNotificationInterface; +import java.util.HashMap; +import java.util.Map; + +/** + * 为解决在 Android 10 以上版本不再允许后台运行 Activity,音视频的离线推送呼叫消息将由通知栏的形式展示给用户 Created by wangw on 2019-12-09. + */ +public class VoIPBroadcastReceiver extends BroadcastReceiver { + + public static final int DEFAULT_FCM_NOTIFICATION_ID = 5000; + private static final String HANGUP = "RC:VCHangup"; + private static final String INVITE = "RC:VCInvite"; + public static final String ACTION_CALLINVITEMESSAGE = "action.push.CallInviteMessage"; + public static final String ACTION_CALLINVITEMESSAGE_CLICKED = + "action.push.CallInviteMessage.CLICKED"; + public static final String ACTION_CALL_HANGUP_CLICKED = "action.push.voip.hangup.click"; + private static final String TAG = "VoIPBroadcastReceiver"; + public static final String ACTION_CLEAR_VOIP_NOTIFICATION = "action.voip.notification.clear"; + private static Map notificationCache = new HashMap<>(); + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + RLog.d(TAG, "onReceive.action:" + action); + + // 通知栏挂断按钮事件响应 + if (ACTION_CALL_HANGUP_CLICKED.equals(action)) { + RongCallSession session = + intent.getParcelableExtra(RongIncomingCallService.KEY_CALL_SESSION); + stopIncomingService(context); + if (session == null) { + RongCallClient.getInstance().hangUpCall(); + } else { + RongCallClient.getInstance().hangUpCall(session.getCallId()); + } + return; + } else if (ACTION_CLEAR_VOIP_NOTIFICATION.equals(action)) { + // 针对 Android 12 的业务逻辑 + IncomingCallExtraHandleUtil.removeNotification(context); + IncomingCallExtraHandleUtil.clear(); + clearNotificationCache(); + return; + } + + PushNotificationMessage message = intent.getParcelableExtra(PushConst.MESSAGE); + // bug fixed : https://rc-jira.rongcloud.net/browse/AC-903 + if (message == null) { + return; + } + RongCallSession callSession = null; + boolean checkPermissions = false; + if (intent.hasExtra("callsession")) { + callSession = intent.getParcelableExtra("callsession"); + checkPermissions = intent.getBooleanExtra("checkPermissions", false); + } + + if (!needShowNotification(context, message)) { + return; + } + + if (TextUtils.equals(ACTION_CALLINVITEMESSAGE, action)) { + if (callSession == null) { + RLog.d(TAG, "callSession is null: " + message); + // fcm voip 走的是透传,处理一下这种情况下,单独弹起一个通知拉起应用 + fcmShowNotification(context, message); + return; + } + clearFcmNotification(context); + String objName = message.getObjectName(); + if (TextUtils.equals(objName, INVITE)) { + IncomingCallExtraHandleUtil.cacheCallSession(callSession, checkPermissions); + UserInfo userInfo = + RongUserInfoManager.getInstance() + .getUserInfo(callSession.getCallerUserId()); + sendNotification(context, message, callSession, checkPermissions, userInfo); + } else { + IncomingCallExtraHandleUtil.clear(); + UserInfo userInfo = + RongUserInfoManager.getInstance() + .getUserInfo(callSession.getCallerUserId()); + sendNotification(context, message, callSession, checkPermissions, userInfo); + } + } else if (TextUtils.equals(ACTION_CALLINVITEMESSAGE_CLICKED, action)) { + IncomingCallExtraHandleUtil.removeNotification(context); + IncomingCallExtraHandleUtil.clear(); + clearNotificationCache(); + handleNotificationClickEvent( + context, + message, + callSession, + checkPermissions, + intent.getStringExtra(RongIncomingCallService.KEY_NEED_AUTO_ANSWER)); + } + } + + private void clearFcmNotification(Context context) { + RLog.d(TAG, "clearFcmNotification"); + NotificationManager nm = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (nm != null) { + nm.cancel(DEFAULT_FCM_NOTIFICATION_ID); + } + } + + public void fcmShowNotification(final Context context, PushNotificationMessage message) { + + try { + CallRingingUtil.getInstance().createNotificationChannel(context); + int smallIcon = + context.getResources() + .getIdentifier( + "notification_small_icon", + "drawable", + context.getPackageName()); + if (smallIcon <= 0) { + smallIcon = context.getApplicationInfo().icon; + } + Uri uri = + Uri.parse("rong://" + context.getPackageName()) + .buildUpon() + .appendPath("conversationlist") + .build(); + Intent intent = new Intent(); + intent.setData(uri); + intent.setPackage(context.getPackageName()); + // 目标activity的包名和类名 + PendingIntent pendingIntent; + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + pendingIntent = + PendingIntent.getActivity( + context, + 1000, + intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + pendingIntent = + PendingIntent.getActivity( + context, 1000, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder( + context, + CallRingingUtil.getInstance().getNotificationChannelId()) + .setContentText(message.getPushContent()) + .setContentTitle(message.getPushTitle()) + .setSmallIcon(smallIcon) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setCategory(NotificationCompat.CATEGORY_CALL) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .setOngoing(true); + Notification notification = notificationBuilder.build(); + NotificationManager notificationManager = null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + notificationManager = context.getSystemService(NotificationManager.class); + } + if (notificationManager != null) { + notificationManager.notify(DEFAULT_FCM_NOTIFICATION_ID, notification); + } + if (HANGUP.equals(message.getObjectName())) { + CallRingingUtil.getInstance().stopRinging(); + } else { + CallRingingUtil.getInstance().startRinging(context, RingingMode.Incoming); + } + + } catch (Exception e) { + io.rong.common.RLog.e(TAG, "onStartCommand = " + e.getMessage()); + e.printStackTrace(); + } + } + + private boolean needShowNotification(Context context, PushNotificationMessage message) { + if (message == null || context == null) { + return false; + } + if (INVITE.equals(message.getObjectName()) + && Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { + // Android 10 以下允许后台运行,直接交由会话列表界面拉取消息 + RLog.d(TAG, "handle VoIP event."); + try { + Intent newIntent = new Intent(); + newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri uri = + Uri.parse("rong://" + context.getPackageName()) + .buildUpon() + .appendPath("conversationlist") + .appendQueryParameter("isFromPush", "false") + .build(); + newIntent.setData(uri); + newIntent.setPackage(context.getPackageName()); + context.startActivity(newIntent); + } catch (Exception e) { + e.printStackTrace(); + return true; + } + return false; + } + return true; + } + + @SuppressLint("QueryPermissionsNeeded") + private void handleNotificationClickEvent( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions, + String needAutoAnswerCallId) { + Intent intent; + // 如果进程被杀 RongCallClient.getInstance() 返回Null + if (RongCallClient.getInstance() != null + && RongCallClient.getInstance().getCallSession() != null + && callSession != null) { + intent = RongCallModule.createVoIPIntent(context, callSession, checkPermissions); + RLog.d(TAG, "handleNotificationClickEvent: start call activity"); + } else { + intent = createConversationListIntent(context); + RLog.d(TAG, "handleNotificationClickEvent: start conversation activity"); + } + if (callSession != null && !TextUtils.isEmpty(needAutoAnswerCallId)) { + intent.putExtra(RongIncomingCallService.KEY_NEED_AUTO_ANSWER, callSession.getCallId()); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(context.getPackageName()); + // bug fixed : https://rc-jira.rongcloud.net/browse/AC-864 + if (intent.resolveActivity(context.getPackageManager()) != null) { + context.startActivity(intent); + } else { + StringBuilder builder = new StringBuilder("start activity with scheme : "); + if (intent.getData() != null) { + builder.append(intent.getData().toString()); + } + FwLog.write(FwLog.I, FwLog.IM, "L-VoIP_notify_scheme", "scheme", builder.toString()); + } + } + + private void sendNotification( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions, + UserInfo userInfo) { + RLog.d(TAG, "sendNotification: " + message.getObjectName()); + String pushContent; + boolean isAudio = callSession.getMediaType() == RongCallCommon.CallMediaType.AUDIO; + if (HANGUP.equals(message.getObjectName())) { + pushContent = + context.getResources().getString(R.string.rc_voip_call_terminalted_notify); + if (callSession.getConversationType().equals(ConversationType.GROUP) + && RongCallClient.getInstance().getCallSession() != null) { + return; // 群组消息,getCallSession不为空,说明收到的hangup并不是最后一个人发出的,此时不需要生成通知 + } + } else { + pushContent = + context.getResources() + .getString( + isAudio + ? R.string.rc_voip_audio_call_inviting + : R.string.rc_voip_video_call_inviting); + } + message.setPushContent(pushContent); + if (callSession.getConversationType().equals(ConversationType.PRIVATE)) { + if (userInfo != null && !TextUtils.isEmpty(userInfo.getName())) { + message.setPushTitle(userInfo.getName()); + } + } else if (callSession.getConversationType().equals(ConversationType.GROUP)) { + Group group = RongUserInfoManager.getInstance().getGroupInfo(callSession.getTargetId()); + if (group != null && !TextUtils.isEmpty(group.getName())) { + message.setPushTitle(group.getName()); + } + } + if (callSession != null && callSession.getPushConfig() != null) { + MessagePushConfig messagePushConfig = callSession.getPushConfig(); + if (!TextUtils.isEmpty(messagePushConfig.getPushTitle())) { + message.setPushTitle(messagePushConfig.getPushTitle()); + } + if (!TextUtils.isEmpty(messagePushConfig.getPushContent()) + && !messagePushConfig.getPushContent().equals("voip")) { + // message.setPushContent(messagePushConfig.getPushContent()); + } + if (messagePushConfig.isForceShowDetailContent()) { + message.setShowDetail(messagePushConfig.isForceShowDetailContent()); + } + AndroidConfig androidConfig = messagePushConfig.getAndroidConfig(); + if (androidConfig != null) { + message.setChannelIdHW(androidConfig.getChannelIdHW()); + message.setChannelIdMi(androidConfig.getChannelIdMi()); + message.setChannelIdOPPO(androidConfig.getChannelIdOPPO()); + message.setNotificationId(androidConfig.getNotificationId()); + } + } + sendNotification(context, message, callSession, checkPermissions); + } + + private void startIncomingService( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Bundle bundle = new Bundle(); + bundle.putParcelable(RongIncomingCallService.KEY_MESSAGE, message); + bundle.putParcelable(RongIncomingCallService.KEY_CALL_SESSION, callSession); + bundle.putBoolean(RongIncomingCallService.KEY_CHECK_PERMISSIONS, checkPermissions); + CallRingingUtil.getInstance().startRingingService(context, bundle); + } + } + + private void stopIncomingService(Context context) { + CallRingingUtil.getInstance().stopService(context); + } + + private void sendNotification( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions) { + String objName = message.getObjectName(); + if (TextUtils.isEmpty(objName)) { + return; + } + + String title; + String content; + int notificationId = IncomingCallExtraHandleUtil.VOIP_NOTIFICATION_ID; + RLog.i( + TAG, + "sendNotification() messageType: " + + message.getConversationType() + + " messagePushContent: " + + message.getPushContent() + + " messageObjectName: " + + message.getObjectName() + + " notificationId: " + + message.getNotificationId()); + + // Android 10 以上走新逻辑,通过服务启动 + if (Build.VERSION.SDK_INT >= 29) { + if (INVITE.equals(objName)) { + startIncomingService(context, message, callSession, checkPermissions); + } else if (HANGUP.equals(objName)) { + stopIncomingService(context); + sendHangupNotification(context, message, callSession, checkPermissions); + } + return; + } + + if (objName.equals(INVITE) || objName.equals(HANGUP)) { + content = message.getPushContent(); + title = message.getPushTitle(); + } else { + return; + } + + Notification notification = + RongNotificationInterface.createNotification( + context, + title, + createPendingIntent( + context, + message, + callSession, + checkPermissions, + IncomingCallExtraHandleUtil.VOIP_REQUEST_CODE, + false), + content, + RongNotificationInterface.SoundType.VOIP, + message.isShowDetail()); + NotificationManager nm = + (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + notification.flags |= Notification.FLAG_AUTO_CANCEL; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_HIGH; + String channelName = CallRingingUtil.getInstance().getNotificationChannelName(context); + NotificationChannel notificationChannel = + new NotificationChannel( + CallRingingUtil.getInstance().getNotificationChannelId(), + channelName, + importance); + notificationChannel.enableLights(true); + notificationChannel.setLightColor(Color.GREEN); + if (notification != null && notification.sound != null) { + notificationChannel.setSound(notification.sound, null); + } + nm.createNotificationChannel(notificationChannel); + } + if (notification != null) { + RLog.i( + TAG, + "sendNotification() real notify! notificationId: " + + notificationId + + " notification: " + + notification.toString()); + if (INVITE.equals(message.getObjectName())) { + notificationCache.put(callSession.getCallId(), notificationId); + nm.notify(notificationId, notification); + IncomingCallExtraHandleUtil.VOIP_NOTIFICATION_ID++; + } else if (notificationCache.containsKey(callSession.getCallId())) { + notificationId = notificationCache.get(callSession.getCallId()); + nm.notify(notificationId, notification); + } + } + } + + private void sendHangupNotification( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions) { + try { + String content = + context.getResources().getString(R.string.rc_voip_call_terminalted_notify); + String title = message.getPushTitle(); + int notificationId = IncomingCallExtraHandleUtil.VOIP_NOTIFICATION_ID; + Notification notification = + RongNotificationInterface.createNotification( + context, + title, + createPendingIntent( + context, + message, + callSession, + checkPermissions, + IncomingCallExtraHandleUtil.VOIP_REQUEST_CODE, + false), + content, + RongNotificationInterface.SoundType.VOIP, + message.isShowDetail()); + if (notification == null) { + return; + } + NotificationManager nm = + (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + notification.flags |= Notification.FLAG_AUTO_CANCEL; + CallRingingUtil.getInstance().createNotificationChannel(context); + RLog.i( + TAG, + "sendNotification() real notify! notificationId: " + + notificationId + + " notification: " + + notification.toString()); + notification.defaults = Notification.DEFAULT_ALL; + notification.sound = null; + nm.notify(notificationId, notification); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static PendingIntent createPendingIntent( + Context context, + PushNotificationMessage message, + RongCallSession callSession, + boolean checkPermissions, + int requestCode, + boolean isMulti) { + Intent intent = new Intent(); + intent.setAction(ACTION_CALLINVITEMESSAGE_CLICKED); + intent.putExtra(PushConst.MESSAGE, message); + intent.putExtra("callsession", callSession); + intent.putExtra("checkPermissions", checkPermissions); + intent.putExtra(PushConst.IS_MULTI, isMulti); + intent.setPackage(context.getPackageName()); + // KNOTE: 2021/9/29 PendingIntent + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return PendingIntent.getBroadcast( + context, + requestCode, + intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else { + return PendingIntent.getBroadcast( + context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + } + + private static Intent createConversationListIntent(Context context) { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri uri = + Uri.parse("rong://" + context.getPackageName()) + .buildUpon() + .appendPath("conversationlist") + .build(); + intent.setData(uri); + intent.setPackage(context.getPackageName()); + return intent; + } + + public static void clearNotificationCache() { + notificationCache.clear(); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/ActivityStartCheckUtils.java b/callkit/src/main/java/io/rong/callkit/util/ActivityStartCheckUtils.java new file mode 100644 index 000000000..7871e355d --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/ActivityStartCheckUtils.java @@ -0,0 +1,156 @@ +package io.rong.callkit.util; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.text.TextUtils; +import io.rong.callkit.RongCallModule; +import io.rong.callkit.RongVoIPIntent; + +public class ActivityStartCheckUtils { + public interface ActivityStartResultCallback { + void onStartActivityResult(boolean isActivityStarted); + } + + private static final int TIME_DELAY = 3000; + private boolean mPostDelayIsRunning; + private String mClassName; + private Handler mHandler = new Handler(); + private Activity topActivity; + private Context mAppContext; + private ActivityStartResultCallback activityStartResultCallback; + private static final String[] CALL_ACTIONS = { + RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIVIDEO, + RongVoIPIntent.RONG_INTENT_ACTION_VOIP_MULTIAUDIO, + RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEVIDEO, + RongVoIPIntent.RONG_INTENT_ACTION_VOIP_SINGLEAUDIO + }; + + private static class SingletonHolder { + + static ActivityStartCheckUtils sInstance = new ActivityStartCheckUtils(); + } + + private ActivityStartCheckUtils() {} + + public static ActivityStartCheckUtils getInstance() { + return SingletonHolder.sInstance; + } + + public void registerActivityLifecycleCallbacks(Context context) { + + mAppContext = context.getApplicationContext(); + Application application = (Application) mAppContext; + + if (application == null) return; + + application.registerActivityLifecycleCallbacks( + new Application.ActivityLifecycleCallbacks() { + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} + + @Override + public void onActivityStarted(Activity activity) {} + + @Override + public void onActivityResumed(Activity activity) { + topActivity = activity; + handleIncomingCallNotify(topActivity); + } + + @Override + public void onActivityPaused(Activity activity) {} + + @Override + public void onActivityStopped(Activity activity) { + if (topActivity == activity) { + topActivity = null; + } + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} + + @Override + public void onActivityDestroyed(Activity activity) {} + }); + } + + public String getTopActivity() { + if (topActivity == null) { + return null; + } + + return topActivity.getClass().getSuperclass().getSimpleName(); + } + + public void startActivity( + Context context, + Intent intent, + String className, + ActivityStartResultCallback callback) { + if (context == null || intent == null || TextUtils.isEmpty(className)) { + return; + } + context.startActivity(intent); + mClassName = className; + if (mPostDelayIsRunning) { + mHandler.removeCallbacks(mRunnable); + } + mPostDelayIsRunning = true; + activityStartResultCallback = callback; + mHandler.postDelayed(mRunnable, TIME_DELAY); + } + + private boolean isActivityOnTop() { + boolean result = false; + String topActivityName = getTopActivity(); + if (!TextUtils.isEmpty(topActivityName)) { + if (topActivityName.contains(mClassName)) { + result = true; + } + } + return result; + } + + private Runnable mRunnable = + new Runnable() { + @Override + public void run() { + mPostDelayIsRunning = false; + boolean isOnTop = isActivityOnTop(); + if (activityStartResultCallback != null) { + activityStartResultCallback.onStartActivityResult(isOnTop); + } + } + }; + + /** + * Android 10 以上禁止后台启动 Activity callKit 适配方案是后台来电时弹通知栏通知,但是如果用户不点击通知栏, + * 通过桌面图标打开应用,需要增加一种补偿机制启动来电界面 + */ + private void handleIncomingCallNotify(Activity activity) { + if (activity != null && IncomingCallExtraHandleUtil.needNotify()) { + String action = activity.getIntent().getAction(); + if (!TextUtils.isEmpty(action)) { + for (String ac : CALL_ACTIONS) { + if (TextUtils.equals(ac, action)) { + IncomingCallExtraHandleUtil.clear(); // 解决鸿蒙3.0设备 mate 10 重复启动通话界面问题 + return; + } + } + } + + IncomingCallExtraHandleUtil.removeNotification(mAppContext); + activity.startActivity( + RongCallModule.createVoIPIntent( + mAppContext, + IncomingCallExtraHandleUtil.getCallSession(), + IncomingCallExtraHandleUtil.isCheckPermissions())); + IncomingCallExtraHandleUtil.clear(); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/BluetoothUtil.java b/callkit/src/main/java/io/rong/callkit/util/BluetoothUtil.java new file mode 100644 index 000000000..19443a134 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/BluetoothUtil.java @@ -0,0 +1,305 @@ +package io.rong.callkit.util; + +import static android.content.Context.AUDIO_SERVICE; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothProfile; +import android.content.ComponentName; +import android.content.Context; +import android.media.AudioManager; +import android.text.TextUtils; +import io.rong.common.RLog; +import java.util.List; + +/** Created by degnxudong on 2018/8/24. */ +public class BluetoothUtil { + + private static final String TAG = "BluetoothUtil"; + + /** + * 是否连接了蓝牙耳机 + * + * @return + */ + @SuppressLint("WrongConstant") + public static boolean hasBluetoothA2dpConnected() { + boolean bool = false; + BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mAdapter != null && mAdapter.isEnabled()) { + int a2dp = mAdapter.getProfileConnectionState(BluetoothProfile.A2DP); + if (a2dp == BluetoothProfile.STATE_CONNECTED) { + bool = true; + } + } + return bool; + } + + /** + * 是否插入了有线耳机 + * + * @param context + * @return + */ + public static boolean isWiredHeadsetOn(Context context) { + AudioManager audioManager = (AudioManager) context.getSystemService(AUDIO_SERVICE); + return audioManager.isWiredHeadsetOn(); + } + + private static String getStyleContent(int styleMajor) { + String content = "未知...."; + switch (styleMajor) { + case BluetoothClass.Device.Major.AUDIO_VIDEO: // 音频设备 + content = "音配设备"; + break; + case BluetoothClass.Device.Major.COMPUTER: // 电脑 + content = "电脑"; + break; + case BluetoothClass.Device.Major.HEALTH: // 健康状况 + content = "健康状况"; + break; + case BluetoothClass.Device.Major.IMAGING: // 镜像,映像 + content = "镜像"; + break; + case BluetoothClass.Device.Major.MISC: // 麦克风 + content = "麦克风"; + break; + case BluetoothClass.Device.Major.NETWORKING: // 网络 + content = "网络"; + break; + case BluetoothClass.Device.Major.PERIPHERAL: // 外部设备 + content = "外部设备"; + break; + case BluetoothClass.Device.Major.PHONE: // 电话 + content = "电话"; + break; + case BluetoothClass.Device.Major.TOY: // 玩具 + content = "玩具"; + break; + case BluetoothClass.Device.Major.UNCATEGORIZED: // 未知的 + content = "未知的"; + break; + case BluetoothClass.Device.Major.WEARABLE: // 穿戴设备 + content = "穿戴设备"; + break; + } + return content; + } + + private static boolean getDeviceClass(int deviceClass) { + boolean bool = false; + switch (deviceClass) { + case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER: // 录像机 + // "录像机"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: + // "车载设备"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: + // "蓝牙耳机"; + bool = true; + break; + case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER: + // "扬声器"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE: + // "麦克风"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO: + // "打印机"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX: + // "BOX"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED: + // "未知的"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_VCR: + // "录像机"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CAMERA: + // "照相机录像机"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CONFERENCING: + // "conferencing"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER: + // "显示器和扬声器"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_GAMING_TOY: + // "游戏"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_MONITOR: + // "显示器"; + break; + case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: + // "可穿戴设备"; + bool = true; + break; + case BluetoothClass.Device.PHONE_CELLULAR: + // "手机"; + break; + case BluetoothClass.Device.PHONE_CORDLESS: + // "无线电设备"; + break; + case BluetoothClass.Device.PHONE_ISDN: + // "手机服务数据网"; + break; + case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY: + // "手机调节器"; + break; + case BluetoothClass.Device.PHONE_SMART: + // "手机卫星"; + break; + case BluetoothClass.Device.PHONE_UNCATEGORIZED: + // "未知手机"; + break; + case BluetoothClass.Device.WEARABLE_GLASSES: + // "可穿戴眼睛"; + break; + case BluetoothClass.Device.WEARABLE_HELMET: + // "可穿戴头盔"; + break; + case BluetoothClass.Device.WEARABLE_JACKET: + // "可穿戴上衣"; + break; + case BluetoothClass.Device.WEARABLE_PAGER: + // "客串点寻呼机"; + break; + case BluetoothClass.Device.WEARABLE_UNCATEGORIZED: + // "未知的可穿戴设备"; + break; + case BluetoothClass.Device.WEARABLE_WRIST_WATCH: + // "手腕监听设备"; + break; + case BluetoothClass.Device.TOY_CONTROLLER: + // "可穿戴设备"; + break; + case BluetoothClass.Device.TOY_DOLL_ACTION_FIGURE: + // "玩具doll_action_figure"; + break; + case BluetoothClass.Device.TOY_GAME: + // "游戏"; + break; + case BluetoothClass.Device.TOY_ROBOT: + // "玩具遥控器"; + break; + case BluetoothClass.Device.TOY_UNCATEGORIZED: + // "玩具未知设备"; + break; + case BluetoothClass.Device.TOY_VEHICLE: + // "vehicle"; + break; + case BluetoothClass.Device.HEALTH_BLOOD_PRESSURE: + // "健康状态-血压"; + break; + case BluetoothClass.Device.HEALTH_DATA_DISPLAY: + // "健康状态数据"; + break; + case BluetoothClass.Device.HEALTH_GLUCOSE: + // "健康状态葡萄糖"; + break; + case BluetoothClass.Device.HEALTH_PULSE_OXIMETER: + // "健康状态脉搏血氧计"; + break; + case BluetoothClass.Device.HEALTH_PULSE_RATE: + // "健康状态脉搏速率"; + break; + case BluetoothClass.Device.HEALTH_THERMOMETER: + // "健康状态体温计"; + break; + case BluetoothClass.Device.HEALTH_WEIGHING: + // "健康状态体重"; + break; + case BluetoothClass.Device.HEALTH_UNCATEGORIZED: + // "未知健康状态设备"; + break; + case BluetoothClass.Device.COMPUTER_DESKTOP: + // "电脑桌面"; + break; + case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA: + // "手提电脑或Pad"; + break; + case BluetoothClass.Device.COMPUTER_LAPTOP: + // "便携式电脑"; + break; + case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA: + // "微型电脑"; + break; + case BluetoothClass.Device.COMPUTER_SERVER: + // "电脑服务"; + break; + case BluetoothClass.Device.COMPUTER_UNCATEGORIZED: + // "未知的电脑设备"; + break; + case BluetoothClass.Device.COMPUTER_WEARABLE: + /// "可穿戴的电脑"; + break; + } + return bool; + } + + public static boolean isForground(Activity activity) { + return isForground(activity, activity.getClass().getName()); + } + + private static boolean isForground(Context context, String className) { + if (context == null || TextUtils.isEmpty(className)) { + return false; + } + ActivityManager activityManager = + (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); + List list = activityManager.getRunningTasks(1); + if (null != list && list.size() > 0) { + ComponentName componentName = list.get(0).topActivity; + if (className.equals(componentName.getClassName())) { + return true; + } + } + return false; + } + + /** + * 是否支持蓝牙 + * + * @return + */ + public static boolean isSupportBluetooth() { + boolean bool = false; + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (null != bluetoothAdapter) { + bool = true; + } + RLog.i(TAG, "isSupportBluetooth = " + bool); + return bool; + } + + public static void startBlueToothSco(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if (am != null) { + if (am.getMode() != AudioManager.MODE_IN_COMMUNICATION) { + am.setMode(AudioManager.MODE_IN_COMMUNICATION); + } + if (!am.isBluetoothScoOn()) { + am.startBluetoothSco(); + am.setBluetoothScoOn(false); + } + } + } + + public static void stopBlueToothSco(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if (am != null) { + // if (am.getMode() != AudioManager.MODE_IN_COMMUNICATION) { + // am.setMode(AudioManager.MODE_IN_COMMUNICATION); + // } + if (am.isBluetoothScoOn()) { + am.stopBluetoothSco(); + am.setBluetoothScoOn(false); + } + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/BlurBitmapUtil.java b/callkit/src/main/java/io/rong/callkit/util/BlurBitmapUtil.java new file mode 100644 index 000000000..5d572a745 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/BlurBitmapUtil.java @@ -0,0 +1,59 @@ +package io.rong.callkit.util; + +import android.annotation.TargetApi; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.Build; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.ScriptIntrinsicBlur; + +/** Created by dengxudong on 2018/5/18. */ +public class BlurBitmapUtil { + + private static class SingletonHolder { + + static BlurBitmapUtil sInstance = new BlurBitmapUtil(); + } + + private BlurBitmapUtil() {} + + public static BlurBitmapUtil instance() { + return SingletonHolder.sInstance; + } + /** + * @param context 上下文对象 + * @param image 需要模糊的图片 + * @param outWidth 输入出的宽度 + * @param outHeight 输出的高度 + * @return 模糊处理后的Bitmap + */ + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) + public Bitmap blurBitmap( + Context context, Bitmap image, float blurRadius, int outWidth, int outHeight) { + // 将缩小后的图片做为预渲染的图片 + Bitmap inputBitmap = Bitmap.createScaledBitmap(image, outWidth, outHeight, false); + // 创建一张渲染后的输出图片 + Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); + // 创建RenderScript内核对象 + RenderScript rs = RenderScript.create(context); + // 创建一个模糊效果的RenderScript的工具对象 + ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); + // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间 + // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去 + Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); + Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); + // 设置渲染的模糊程度, 25f是最大模糊度 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + blurScript.setRadius(blurRadius); + } + // 设置blurScript对象的输入内存 + blurScript.setInput(tmpIn); + // 将输出数据保存到输出内存中 + blurScript.forEach(tmpOut); + // 将数据填充到Allocation中 + tmpOut.copyTo(outputBitmap); + return outputBitmap; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarListener.java b/callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarListener.java new file mode 100644 index 000000000..8eab8e8c0 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarListener.java @@ -0,0 +1,16 @@ +package io.rong.callkit.util; + +public interface CallKitSearchBarListener { + /** + * 开始搜索 EditText 中输入内容后,会触发此回调 + * + * @param keyword 搜索关键字 + */ + void onSearchStart(String keyword); + + /** 软键盘中"搜索"被点击后,触发此回调 此回调被触发后,仅收起软键盘 */ + void onSoftSearchKeyClick(); + + /** 搜索控件中,点击"清除"后,触发此回调 */ + void onClearButtonClick(); +} diff --git a/callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarView.java b/callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarView.java new file mode 100644 index 000000000..d15420617 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/CallKitSearchBarView.java @@ -0,0 +1,153 @@ +package io.rong.callkit.util; + +import android.content.Context; +import android.os.Handler; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import io.rong.callkit.R; + +public class CallKitSearchBarView extends RelativeLayout { + + private EditText editSearch; + private View clearBtn; + private ImageView searchIV; + private CallKitSearchBarListener listener; + private Handler handler; + private boolean searchContentCleared; + + public CallKitSearchBarView(final Context context, AttributeSet attrs) { + super(context, attrs); + inflate(context, R.layout.callkit_view_search_bar_layout, this); + searchIV = findViewById(R.id.iv_icon); + editSearch = findViewById(R.id.et_search); + if (CallKitUtils.findConfigurationLanguage(context, "ar")) { + editSearch.setTextDirection(View.TEXT_DIRECTION_RTL); + } + handler = new Handler(); + editSearch.addTextChangedListener( + new TextWatcher() { + Runnable searchRunnable = null; + + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (!TextUtils.isEmpty(s.toString())) { + searchIV.setImageDrawable( + getResources() + .getDrawable(R.drawable.callkit_ic_search_focused_x)); + clearBtn.setVisibility(VISIBLE); + } else { + searchIV.setImageDrawable( + getResources().getDrawable(R.drawable.callkit_ic_search_x)); + clearBtn.setVisibility(GONE); + } + } + + @Override + public void afterTextChanged(Editable s) { + if (listener == null) { + return; + } + if (searchRunnable != null) { + handler.removeCallbacks(searchRunnable); + } + final String keywords = editSearch.getText().toString().trim(); + if (!TextUtils.isEmpty(keywords)) { + searchContentCleared = false; + searchRunnable = + new Runnable() { + @Override + public void run() { + listener.onSearchStart(keywords); + } + }; + handler.postDelayed(searchRunnable, 500); + } else { + if (!searchContentCleared) { + listener.onClearButtonClick(); + } + } + } + }); + editSearch.setOnEditorActionListener( + new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + listener.onSoftSearchKeyClick(); + } + return false; + } + }); + clearBtn = findViewById(R.id.iv_clear); + clearBtn.setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + editSearch.setText(""); + searchIV.setImageDrawable( + getResources().getDrawable(R.drawable.callkit_ic_search_x)); + clearBtn.setVisibility(GONE); + listener.onClearButtonClick(); + } + }); + + setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + InputMethodManager imm = + (InputMethodManager) + context.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(editSearch, InputMethodManager.HIDE_NOT_ALWAYS); + listener.onSoftSearchKeyClick(); + } + }); + } + + boolean isSearchTextEmpty() { + return editSearch.getText().toString().equals(""); + } + + public void setSearchBarListener(CallKitSearchBarListener listener) { + this.listener = listener; + } + + public void clearSearchContent() { + searchContentCleared = true; + editSearch.setText(""); + } + + public void setSearchHint(String text) { + editSearch.setHint(text); + } + + void setSearchText(String content) { + if (TextUtils.isEmpty(content)) { + clearBtn.setVisibility(GONE); + return; + } + editSearch.setText(content); + editSearch.setSelection(content.length()); + searchIV.setImageDrawable( + getResources().getDrawable(R.drawable.callkit_ic_search_focused_x)); + clearBtn.setVisibility(VISIBLE); + } + + public EditText getEditText() { + return editSearch; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/CallKitUtils.java b/callkit/src/main/java/io/rong/callkit/util/CallKitUtils.java new file mode 100644 index 000000000..1a38ed40e --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/CallKitUtils.java @@ -0,0 +1,270 @@ +package io.rong.callkit.util; + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.os.IBinder; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.View; +import android.view.Window; +import android.view.inputmethod.InputMethodManager; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.core.app.AppOpsManagerCompat; +import androidx.core.content.ContextCompat; +import io.rong.callkit.R; +import io.rong.calllib.RongCallCommon; +import io.rong.common.RLog; +import io.rong.imlib.model.Message; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** Created by dengxudong on 2018/5/17. */ +public class CallKitUtils { + + /** 拨打true or 接听false */ + public static boolean isDial = true; + + public static boolean shouldShowFloat; + /** 是否已经建立通话连接 默认没有,为了修改接听之后将情景模式切换成震动 在通话界面一直震动的问题 */ + public static boolean callConnected = false; + /** true:响铃中,false:响铃已结束 */ + // public static boolean RINGSTATE=false; + /** 当前 免提 是否打开的状态 true:打开中 */ + public static boolean speakerphoneState = false; + + public static StringBuffer stringBuffer = null; + + private static Map mapLastClickTime = new HashMap<>(); + + public static Drawable BackgroundDrawable(int drawable, Context context) { + return ContextCompat.getDrawable(context, drawable); + } + + public static int dp2px(float dpVal, Context context) { + return (int) + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + dpVal, + context.getResources().getDisplayMetrics()); + } + + /** 关闭软键盘 */ + public static void closeKeyBoard(Activity activity, View view) { + IBinder token; + if (view == null || view.getWindowToken() == null) { + if (null == activity) { + return; + } + Window window = activity.getWindow(); + if (window == null) { + return; + } + View v = window.peekDecorView(); + if (v == null) { + return; + } + token = v.getWindowToken(); + } else { + token = view.getWindowToken(); + } + InputMethodManager imm = + (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(token, 0); + } + + /** + * 提供(相对)精确的除法运算。 + * + * @param vl1 被除数 + * @param vl2 除数 + * @return 商 + */ + public static double div(double vl1, double vl2) { + + BigDecimal b1 = BigDecimal.valueOf(vl1); + BigDecimal b2 = BigDecimal.valueOf(vl2); + // 4 表示表示需要精确到小数点以后几位。当发生除不尽的情况时,参数指定精度,以后的数字四舍五入。 + return b1.divide(b2, 4, BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** 四舍五入把double转化int整型 */ + public static int getInt(double number) { + BigDecimal bd = BigDecimal.valueOf(number).setScale(0, BigDecimal.ROUND_HALF_UP); + return Integer.parseInt(bd.toString()); + } + + public static void textViewShadowLayer(TextView text, Context context) { + if (null == text) { + return; + } + text.setShadowLayer( + 16F, + 0F, + 2F, + context.getApplicationContext() + .getResources() + .getColor(R.color.callkit_shadowcolor)); + } + + public static boolean checkPermissions(Context context, @NonNull String[] permissions) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return true; + } + + if (permissions == null || permissions.length == 0) { + return true; + } + for (String permission : permissions) { + if (!hasPermission(context, permission)) { + return false; + } + } + return true; + } + + private static boolean hasPermission(Context context, String permission) { + String opStr = AppOpsManagerCompat.permissionToOp(permission); + if (opStr == null) { + return true; + } + boolean bool = + context.checkCallingOrSelfPermission(permission) + == PackageManager.PERMISSION_GRANTED; + return bool; + } + + public static String[] getCallpermissions() { + String[] permissions = + new String[] { + Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.INTERNET, + Manifest.permission.MODIFY_AUDIO_SETTINGS, + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, + Manifest.permission.READ_PHONE_STATE, + }; + return permissions; + } + + /** 获取字符串指定拼接内容 */ + public static String getStitchedContent(String val1, String val2) { + if (TextUtils.isEmpty(val1)) { + val1 = ""; + } + if (TextUtils.isEmpty(val2)) { + val2 = ""; + } + if (stringBuffer == null) { + stringBuffer = new StringBuffer(); + } else { + stringBuffer.setLength(0); + } + stringBuffer.append(val1); + stringBuffer.append(val2); + return stringBuffer.toString(); + } + + /** 是否是debug状态 */ + public static boolean isDebug(Context context) { + try { + ApplicationInfo info = context.getApplicationInfo(); + return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } catch (Exception e) { + return false; + } + } + + public static boolean isNetworkAvailable(Context context) { + ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + if (networkInfo == null || !networkInfo.isConnected() || !networkInfo.isAvailable()) { + return false; + } + return true; + } + + /** double click */ + public static boolean isFastDoubleClick() { + return isFastDoubleClick("Default"); + } + + public static boolean isFastDoubleClick(String eventType) { + Long lastClickTime = mapLastClickTime.get(eventType); + if (lastClickTime == null) { + lastClickTime = 0l; + } + long curTime = System.currentTimeMillis(); + long timeD = curTime - lastClickTime; + if (timeD > 0 && timeD < 800) { + return true; + } + mapLastClickTime.put(eventType, curTime); + return false; + } + + /** 昵称长度超过5,后面使用...显示 */ + public static String nickNameRestrict(String userName) { + if (!TextUtils.isEmpty(userName) && userName.length() > 5) { + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append(userName.substring(0, 5).trim()); + stringBuffer.append("..."); + userName = stringBuffer.toString(); + } + return userName; + } + + public static Message.ReceivedStatus getReceivedStatus( + RongCallCommon.CallDisconnectedReason reason) { + // 己方超时未接听或是对方取消通话时,应插入未读消息 + if (reason == RongCallCommon.CallDisconnectedReason.REMOTE_CANCEL + || reason == RongCallCommon.CallDisconnectedReason.NO_RESPONSE) { + return new Message.ReceivedStatus(0); + } + // 默认是已读状态 + return new Message.ReceivedStatus(1); + } + + /** @param language zh en ar */ + public static boolean findConfigurationLanguage(Context context, String language) { + if (context == null || TextUtils.isEmpty(language)) { + RLog.w("bugtags", "findConfigurationLanguage->Resources is empty"); + return false; + } + Resources resources = context.getResources(); + if (resources == null) { + RLog.w("bugtags", "findConfigurationLanguage->Resources is empty"); + return false; + } + Configuration configuration = resources.getConfiguration(); + if (configuration == null || configuration.locale == null) { + RLog.w("bugtags", "findConfigurationLanguage->configuration is empty"); + return false; + } + + Locale locale = configuration.locale; + String languageApp = locale.getLanguage(); + RLog.d( + "bugtags", + "findConfigurationLanguage->languageApp : " + + languageApp + + " ,language : " + + language); + return TextUtils.equals(languageApp, language); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/CallRingingUtil.java b/callkit/src/main/java/io/rong/callkit/util/CallRingingUtil.java new file mode 100644 index 000000000..9456ff613 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/CallRingingUtil.java @@ -0,0 +1,427 @@ +package io.rong.callkit.util; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.AssetFileDescriptor; +import android.media.AudioAttributes; +import android.media.AudioAttributes.Builder; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.os.Vibrator; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; +import androidx.annotation.DrawableRes; +import androidx.annotation.RequiresApi; +import io.rong.callkit.R; +import io.rong.callkit.RongIncomingCallService; +import io.rong.common.RLog; +import io.rong.imkit.notification.NotificationUtil; +import io.rong.push.notification.RongNotificationHelper; +import java.io.IOException; + +/** @author gusd @Date 2021/09/14 */ +public class CallRingingUtil { + private static final String TAG = "CallRingingUtil"; + private volatile boolean isRinging = false; + private volatile RingingMode mCurrentRingingMode = null; + + private MediaPlayer mMediaPlayer; + private Vibrator mVibrator; + private Context applicationContext; + private volatile boolean stopServiceAndRingingTag = false; + private volatile boolean isFirstReceivedBroadcast = true; + + private static final String DEFAULT_CHANNEL_NAME = "VOIP"; + private static final String DEFAULT_CHANNEL_ID = + RongNotificationHelper.getDefaultVoipChannelId(); + public static final int DEFAULT_ANSWER_ICON = R.drawable.rc_voip_notification_answer; + public static final int DEFAULT_HANGUP_ICON = R.drawable.rc_voip_notification_hangup; + + @DrawableRes private int answerIcon = DEFAULT_ANSWER_ICON; + @DrawableRes private int hangupIcon = DEFAULT_HANGUP_ICON; + + private CallRingingUtil() {} + + private static class InstanceHolder { + static final CallRingingUtil instance = new CallRingingUtil(); + } + + public static CallRingingUtil getInstance() { + return InstanceHolder.instance; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void startRingingService(Context context, Bundle bundle) { + if (!isRingingServiceRunning(context)) { + Intent intent = new Intent(); + intent.putExtras(bundle); + intent.setPackage(context.getPackageName()); + // KNOTE: 2021/9/29 前台服务启动限制 + try { + RongIncomingCallService.getInstance().startRing(context, intent); + } catch (Exception e) { + e.printStackTrace(); + RLog.e(TAG, e.getMessage()); + } + } + } + + public void stopService(Context context) { + RLog.d(TAG, "stopService: "); + if (isRingingServiceRunning(context)) { + RongIncomingCallService.getInstance().stopRinging(context); + } + } + + public void stopServiceButContinueRinging(Context context) { + RLog.d(TAG, "stopServiceButContinueRinging: "); + if (!isRingingServiceRunning(context)) { + stopServiceAndRingingTag = false; + return; + } + stopServiceAndRingingTag = true; + stopService(context); + } + + public boolean isRingingServiceRunning(Context context) { + return RongIncomingCallService.getInstance().isRinging(); + } + + public void startRinging(Context context, RingingMode mode) { + RLog.d(TAG, "startRinging: "); + if (isRinging) { + return; + } + + if (context == null) { + return; + } + applicationContext = context.getApplicationContext(); + + // 注册 BroadcastReceiver 监听情景模式的切换 + IntentFilter filter = new IntentFilter(); + filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); + isFirstReceivedBroadcast = true; + applicationContext.registerReceiver( + mRingModeReceiver, + filter, + context.getApplicationInfo().packageName + ".permission.RONG_ACCESS_RECEIVER", + null); + + if (mode == RingingMode.Incoming || mode == RingingMode.Incoming_Custom) { + int ringerMode = NotificationUtil.getInstance().getRingerMode(context); + if (ringerMode != AudioManager.RINGER_MODE_SILENT) { + if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { + startVibrator(context); + } else { + if (isVibrateWhenRinging(context)) { + startVibrator(context); + } + callRinging(context, mode); + } + } + } else { + callRinging(context, mode); + } + mCurrentRingingMode = mode; + isRinging = true; + } + + protected void startVibrator(Context context) { + Log.d(TAG, "startVibrator: "); + if (mVibrator == null) { + mVibrator = + (Vibrator) + context.getApplicationContext() + .getSystemService(Context.VIBRATOR_SERVICE); + } else { + mVibrator.cancel(); + } + + long[] pattern = {500, 1000}; + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + AudioAttributes build = + new Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION) + .build(); + mVibrator.vibrate(pattern, 0, build); + } else { + mVibrator.vibrate(pattern, 0); + } + } + + /** 判断系统是否设置了 响铃时振动 */ + private boolean isVibrateWhenRinging(Context context) { + ContentResolver resolver = context.getApplicationContext().getContentResolver(); + if (Build.MANUFACTURER.equals("Xiaomi")) { + return Settings.System.getInt(resolver, "vibrate_in_normal", 0) == 1; + } else if (Build.MANUFACTURER.equals("smartisan")) { + return Settings.Global.getInt(resolver, "telephony_vibration_enabled", 0) == 1; + } else { + return Settings.System.getInt(resolver, "vibrate_when_ringing", 0) == 1; + } + } + + private void callRinging(Context context, RingingMode mode) { + initMp(); + try { + if (mode == RingingMode.Incoming) { + Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); + mMediaPlayer.setDataSource(context.getApplicationContext(), uri); + } else if (mode == RingingMode.Incoming_Custom || mode == RingingMode.Outgoing) { + int rawResId = + mode == RingingMode.Outgoing + ? R.raw.voip_outgoing_ring + : R.raw.voip_incoming_ring; + AssetFileDescriptor assetFileDescriptor = + context.getResources().openRawResourceFd(rawResId); + mMediaPlayer.setDataSource( + assetFileDescriptor.getFileDescriptor(), + assetFileDescriptor.getStartOffset(), + assetFileDescriptor.getLength()); + assetFileDescriptor.close(); + } + + // 设置 MediaPlayer 播放的声音用途 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + int usage = AudioAttributes.USAGE_VOICE_COMMUNICATION; + if (TextUtils.equals(Build.BRAND, "Xiaomi")) { + usage = AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING; + } + AudioAttributes attributes = new AudioAttributes.Builder().setUsage(usage).build(); + mMediaPlayer.setAudioAttributes(attributes); + } else { + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); + } + mMediaPlayer.prepareAsync(); + final AudioManager am = + (AudioManager) + context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE); + if (am != null) { + am.setSpeakerphoneOn( + mode == RingingMode.Incoming || mode == RingingMode.Incoming_Custom); + // 设置此值可在拨打时控制响铃音量 + am.setMode(AudioManager.MODE_IN_COMMUNICATION); + // 设置拨打时响铃音量默认值 + am.setStreamVolume( + AudioManager.STREAM_VOICE_CALL, 5, AudioManager.STREAM_VOICE_CALL); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e1) { + RLog.i(TAG, "---onOutgoingCallRinging Error---" + e1.getMessage()); + } + } + + private void initMp() { + if (mMediaPlayer == null) { + mMediaPlayer = new MediaPlayer(); + mMediaPlayer.setOnPreparedListener( + new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + try { + if (mp != null) { + mp.setLooping(true); + mp.start(); + } + } catch (IllegalStateException e) { + e.printStackTrace(); + RLog.i(TAG, "setOnPreparedListener Error!"); + } + } + }); + } + } + + public void stopRinging() { + try { + RLog.d(TAG, "stopRinging: "); + if (stopServiceAndRingingTag) { + stopServiceAndRingingTag = false; + return; + } + if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { + mMediaPlayer.stop(); + } + if (mMediaPlayer != null) { + mMediaPlayer.reset(); + } + if (mVibrator != null) { + mVibrator.cancel(); + } + if (applicationContext != null) { + try { + applicationContext.unregisterReceiver(mRingModeReceiver); + } catch (Exception e) { + } + final AudioManager am = + (AudioManager) applicationContext.getSystemService(Context.AUDIO_SERVICE); + if (am != null) { + am.setMode(AudioManager.MODE_IN_COMMUNICATION); + } + } + } catch (Exception e) { + e.printStackTrace(); + RLog.i(TAG, "mMediaPlayer stopRing error=" + e.getMessage()); + } finally { + isRinging = false; + mCurrentRingingMode = null; + } + } + + protected final BroadcastReceiver mRingModeReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + RLog.d( + TAG, + "onReceive : " + "context = " + context + "," + "intent = " + intent); + // 此类广播为 sticky 类型的,首次注册广播便会收到,因此第一次收到的广播不作处理 + if (isFirstReceivedBroadcast) { + isFirstReceivedBroadcast = false; + return; + } + if (!isRinging) { + return; + } + // 根据 isIncoming 判断只有在接听界面时做铃声和振动的切换,拨打界面不作处理 + if ((mCurrentRingingMode == RingingMode.Incoming + || mCurrentRingingMode == RingingMode.Incoming_Custom) + && AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction()) + && !CallKitUtils.callConnected) { + AudioManager am = + (AudioManager) + context.getApplicationContext() + .getSystemService(Context.AUDIO_SERVICE); + final int ringMode = am.getRingerMode(); + RLog.i(TAG, "Ring mode Receiver mode=" + ringMode); + switch (ringMode) { + case AudioManager.RINGER_MODE_NORMAL: + stopRinging(); + callRinging(context.getApplicationContext(), RingingMode.Incoming); + break; + case AudioManager.RINGER_MODE_SILENT: + stopRinging(); + break; + case AudioManager.RINGER_MODE_VIBRATE: + stopRinging(); + startVibrator(context); + break; + default: + } + } + } + }; + + /** + * 创建通知通道 + * + * @param context + */ + public void createNotificationChannel(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = + new NotificationChannel( + getNotificationChannelId(), + getNotificationChannelName(context), + NotificationManager.IMPORTANCE_HIGH); + channel.setSound(null, null); + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + } + + public String getNotificationChannelId() { + return DEFAULT_CHANNEL_ID; + } + + public String getNotificationChannelName(Context context) { + int id = + context.getResources() + .getIdentifier( + RongNotificationHelper.getDefaultVoipChannelName(), + "string", + context.getPackageName()); + String channelName = id == 0 ? null : context.getResources().getString(id); + return TextUtils.isEmpty(channelName) ? DEFAULT_CHANNEL_NAME : channelName; + } + + public void setNotificationHangupIcon(@DrawableRes int hangupIcon) { + this.hangupIcon = hangupIcon; + } + + @DrawableRes + public int getNotificationHangupIcon() { + return this.hangupIcon; + } + + public void setNotificationAnswerIcon(@DrawableRes int answerIcon) { + this.answerIcon = answerIcon; + } + + @DrawableRes + public int getNotificationAnswerIcon() { + return this.answerIcon; + } + + /** + * 创建通道并检查是否有悬浮通知权限 + * + * @param context + */ + public boolean createChannelAndCheckFullScreenPermission(Context context) { + createNotificationChannel(context); + return checkFullScreenPermission(context, getNotificationChannelId()); + } + + /** + * 检查是否有悬浮通知权限 + * + * @param context + * @param channelId + * @return + */ + public boolean checkFullScreenPermission(Context context, String channelId) { + NotificationManager mNotificationManager = + (NotificationManager) + context.getApplicationContext() + .getSystemService(Context.NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android 8.0及以上 + NotificationChannel channel = + mNotificationManager.getNotificationChannel(channelId); // CHANNEL_ID是自己定义的渠道ID + if (channel.getImportance() == NotificationManager.IMPORTANCE_DEFAULT) { // 未开启 + return false; + } + return true; + } + return false; + } + + /** + * 跳转到通知设置界面 + * + * @param context + */ + public void gotoChannelSettingPage(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); + intent.setPackage(context.getPackageName()); + intent.putExtra(Settings.EXTRA_CHANNEL_ID, getNotificationChannelId()); + context.startActivity(intent); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/CallSelectMemberSerializable.java b/callkit/src/main/java/io/rong/callkit/util/CallSelectMemberSerializable.java new file mode 100644 index 000000000..fd0b85df1 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/CallSelectMemberSerializable.java @@ -0,0 +1,20 @@ +package io.rong.callkit.util; + +import java.io.Serializable; +import java.util.HashMap; + +public class CallSelectMemberSerializable implements Serializable { + private HashMap hashMap = new HashMap<>(); + + public CallSelectMemberSerializable(HashMap hashMap) { + this.hashMap = hashMap; + } + + public HashMap getHashMap() { + return hashMap; + } + + public void setHashMap(HashMap hashMap) { + this.hashMap = hashMap; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/CallVerticalScrollView.java b/callkit/src/main/java/io/rong/callkit/util/CallVerticalScrollView.java new file mode 100644 index 000000000..2605e5308 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/CallVerticalScrollView.java @@ -0,0 +1,259 @@ +package io.rong.callkit.util; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.CircleCrop; +import com.bumptech.glide.request.RequestOptions; +import io.rong.callkit.R; +import io.rong.callkit.RongCallKit; +import io.rong.imlib.model.UserInfo; +import java.util.ArrayList; +import java.util.List; + +/** 竖向滑动 多人语音——主叫方和通话中 */ +public class CallVerticalScrollView extends ScrollView implements ICallScrollView { + private Context context; + private boolean enableTitle; + private LinearLayout linearLayout; + private static int CHILDREN_PER_LINE = 4; + private static final int CHILDREN_SPACE = 18; + + private int portraitSize; + + public CallVerticalScrollView(Context context) { + super(context); + init(context); + } + + public CallVerticalScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + private void init(Context context) { + this.context = context; + linearLayout = new LinearLayout(context); + linearLayout.setLayoutParams( + new LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + linearLayout.setOrientation(LinearLayout.VERTICAL); + addView(linearLayout); + } + + public int dip2pix(int dipValue) { + float scale = getResources().getDisplayMetrics().density; + return (int) (dipValue * scale + 0.5f); + } + + @Override + public View getChildAtIndex(int index) { + return linearLayout.getChildAt(index); + } + + @Override + public int getChildrenSpace() { + return CHILDREN_PER_LINE; + } + + public int getScreenWidth() { + return getResources().getDisplayMetrics().widthPixels; + } + + public void setChildPortraitSize(int size) { + portraitSize = size; + } + + public void enableShowState(boolean enable) { + enableTitle = enable; + } + + public void addChild(String childId, UserInfo userInfo) { + addChild(childId, userInfo, null); + } + + public void addChild(String childId, UserInfo userInfo, String state) { + int containerCount = linearLayout.getChildCount(); + LinearLayout lastContainer = null; + int i; + for (i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + if (container.getChildCount() < CHILDREN_PER_LINE) { + lastContainer = container; + break; + } + } + if (lastContainer == null) { + lastContainer = new LinearLayout(context); + lastContainer.setLayoutParams( + new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + lastContainer.setGravity(Gravity.CENTER_HORIZONTAL); + lastContainer.setPadding(0, dip2pix(CHILDREN_SPACE), 0, 0); + linearLayout.addView(lastContainer); + } + + LinearLayout child = + (LinearLayout) + LayoutInflater.from(context) + .inflate(R.layout.rc_voip_user_info_mutlaudio, null); + child.setLayoutParams( + new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + child.setPadding(0, 0, dip2pix(CHILDREN_SPACE), 0); + child.setTag(childId); + if (portraitSize > 0) { + child.findViewById(R.id.rc_user_portrait_layout) + .setLayoutParams(new LinearLayout.LayoutParams(portraitSize, portraitSize)); + } + ImageView imageView = (ImageView) child.findViewById(R.id.rc_user_portrait); + TextView name = (TextView) child.findViewById(R.id.rc_user_name); + name.setVisibility(enableTitle ? VISIBLE : GONE); + TextView stateV = (TextView) child.findViewById(R.id.rc_voip_member_state); + stateV.setVisibility(enableTitle ? VISIBLE : GONE); + if (state != null) { + stateV.setText(state); + } else { + stateV.setVisibility(GONE); + } + + if (userInfo != null) { + RongCallKit.getKitImageEngine() + .loadPortrait( + this.getContext(), + userInfo.getPortraitUri(), + R.drawable.rc_default_portrait, + imageView); + name.setText(userInfo.getName() == null ? userInfo.getUserId() : userInfo.getName()); + } else { + name.setText(childId); + } + lastContainer.addView(child); + } + + @Override + public void setScrollViewOverScrollMode(int mode) { + this.setOverScrollMode(mode); + } + + @Override + public void removeAllChild() { + linearLayout.removeAllViews(); + } + + public void removeChild(String childId) { + int containerCount = linearLayout.getChildCount(); + + LinearLayout lastContainer = null; + List containerList = new ArrayList<>(); + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + containerList.add(container); + } + for (LinearLayout resultContainer : containerList) { + if (lastContainer == null) { + LinearLayout child = (LinearLayout) resultContainer.findViewWithTag(childId); + if (child != null) { + resultContainer.removeView(child); + if (resultContainer.getChildCount() == 0) { + linearLayout.removeView(resultContainer); + break; + } else { + lastContainer = resultContainer; + } + } + } else { + View view = resultContainer.getChildAt(0); + resultContainer.removeView(view); + lastContainer.addView(view); + if (resultContainer.getChildCount() == 0) { + linearLayout.removeView(resultContainer); + break; + } else { + lastContainer = resultContainer; + } + } + } + } + + public View findChildById(String childId) { + int containerCount = linearLayout.getChildCount(); + + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + return child; + } + } + return null; + } + + public void updateChildInfo(String childId, UserInfo userInfo) { + int containerCount = linearLayout.getChildCount(); + + LinearLayout lastContainer = null; + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + ImageView imageView = (ImageView) child.findViewById(R.id.rc_user_portrait); + Glide.with(this) + .load(userInfo.getPortraitUri()) + .placeholder(R.drawable.rc_default_portrait) + .apply(RequestOptions.bitmapTransform(new CircleCrop())) + .into(imageView); + if (enableTitle) { + TextView textView = (TextView) child.findViewById(R.id.rc_user_name); + textView.setLines(1); + textView.setEllipsize(TextUtils.TruncateAt.END); + textView.setText(userInfo.getName()); + } + } + } + } + + public void updateChildState(String childId, String state) { + int containerCount = linearLayout.getChildCount(); + + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + TextView textView = (TextView) child.findViewById(R.id.rc_voip_member_state); + textView.setText(state); + } + } + } + + /** + * @param childId + * @param visible + */ + public void updateChildState(String childId, boolean visible) { + int containerCount = linearLayout.getChildCount(); + + for (int i = 0; i < containerCount; i++) { + LinearLayout container = (LinearLayout) linearLayout.getChildAt(i); + LinearLayout child = (LinearLayout) container.findViewWithTag(childId); + if (child != null) { + TextView textView = (TextView) child.findViewById(R.id.rc_voip_member_state); + textView.setVisibility(visible ? VISIBLE : GONE); + // ImageView imageView = + // (ImageView) + // child.findViewById(R.id.callkit_mutilAudio_Floatinglayer); + // imageView.setVisibility(visible ? VISIBLE : GONE); + } + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/DefaultPushConfig.java b/callkit/src/main/java/io/rong/callkit/util/DefaultPushConfig.java new file mode 100644 index 000000000..3eb9947d8 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/DefaultPushConfig.java @@ -0,0 +1,157 @@ +package io.rong.callkit.util; + +import static android.content.Context.MODE_PRIVATE; + +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; +import io.rong.callkit.R; +import io.rong.imkit.RongIM; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imlib.model.AndroidConfig; +import io.rong.imlib.model.IOSConfig; +import io.rong.imlib.model.MessagePushConfig; +import io.rong.imlib.model.UserInfo; + +public class DefaultPushConfig { + + /** + * 获取邀请的 push config + * + * @param isPrivate 是否单人呼叫 + * @param groupName 群组呼叫的时候才需要填写: + */ + public static MessagePushConfig getInviteConfig( + Context context, boolean isAudio, boolean isPrivate, String groupName) { + UserInfo userInfo = + RongUserInfoManager.getInstance() + .getUserInfo(RongIM.getInstance().getCurrentUserId()); + String userName = userInfo == null ? "" : userInfo.getName(); + // 自定义音视频通话推送内容测试代码,融云SealTalk测试时配置写入SharedPreferences, + // 开发者根据实际需求定义发起通话和挂断时的push配置,在 startCall 前设置即可 + SharedPreferences sharedPreferences = + context.getSharedPreferences("push_config", MODE_PRIVATE); + String id = sharedPreferences.getString("id", ""); + String title = sharedPreferences.getString("title", ""); + String pushTile = TextUtils.isEmpty(title) ? (isPrivate ? userName : groupName) : title; + String content = sharedPreferences.getString("content", ""); + if (TextUtils.isEmpty(content)) { + content = + TextUtils.isEmpty(userName) + ? context.getResources() + .getString( + isAudio + ? R.string + .rc_voip_notificatio_audio_call_inviting_general + : R.string + .rc_voip_notificatio_video_call_inviting_general) + : userName + + " " + + context.getResources() + .getString( + isAudio + ? R.string + .rc_voip_notificatio_audio_call_inviting + : R.string + .rc_voip_notificatio_video_call_inviting); + } + String invitePushContent = content; + String data = sharedPreferences.getString("data", ""); + String hw = sharedPreferences.getString("hw", ""); + String mi = sharedPreferences.getString("mi", ""); + String oppo = sharedPreferences.getString("oppo", ""); + String threadId = sharedPreferences.getString("threadId", ""); + String apnsId = sharedPreferences.getString("apnsId", ""); + boolean vivo = sharedPreferences.getBoolean("vivo", false); + boolean forceDetail = sharedPreferences.getBoolean("forceDetail", false); + MessagePushConfig invitePushConfig = + getMessagePushConfig( + id, + pushTile, + invitePushContent, + data, + hw, + mi, + oppo, + threadId, + apnsId, + forceDetail); + + return invitePushConfig; + } + + /** + * 获取挂断的 push config + * + * @param isPrivate 是否单人呼叫 + * @param groupName 群组呼叫的时候才需要填写: + */ + public static MessagePushConfig getHangupConfig( + Context context, boolean isPrivate, String groupName) { + UserInfo userInfo = RongUserInfoManager.getInstance().getCurrentUserInfo(); + String userName = userInfo == null ? "" : userInfo.getName(); + + // 自定义音视频通话推送内容测试代码,融云SealTalk测试时配置写入SharedPreferences, + // 开发者根据实际需求定义发起通话和挂断时的push配置,在 startCall 前设置即可 + SharedPreferences sharedPreferences = + context.getSharedPreferences("push_config", MODE_PRIVATE); + String id = sharedPreferences.getString("id", ""); + String title = sharedPreferences.getString("title", ""); + String pushTile = TextUtils.isEmpty(title) ? (isPrivate ? userName : groupName) : title; + String content = sharedPreferences.getString("content", ""); + String hangupPushContent = + TextUtils.isEmpty(content) + ? context.getResources().getString(R.string.rc_voip_call_terminalted_notify) + : content; + String data = sharedPreferences.getString("data", ""); + String hw = sharedPreferences.getString("hw", ""); + String mi = sharedPreferences.getString("mi", ""); + String oppo = sharedPreferences.getString("oppo", ""); + String threadId = sharedPreferences.getString("threadId", ""); + String apnsId = sharedPreferences.getString("apnsId", ""); + boolean vivo = sharedPreferences.getBoolean("vivo", false); + boolean forceDetail = sharedPreferences.getBoolean("forceDetail", false); + MessagePushConfig hangupPushConfig = + getMessagePushConfig( + id, + pushTile, + hangupPushContent, + data, + hw, + mi, + oppo, + threadId, + apnsId, + forceDetail); + return hangupPushConfig; + } + + private static MessagePushConfig getMessagePushConfig( + String id, + String pushTile, + String invitePushContent, + String data, + String hw, + String mi, + String oppo, + String threadId, + String apnsId, + boolean forceDetail) { + return new MessagePushConfig.Builder() // + .setPushTitle(pushTile) // + .setPushContent(invitePushContent) // + .setPushData(data) // + .setForceShowDetailContent(forceDetail) // + .setAndroidConfig( + new AndroidConfig.Builder() // + .setNotificationId(id) // + .setChannelIdHW(hw) // + .setChannelIdMi(mi) // + .setChannelIdOPPO(oppo) // + .setCategoryHW("VOIP") + .setCategoryVivo("IM") + .build()) // + .setIOSConfig(new IOSConfig(threadId, apnsId)) + .build(); // + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/GlideBlurformation.java b/callkit/src/main/java/io/rong/callkit/util/GlideBlurformation.java new file mode 100644 index 000000000..6cbaae338 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/GlideBlurformation.java @@ -0,0 +1,26 @@ +package io.rong.callkit.util; + +import android.content.Context; +import android.graphics.Bitmap; +import androidx.annotation.NonNull; +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; +import java.security.MessageDigest; + +/** Created by dengxudong on 2018/5/18. */ +public class GlideBlurformation extends BitmapTransformation { + private Context context; + + public GlideBlurformation(Context context) { + this.context = context; + } + + @Override + protected Bitmap transform( + @NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { + return BlurBitmapUtil.instance().blurBitmap(context, toTransform, 20, outWidth, outHeight); + } + + @Override + public void updateDiskCacheKey(MessageDigest messageDigest) {} +} diff --git a/callkit/src/main/java/io/rong/callkit/util/GlideRoundTransform.java b/callkit/src/main/java/io/rong/callkit/util/GlideRoundTransform.java new file mode 100644 index 000000000..1ae647fd4 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/GlideRoundTransform.java @@ -0,0 +1,54 @@ +package io.rong.callkit.util; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; +import java.security.MessageDigest; + +/** Created by Ethan on 2018/6/1. */ +public class GlideRoundTransform extends BitmapTransformation { + + private static float radius = 8f; + + public GlideRoundTransform() { + this(8); + } + + public GlideRoundTransform(int dp) { + super(); + this.radius = Resources.getSystem().getDisplayMetrics().density * dp; + } + + @Override + protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { + return roundCrop(pool, toTransform); + } + + private static Bitmap roundCrop(BitmapPool pool, Bitmap source) { + if (source == null) return null; + + Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); + if (result == null) { + result = + Bitmap.createBitmap( + source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); + } + + Canvas canvas = new Canvas(result); + Paint paint = new Paint(); + paint.setShader( + new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); + paint.setAntiAlias(true); + RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight()); + canvas.drawRoundRect(rectF, radius, radius, paint); + return result; + } + + @Override + public void updateDiskCacheKey(MessageDigest messageDigest) {} +} diff --git a/callkit/src/main/java/io/rong/callkit/util/GlideUtils.java b/callkit/src/main/java/io/rong/callkit/util/GlideUtils.java new file mode 100644 index 000000000..2d0a424bc --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/GlideUtils.java @@ -0,0 +1,54 @@ +package io.rong.callkit.util; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; +import android.widget.ImageView; +import cn.rongcloud.rtc.utils.FinLog; +import com.bumptech.glide.Glide; +import com.bumptech.glide.Priority; +import com.bumptech.glide.request.RequestOptions; +import io.rong.callkit.R; + +/** Created by dengxudong on 2018/5/18. */ +public class GlideUtils { + + private static final String TAG = GlideUtils.class.getSimpleName(); + + public static void showBlurTransformation(Context context, ImageView imageView, Uri val) { + if (val == null) { + return; + } + try { + Glide.with(context) + .load(val) + .apply(RequestOptions.bitmapTransform(new GlideBlurformation(context))) + .apply(new RequestOptions().centerCrop()) + .into(imageView); + } catch (Exception e) { + e.printStackTrace(); + FinLog.e(TAG, "Glide Utils Error=" + e.getMessage()); + } catch (NoSuchMethodError noSuchMethodError) { + noSuchMethodError.printStackTrace(); + FinLog.e(TAG, "Glide NoSuchMethodError = " + noSuchMethodError.getMessage()); + } + } + + public static void showPortrait(Context context, ImageView imageView, Uri val) { + RequestOptions requestOptions = new RequestOptions(); + requestOptions + .transform(new GlideBlurformation(context)) + .priority(Priority.HIGH) + .placeholder(R.drawable.rc_default_portrait) + .apply(new RequestOptions().centerCrop()); + if (val == null) { + Log.d(TAG, "showPortrait: val is Null"); + Glide.with(context) + .load(R.drawable.rc_default_portrait) + .apply(requestOptions) + .into(imageView); + } else { + Glide.with(context).load(val).apply(requestOptions).into(imageView); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/HeadsetInfo.java b/callkit/src/main/java/io/rong/callkit/util/HeadsetInfo.java new file mode 100644 index 000000000..506da3ce0 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/HeadsetInfo.java @@ -0,0 +1,45 @@ +package io.rong.callkit.util; + +/** Created by Dengxudong on 2018/8/23. */ +public class HeadsetInfo { + private boolean isInsert; + private HeadsetType type; + + public HeadsetInfo(boolean isInsert, HeadsetType type) { + this.isInsert = isInsert; + this.type = type; + } + + public boolean isInsert() { + return isInsert; + } + + public void setInsert(boolean insert) { + isInsert = insert; + } + + public HeadsetType getType() { + return type; + } + + public void setType(HeadsetType type) { + this.type = type; + } + + public enum HeadsetType { + /** 有线耳机 */ + WiredHeadset(0), + /** 蓝牙耳机 */ + BluetoothA2dp(1); + + int value; + + HeadsetType(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/ICallScrollView.java b/callkit/src/main/java/io/rong/callkit/util/ICallScrollView.java new file mode 100644 index 000000000..1709100e2 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/ICallScrollView.java @@ -0,0 +1,35 @@ +package io.rong.callkit.util; + +import android.view.View; +import io.rong.imlib.model.UserInfo; + +/** Created by dengxudong on 2018/5/18. */ +public interface ICallScrollView { + void setScrollViewOverScrollMode(int mode); + + void removeAllChild(); + + void removeChild(String childId); + + View findChildById(String childId); + + void updateChildState(String childId, boolean visible); + + void updateChildState(String childId, String state); + + void setChildPortraitSize(int size); + + void enableShowState(boolean enable); + + void addChild(String childId, UserInfo userInfo); + + void addChild(String childId, UserInfo userInfo, String state); + + void updateChildInfo(String childId, UserInfo userInfo); + + int dip2pix(int dipValue); + + View getChildAtIndex(int index); + + int getChildrenSpace(); +} diff --git a/callkit/src/main/java/io/rong/callkit/util/IncomingCallExtraHandleUtil.java b/callkit/src/main/java/io/rong/callkit/util/IncomingCallExtraHandleUtil.java new file mode 100644 index 000000000..320703b9f --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/IncomingCallExtraHandleUtil.java @@ -0,0 +1,54 @@ +package io.rong.callkit.util; + +import android.app.NotificationManager; +import android.content.Context; +import io.rong.callkit.CallFloatBoxView; +import io.rong.callkit.VoIPBroadcastReceiver; +import io.rong.calllib.RongCallSession; +import io.rong.push.notification.RongNotificationInterface; + +/** 适配 Android 10 以上不允许后台启动 Activity 的工具类 */ +public class IncomingCallExtraHandleUtil { + public static int VOIP_NOTIFICATION_ID = 3000; // VoIP类型的通知消息。 + public static final int VOIP_REQUEST_CODE = 30001; + + private static RongCallSession cachedCallSession = null; + private static boolean checkPermissions = false; + + public static void removeNotification(Context context) { + RongNotificationInterface.removeNotification(context, VOIP_NOTIFICATION_ID); + removeAllPushServiceNotification(context); + VoIPBroadcastReceiver.clearNotificationCache(); + } + + public static void removeAllPushServiceNotification(Context context) { + NotificationManager nm = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + for (int i = VOIP_NOTIFICATION_ID; i >= 3000; i--) { + nm.cancel(i); + } + VOIP_NOTIFICATION_ID = 3000; + } + + public static RongCallSession getCallSession() { + return cachedCallSession; + } + + public static void cacheCallSession(RongCallSession callSession, boolean permissions) { + cachedCallSession = callSession; + checkPermissions = permissions; + } + + public static boolean isCheckPermissions() { + return checkPermissions; + } + + public static void clear() { + cachedCallSession = null; + checkPermissions = false; + } + + public static boolean needNotify() { + return cachedCallSession != null && !CallFloatBoxView.isCallFloatBoxShown(); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/RTCPhoneStateReceiver.java b/callkit/src/main/java/io/rong/callkit/util/RTCPhoneStateReceiver.java new file mode 100644 index 000000000..5e994a3df --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/RTCPhoneStateReceiver.java @@ -0,0 +1,76 @@ +package io.rong.callkit.util; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallSession; + +public class RTCPhoneStateReceiver extends BroadcastReceiver { + + private static final String TAG = "RTCPhoneStateReceiver"; + // 21以上会回调两次(状态值一样) + private static String twice = ""; + private TelephonyManager mTelephonyManager; + + public int getCallState(Context context) { + if (context == null) { + return -1; + } + + if (mTelephonyManager == null) { + mTelephonyManager = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + } + return mTelephonyManager.getCallState(); + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (!("android.intent.action.PHONE_STATE").equals(action)) { + Log.i(TAG, "action :" + action); + return; + } + + String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); + + if (TextUtils.isEmpty(state) && TextUtils.isEmpty(twice)) { + int callState = getCallState(context); + if (TelephonyManager.CALL_STATE_OFFHOOK == callState) { + state = TelephonyManager.EXTRA_STATE_OFFHOOK; + } else if (TelephonyManager.CALL_STATE_RINGING == callState) { + state = TelephonyManager.EXTRA_STATE_RINGING; + } else if (TelephonyManager.CALL_STATE_IDLE == callState) { + state = TelephonyManager.EXTRA_STATE_IDLE; + } + } + + Log.i(TAG, "state : " + state + " , twice : " + twice); + + if (!TextUtils.isEmpty(state) && !twice.equals(state)) { + twice = state; + + if (RongCallClient.getInstance() == null) { + Log.e(TAG, "RongCallClient is empty"); + return; + } + + RongCallSession callSession = RongCallClient.getInstance().getCallSession(); + if (callSession == null) { + Log.e(TAG, "callSession is empty"); + return; + } + + if (twice.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { + // ON_PHONE; + RongCallClient.getInstance().hangUpCall(); + } else if (twice.equals(TelephonyManager.EXTRA_STATE_IDLE)) { + // ON_PHONE_ENDED; + } + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/RingingMode.java b/callkit/src/main/java/io/rong/callkit/util/RingingMode.java new file mode 100644 index 000000000..933f92b63 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/RingingMode.java @@ -0,0 +1,13 @@ +package io.rong.callkit.util; + +public enum RingingMode { + Incoming(0), + Outgoing(1), + Incoming_Custom(2); + + private int val; + + RingingMode(int val) { + this.val = val; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/RongCallPermissionUtil.java b/callkit/src/main/java/io/rong/callkit/util/RongCallPermissionUtil.java new file mode 100644 index 000000000..52195c2a0 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/RongCallPermissionUtil.java @@ -0,0 +1,358 @@ +package io.rong.callkit.util; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import android.text.TextUtils; +import androidx.annotation.NonNull; +import androidx.core.app.AppOpsManagerCompat; +import io.rong.callkit.util.permission.PermissionShowDetail; +import io.rong.callkit.util.permission.PermissionType; +import io.rong.calllib.RongCallCommon; +import io.rong.common.RLog; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** @author gusd @Date 2021/09/17 */ +public class RongCallPermissionUtil { + private static final String TAG = "RongCallPermissionUtil"; + + public static void requestPermissions( + Activity activity, PermissionType[] permissionTypes, int requestCode) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return; + } + final List permissionsNotGranted = new ArrayList<>(); + for (PermissionType audioCallPermission : permissionTypes) { + if (!audioCallPermission.checkPermission(activity)) { + permissionsNotGranted.add(audioCallPermission.getPermissionName()); + } + } + if (!permissionsNotGranted.isEmpty()) { + activity.requestPermissions(permissionsNotGranted.toArray(new String[0]), requestCode); + } + } + + /////////////////////////////////////////////////////////////////////////// + // 音频通话权限相关 + /////////////////////////////////////////////////////////////////////////// + + /** + * 请求音频通话所需权限 + * + * @param activity + */ + public static void requestAudioCallNeedPermission(Activity activity, final int requestCode) { + requestPermissions(activity, getAudioCallPermissions(activity), requestCode); + } + + /** + * 获取音频通话所需权限 + * + * @return + */ + public static PermissionType[] getAudioCallPermissions(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + && context.getApplicationInfo() != null + && context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S) { + return new PermissionType[] { + PermissionType.AudioRecord, + PermissionType.BluetoothConnect, + PermissionType.BluetoothScan, + PermissionType.BluetoothAdvertise + }; + } else { + return new PermissionType[] {PermissionType.AudioRecord}; + } + } + + public static boolean checkAudioCallNeedPermission(Context context) { + for (PermissionType audioCallPermission : getAudioCallPermissions(context)) { + if (!audioCallPermission.checkPermission(context)) { + return false; + } + } + return true; + } + + public static boolean checkAndRequestAudioCallPermission( + Activity activity, final int requestCode) { + boolean granted = checkAudioCallNeedPermission(activity); + if (!granted) { + requestAudioCallNeedPermission(activity, requestCode); + } + return granted; + } + + /////////////////////////////////////////////////////////////////////////// + // 视频通话权限相关 + /////////////////////////////////////////////////////////////////////////// + public static boolean checkVideoCallNeedPermission(Context context) { + for (PermissionType audioCallPermission : getVideoCallPermissions(context)) { + if (!audioCallPermission.checkPermission(context)) { + return false; + } + } + return true; + } + + public static void requestVideoCallNeedPermission(Activity activity, final int requestCode) { + requestPermissions(activity, getVideoCallPermissions(activity), requestCode); + } + + public static boolean checkAndRequestVideoCallPermission( + Activity activity, final int requestCode) { + boolean granted = checkVideoCallNeedPermission(activity); + if (!granted) { + requestVideoCallNeedPermission(activity, requestCode); + } + return granted; + } + + /** + * 获取视频通话所需必要权限 + * + * @return + */ + public static PermissionType[] getVideoCallPermissions(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + && context.getApplicationInfo() != null + && context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S) { + return new PermissionType[] { + PermissionType.CameraPermission, + PermissionType.AudioRecord, + PermissionType.BluetoothConnect, + PermissionType.BluetoothScan, + PermissionType.BluetoothAdvertise, + }; + } else { + return new PermissionType[] { + PermissionType.CameraPermission, PermissionType.AudioRecord + }; + } + } + + public static boolean checkAndRequestPermissionByCallType( + Activity activity, RongCallCommon.CallMediaType type, final int requestCode) { + if (RongCallCommon.CallMediaType.VIDEO.equals(type)) { + return checkAndRequestVideoCallPermission(activity, requestCode); + } else if (RongCallCommon.CallMediaType.AUDIO.equals(type)) { + return checkAndRequestAudioCallPermission(activity, requestCode); + } + return false; + } + + public static boolean checkPermissionByType( + Context context, RongCallCommon.CallMediaType type) { + if (RongCallCommon.CallMediaType.VIDEO.equals(type)) { + return checkVideoCallNeedPermission(context); + } else if (RongCallCommon.CallMediaType.AUDIO.equals(type)) { + return checkAudioCallNeedPermission(context); + } + return false; + } + + /////////////////////////////////////////////////////////////////////////// + // 悬浮窗相关 + /////////////////////////////////////////////////////////////////////////// + + public static void requestFloatWindowNeedPermission( + final Context context, final DialogInterface.OnClickListener listener) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + ArrayList permissionList = new ArrayList<>(); + permissionList.add(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); + showPermissionAlert( + context, + context.getString(io.rong.imkit.R.string.rc_permission_grant_needed) + + getNotGrantedPermissionMsg(context, permissionList), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (listener != null) { + listener.onClick(dialog, which); + } + if (DialogInterface.BUTTON_POSITIVE == which) { + Intent intent = + new Intent( + Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + context.getPackageName())); + if (intent.resolveActivity(context.getPackageManager()) != null) { + context.startActivity(intent); + } + } + } + }); + } + } + + private static String getNotGrantedPermissionMsg(Context context, List permissions) { + if (permissions == null || permissions.size() == 0) { + return ""; + } + Set permissionsValue = new HashSet<>(); + String permissionValue; + try { + for (String permission : permissions) { + permissionValue = + context.getString( + context.getResources() + .getIdentifier( + "rc_" + permission, + "string", + context.getPackageName()), + 0); + permissionsValue.add(permissionValue); + } + } catch (Resources.NotFoundException e) { + RLog.e( + TAG, + "one of the permissions is not recognized by SDK." + permissions.toString()); + return ""; + } + + StringBuilder result = new StringBuilder("("); + for (String value : permissionsValue) { + result.append(value).append(" "); + } + result = new StringBuilder(result.toString().trim() + ")"); + return result.toString(); + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private static void showPermissionAlert( + Context context, String content, DialogInterface.OnClickListener listener) { + new AlertDialog.Builder(context) + .setMessage(content) + .setPositiveButton(io.rong.imkit.R.string.rc_confirm, listener) + .setNegativeButton(io.rong.imkit.R.string.rc_cancel, listener) + .setNeutralButton(io.rong.imkit.R.string.rc_not_prompt, listener) + .setCancelable(false) + .create() + .show(); + } + + public static boolean checkFloatWindowPermission(Context context) { + return PermissionType.FloatWindow.checkPermission(context); + } + + public static void showRequestPermissionFailedAlter( + final Context context, @NonNull String[] permissions, @NonNull int[] grantResults) { + final String content = getNotGrantedPermissionMsg(context, permissions, grantResults); + if (TextUtils.isEmpty(content)) { + return; + } + DialogInterface.OnClickListener listener = + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + PermissionShowDetail.showPermissionDetail(context); + break; + case DialogInterface.BUTTON_NEGATIVE: + default: + break; + } + } + }; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + new AlertDialog.Builder(context, android.R.style.Theme_Material_Light_Dialog_Alert) + .setMessage(content) + .setPositiveButton(io.rong.imkit.R.string.rc_confirm, listener) + .setNegativeButton(io.rong.imkit.R.string.rc_cancel, listener) + .setCancelable(false) + .create() + .show(); + } else { + new AlertDialog.Builder(context) + .setMessage(content) + .setPositiveButton(io.rong.imkit.R.string.rc_confirm, listener) + .setNegativeButton(io.rong.imkit.R.string.rc_cancel, listener) + .setCancelable(false) + .create() + .show(); + } + } + + private static String getNotGrantedPermissionMsg( + Context context, String[] permissions, int[] grantResults) { + if (permissions == null || permissions.length == 0) { + return ""; + } + try { + List permissionNameList = new ArrayList<>(permissions.length); + for (int i = 0; i < permissions.length; i++) { + if (grantResults[i] == PackageManager.PERMISSION_DENIED) { + String permissionName = + context.getString( + context.getResources() + .getIdentifier( + "rc_" + permissions[i], + "string", + context.getPackageName()), + 0); + if (!permissionNameList.contains(permissionName)) { + permissionNameList.add(permissionName); + } + } + } + + StringBuilder builder = + new StringBuilder( + context.getResources() + .getString(io.rong.imkit.R.string.rc_permission_grant_needed)); + return builder.append("(") + .append(TextUtils.join(" ", permissionNameList)) + .append(")") + .toString(); + } catch (Resources.NotFoundException e) { + RLog.e( + TAG, + "One of the permissions is not recognized by SDK." + + Arrays.toString(permissions)); + } + + return ""; + } + + public static boolean checkPermissions(Context context, @NonNull String[] permissions) { + if (permissions.length == 0) { + return true; + } + for (String permission : permissions) { + PermissionType permissionType = PermissionType.gerPermissionByName(permission); + if (permissionType != null) { + if (!permissionType.checkPermission(context)) { + return false; + } + } else { + boolean result = hasPermission(context, permission); + if (!result) { + return false; + } + } + } + return true; + } + + private static boolean hasPermission(Context context, String permission) { + String opStr = AppOpsManagerCompat.permissionToOp(permission); + if (opStr == null && Build.VERSION.SDK_INT < 23) { + return true; + } + return context != null + && context.checkCallingOrSelfPermission(permission) + == PackageManager.PERMISSION_GRANTED; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/SPUtils.java b/callkit/src/main/java/io/rong/callkit/util/SPUtils.java new file mode 100644 index 000000000..9b188f2f8 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/SPUtils.java @@ -0,0 +1,175 @@ +package io.rong.callkit.util; + +import android.content.Context; +import android.content.SharedPreferences; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Date; +import java.util.Map; + +/** + * @author dengxudong + * @version $Rev$ + */ +public class SPUtils { + public SPUtils() { + /* cannot be instantiated */ + throw new UnsupportedOperationException("cannot be instantiated"); + } + + /** 保存在手机里面的文件名 */ + public static final String FILE_NAME = "doudou"; + + /** 保存当前时间 */ + public static void putDataAndTime(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + Date nowdate = new Date(); + long timeData = nowdate.getTime(); + editor.putLong(key, timeData); + SharedPreferencesCompat.apply(editor); + } + + /** + * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 + * + * @param context + * @param key + * @param object + */ + public static void put(Context context, String key, Object object) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + SharedPreferencesCompat.apply(editor); + } + + /** + * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 + * + * @param context + * @param key + * @param defaultObject + * @return + */ + public static Object get(Context context, String key, Object defaultObject) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + + if (defaultObject instanceof String) { + return sp.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sp.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sp.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sp.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sp.getLong(key, (Long) defaultObject); + } + + return null; + } + + /** + * 移除某个key值已经对应的值 + * + * @param context + * @param key + */ + public static void remove(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.remove(key); + SharedPreferencesCompat.apply(editor); + } + + /** + * 清除所有数据 + * + * @param context + */ + public static void clear(Context context) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.clear(); + SharedPreferencesCompat.apply(editor); + } + + /** + * 查询某个key是否已经存在 + * + * @param context + * @param key + * @return + */ + public static boolean contains(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + return sp.contains(key); + } + + /** + * 返回所有的键值对 + * + * @param context + * @return + */ + public static Map getAll(Context context) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + return sp.getAll(); + } + + /** + * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类 + * + * @author zhy + */ + private static class SharedPreferencesCompat { + private static final Method sApplyMethod = findApplyMethod(); + + /** + * 反射查找apply的方法 + * + * @return + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private static Method findApplyMethod() { + try { + Class clz = SharedPreferences.Editor.class; + return clz.getMethod("apply"); + } catch (NoSuchMethodException e) { + } + return null; + } + + /** + * 如果找到则使用apply执行,否则使用commit + * + * @param editor + */ + public static void apply(SharedPreferences.Editor editor) { + try { + if (sApplyMethod != null) { + sApplyMethod.invoke(editor); + return; + } + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } + editor.commit(); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/UserProfileOrderManager.java b/callkit/src/main/java/io/rong/callkit/util/UserProfileOrderManager.java new file mode 100644 index 000000000..d9eb265fe --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/UserProfileOrderManager.java @@ -0,0 +1,106 @@ +package io.rong.callkit.util; + +import android.text.TextUtils; +import android.util.Log; +import io.rong.calllib.CallUserProfile; +import io.rong.calllib.RongCallClient; +import java.util.ArrayList; +import java.util.List; + +public final class UserProfileOrderManager { + + private static final String TAG = "UserProfileOrderManager"; + private final ArrayList userIds; + + public UserProfileOrderManager() { + this.userIds = new ArrayList<>(); + } + + public UserProfileOrderManager(ArrayList value) { + this.userIds = new ArrayList<>(); + if (value != null && !value.isEmpty()) { + this.userIds.addAll(value); + } + ArrayList userIdsTmp = new ArrayList<>(); + if (RongCallClient.getInstance() != null + && RongCallClient.getInstance().getCallSession() != null) { + if (RongCallClient.getInstance().getCallSession().getParticipantProfileList() != null) { + for (CallUserProfile userProfile : + RongCallClient.getInstance().getCallSession().getParticipantProfileList()) { + if (!this.userIds.contains(userProfile.getUserId())) { + Log.e(TAG, "userIdsTmp.add : " + userProfile.getUserId()); + userIdsTmp.add(userProfile.getUserId()); + } + } + } + } + if (!userIdsTmp.isEmpty()) { + this.userIds.addAll(userIdsTmp); + } + } + + public List getSortedProfileList( + List participantProfileList) { + if (this.userIds.isEmpty()) { + // Log.e(TAG, "-------getSortedProfileList--->isEmpty"); + for (CallUserProfile userProfile : participantProfileList) { + this.userIds.add(userProfile.getUserId()); + } + return participantProfileList; + } else { + List callUserProfileList = new ArrayList<>(this.userIds.size()); + for (String userId : this.userIds) { + // Log.e(TAG, + // "-------getSortedProfileList--->userId : "+userId); + for (CallUserProfile callUserProfile : participantProfileList) { + if (TextUtils.equals(userId, callUserProfile.getUserId())) { + callUserProfileList.add(callUserProfile); + } + } + } + return callUserProfileList; + } + } + + public ArrayList getUserIds() { + // Log.d(TAG, "------getUserIds.start"); + // if (userIds != null && userIds.size() >= 0) { + // for (String userId : userIds) { + // Log.d(TAG, "getUserIds.id: " + userId); + // } + // } + return userIds; + } + + public void exchange(String fromUserId, String toUserId) { + int fromUserIdIndex = -1, toUserIdIndex = -1; + for (int i = 0; i < this.userIds.size(); i++) { + if (TextUtils.equals(userIds.get(i), fromUserId)) { + fromUserIdIndex = i; + } + + if (TextUtils.equals(userIds.get(i), toUserId)) { + toUserIdIndex = i; + } + } + + if (fromUserIdIndex != -1) { + try { + userIds.set(fromUserIdIndex, toUserId); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (toUserIdIndex != -1) { + try { + userIds.set(toUserIdIndex, fromUserId); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // Log.e(TAG, "-----exchange----fromUserId : "+fromUserId + ", fromUserIdIndex : + // "+fromUserIdIndex + " , toUserId : "+toUserId +" ,toUserIdIndex : " +toUserIdIndex); + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/permission/DeviceAdapter.java b/callkit/src/main/java/io/rong/callkit/util/permission/DeviceAdapter.java new file mode 100644 index 000000000..35cf3a465 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/permission/DeviceAdapter.java @@ -0,0 +1,263 @@ +package io.rong.callkit.util.permission; + +import android.Manifest; +import android.app.AppOpsManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.media.AudioFormat; +import android.media.AudioRecord; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import androidx.core.app.AppOpsManagerCompat; +import io.rong.common.RLog; +import java.lang.reflect.Method; + +/** + * @author gusd @Date 2021/09/17 + * @escription 处理系统之间的差异化问题 + */ +public enum DeviceAdapter { + defaultAdapter(), // 默认 adapter + /////////////////////////////////////////////////////////////////////////// + // 小米手机 + /////////////////////////////////////////////////////////////////////////// + MiuiAdapter() { + @Override + public void gotoAppPermissionSettingPage(Context context) { + try { // MIUI 8 + Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR"); + localIntent.setClassName( + "com.miui.securitycenter", + "com.miui.permcenter.permissions.PermissionsEditorActivity"); + localIntent.putExtra("extra_pkgname", context.getPackageName()); + localIntent.setPackage(context.getPackageName()); + context.startActivity(localIntent); + } catch (Exception e) { + try { // MIUI 5/6/7 + Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR"); + localIntent.setClassName( + "com.miui.securitycenter", + "com.miui.permcenter.permissions.AppPermissionsEditorActivity"); + localIntent.putExtra("extra_pkgname", context.getPackageName()); + localIntent.setPackage(context.getPackageName()); + context.startActivity(localIntent); + } catch (Exception e1) { // 否则跳转到应用详情 + super.gotoAppPermissionSettingPage(context); + } + } + } + + @Override + public boolean checkLockScreenDisplayPermission(Context context) { + AppOpsManager ops = null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + ops = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); + } + try { + int op = 10020; // >= 23 + // ops.checkOpNoThrow(op, uid, packageName) + Method method = + ops.getClass() + .getMethod( + "checkOpNoThrow", + new Class[] {int.class, int.class, String.class}); + Integer result = + (Integer) + method.invoke( + ops, + op, + android.os.Process.myUid(), + context.getPackageName()); + + return result == AppOpsManager.MODE_ALLOWED; + + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + }, + /////////////////////////////////////////////////////////////////////////// + // 魅族手机 + /////////////////////////////////////////////////////////////////////////// + MeiZuAdapter() { + private static final String TAG = "MeiZuAdapter"; + + @Override + public void gotoAppPermissionSettingPage(Context context) { + try { + Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC"); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.putExtra("packageName", context.getApplicationInfo().processName); + intent.setPackage(context.getPackageName()); + context.startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + super.gotoAppPermissionSettingPage(context); + } + } + + @Override + public boolean checkRecordPermission(Context context) { + return super.checkRecordPermission(context) || hasRecordPermision(context); + } + + private boolean hasRecordPermision(Context context) { + boolean hasPermission = false; + int bufferSizeInBytes = + AudioRecord.getMinBufferSize( + 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT); + if (bufferSizeInBytes < 0) { + RLog.e(TAG, "bufferSizeInBytes = " + bufferSizeInBytes); + return false; + } + AudioRecord audioRecord; + try { + audioRecord = + new AudioRecord( + MediaRecorder.AudioSource.MIC, + 44100, + AudioFormat.CHANNEL_IN_STEREO, + AudioFormat.ENCODING_PCM_16BIT, + bufferSizeInBytes); + audioRecord.startRecording(); + if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { + hasPermission = true; + audioRecord.stop(); + } + audioRecord.release(); + } catch (Exception e) { + RLog.e(TAG, "Audio record exception."); + } + return hasPermission; + } + }, + /////////////////////////////////////////////////////////////////////////// + // 华为手机 + /////////////////////////////////////////////////////////////////////////// + HuiWeiAdapter() { + private static final String TAG = "HuiWeiAdapter"; + + @Override + public void gotoAppPermissionSettingPage(Context context) { + try { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ComponentName comp = + new ComponentName( + "com.huawei.systemmanager", + "com.huawei.permissionmanager.ui.MainActivity"); // 华为权限管理 + intent.setComponent(comp); + intent.setPackage(context.getPackageName()); + context.startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + super.gotoAppPermissionSettingPage(context); + } + } + }, + /////////////////////////////////////////////////////////////////////////// + // oppo 手机 + /////////////////////////////////////////////////////////////////////////// + OppoAdapter() { + @Override + public void gotoAppPermissionSettingPage(Context context) { + try { + Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS"); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra("packageName", context.getApplicationInfo().processName); + ComponentName comp = + new ComponentName( + "com.coloros.securitypermission", + "com.coloros.securitypermission.permission.PermissionAppAllPermissionActivity"); // R11t 7.1.1 os-v3.2 + intent.setComponent(comp); + intent.setPackage(context.getPackageName()); + context.startActivity(intent); + } catch (Exception e) { + super.gotoAppPermissionSettingPage(context); + } + } + }, + /////////////////////////////////////////////////////////////////////////// + // vivo 手机 + /////////////////////////////////////////////////////////////////////////// + VivoAdapter() { + @Override + public boolean checkLockScreenDisplayPermission(Context context) { + String packageName = context.getPackageName(); + Uri uri2 = + Uri.parse( + "content://com.vivo.permissionmanager.provider.permission/control_locked_screen_action"); + String selection = "pkgname = ?"; + String[] selectionArgs = new String[] {packageName}; + try { + Cursor cursor = + context.getContentResolver() + .query(uri2, null, selection, selectionArgs, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + int currentMode = cursor.getInt(cursor.getColumnIndex("currentstate")); + cursor.close(); + return currentMode == 0; + } else { + cursor.close(); + return false; + } + } + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + return false; + } + }; + + private static final String TAG = "DeviceAdapter"; + + public static DeviceAdapter getDeviceAdapter() { + DeviceAdapter adapter = null; + if (OSUtils.isEmui()) { + adapter = DeviceAdapter.HuiWeiAdapter; + } else if (OSUtils.isFlyme()) { + adapter = DeviceAdapter.MeiZuAdapter; + } else if (OSUtils.isMiui()) { + adapter = DeviceAdapter.MiuiAdapter; + } else if (OSUtils.isOppo()) { + adapter = DeviceAdapter.OppoAdapter; + } else if (OSUtils.isVivo()) { + adapter = DeviceAdapter.VivoAdapter; + } else { + adapter = DeviceAdapter.defaultAdapter; + } + RLog.d(TAG, "current device adapter = " + adapter.getClass().getName()); + return adapter; + } + + public void gotoAppPermissionSettingPage(Context context) { + Intent intent = new Intent(); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setPackage(context.getPackageName()); + intent.setData(Uri.fromParts("package", context.getPackageName(), null)); + context.startActivity(intent); + } + + public boolean checkRecordPermission(Context context) { + String opStr = AppOpsManagerCompat.permissionToOp(Manifest.permission.RECORD_AUDIO); + if (opStr == null && Build.VERSION.SDK_INT < 23) { + return true; + } + return context != null + && context.checkCallingOrSelfPermission(Manifest.permission.RECORD_AUDIO) + == PackageManager.PERMISSION_GRANTED; + } + + // 只有 小米 和 vivo 设备可检测,其他设备无法检测,默认返回 true + public boolean checkLockScreenDisplayPermission(Context context) { + return true; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/permission/OSUtils.java b/callkit/src/main/java/io/rong/callkit/util/permission/OSUtils.java new file mode 100644 index 000000000..952b79a01 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/permission/OSUtils.java @@ -0,0 +1,119 @@ +package io.rong.callkit.util.permission; + +import android.os.Build; +import android.text.TextUtils; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** Created by Android Studio. User: lvhongzhen Date: 2019-08-15 Time: 01:49 */ +public class OSUtils { + + public static final String ROM_MIUI = "MIUI"; + public static final String ROM_EMUI = "EMUI"; + public static final String ROM_FLYME = "FLYME"; + public static final String ROM_OPPO = "OPPO"; + public static final String ROM_SMARTISAN = "SMARTISAN"; + public static final String ROM_VIVO = "VIVO"; + public static final String ROM_QIKU = "QIKU"; + + private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name"; + private static final String KEY_VERSION_EMUI = "ro.build.version.emui"; + private static final String KEY_VERSION_OPPO = "ro.build.version.opporom"; + private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version"; + private static final String KEY_VERSION_VIVO = "ro.vivo.os.version"; + + private static String sName; + private static String sVersion; + + public static boolean isEmui() { + return check(ROM_EMUI); + } + + public static boolean isMiui() { + return check(ROM_MIUI); + } + + public static boolean isVivo() { + return check(ROM_VIVO); + } + + public static boolean isOppo() { + return check(ROM_OPPO); + } + + public static boolean isFlyme() { + return check(ROM_FLYME); + } + + public static boolean is360() { + return check(ROM_QIKU) || check("360"); + } + + public static boolean isSmartisan() { + return check(ROM_SMARTISAN); + } + + public static String getName() { + if (sName == null) { + check(""); + } + return sName; + } + + public static String getVersion() { + if (sVersion == null) { + check(""); + } + return sVersion; + } + + public static boolean check(String rom) { + if (sName != null) { + return sName.equals(rom); + } + + if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) { + sName = ROM_MIUI; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) { + sName = ROM_EMUI; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) { + sName = ROM_OPPO; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) { + sName = ROM_VIVO; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) { + sName = ROM_SMARTISAN; + } else { + sVersion = Build.DISPLAY; + if (sVersion.toUpperCase().contains(ROM_FLYME)) { + sName = ROM_FLYME; + } else { + sVersion = Build.UNKNOWN; + sName = Build.MANUFACTURER.toUpperCase(); + } + } + return sName.equals(rom); + } + + public static String getProp(String name) { + String line = null; + BufferedReader input = null; + try { + Process p = Runtime.getRuntime().exec("getprop " + name); + input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024); + line = input.readLine(); + input.close(); + } catch (IOException ex) { + return null; + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return line; + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/permission/PermissionShowDetail.java b/callkit/src/main/java/io/rong/callkit/util/permission/PermissionShowDetail.java new file mode 100644 index 000000000..e71cb041d --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/permission/PermissionShowDetail.java @@ -0,0 +1,58 @@ +package io.rong.callkit.util.permission; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; + +public class PermissionShowDetail { + private static final String VIVO = "vivo"; + + public static void showPermissionDetail(Context context) { + String manufacturer = Build.MANUFACTURER.toLowerCase(); + switch (manufacturer) { + case VIVO: + openVIVODetail(context); + break; + default: + defaultToDetail(context); + break; + } + } + + private static void defaultToDetail(Context context) { + try { + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setPackage(context.getPackageName()); + Uri uri = Uri.fromParts("package", context.getPackageName(), null); + intent.setData(uri); + context.startActivity(intent); + } catch (Exception e) { + Intent intent = new Intent(Settings.ACTION_SETTINGS); + context.startActivity(intent); + } + } + + private static void openVIVODetail(Context context) { + Intent localIntent; + if (((Build.MODEL.contains("Y85")) && (!Build.MODEL.contains("Y85A"))) + || (Build.MODEL.contains("vivo Y53L"))) { + localIntent = new Intent(); + localIntent.setClassName( + "com.vivo.permissionmanager", + "com.vivo.permissionmanager.activity.PurviewTabActivity"); + localIntent.putExtra("packagename", context.getPackageName()); + localIntent.putExtra("tabId", "1"); + context.startActivity(localIntent); + } else { + localIntent = new Intent(); + localIntent.setClassName( + "com.vivo.permissionmanager", + "com.vivo.permissionmanager.activity.SoftPermissionDetailActivity"); + localIntent.setAction("secure.intent.action.softPermissionDetail"); + localIntent.putExtra("packagename", context.getPackageName()); + context.startActivity(localIntent); + } + } +} diff --git a/callkit/src/main/java/io/rong/callkit/util/permission/PermissionType.java b/callkit/src/main/java/io/rong/callkit/util/permission/PermissionType.java new file mode 100644 index 000000000..9c7b83582 --- /dev/null +++ b/callkit/src/main/java/io/rong/callkit/util/permission/PermissionType.java @@ -0,0 +1,267 @@ +package io.rong.callkit.util.permission; + +import android.Manifest; +import android.Manifest.permission; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.AppOpsManagerCompat; +import io.rong.common.RLog; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** @author gusd @Date 2021/09/17 别在多线程里面用 */ +public enum PermissionType { + + /** {@link io.rong.callkit.util.RTCPhoneStateReceiver } 类逻辑需要该权限 用于监听SIM卡来电 */ + ReadPhoneStatePermission(permission.READ_PHONE_STATE) { + @Override + public boolean checkPermission(Context context) { + return super.checkPermission(context); + } + }, + + // 摄像头权限 + CameraPermission(Manifest.permission.CAMERA) { + @Override + public boolean checkPermission(Context context) { + return super.checkPermission(context); + } + }, + // 录音权限 + AudioRecord(Manifest.permission.RECORD_AUDIO) { + public boolean checkPermission(Context context) { + return DeviceAdapter.getDeviceAdapter().checkRecordPermission(context); + } + }, + // android 12 的蓝牙权限 + BluetoothConnect("android.permission.BLUETOOTH_CONNECT") { + @Override + public int getVersion() { + return Build.VERSION_CODES.S; + } + }, + + BluetoothScan("android.permission.BLUETOOTH_SCAN") { + @Override + public int getVersion() { + return Build.VERSION_CODES.S; + } + }, + + BluetoothAdvertise("android.permission.BLUETOOTH_ADVERTISE") { + @Override + public int getVersion() { + return Build.VERSION_CODES.S; + } + }, + + // 悬浮窗 + FloatWindow("android.settings.action.MANAGE_OVERLAY_PERMISSION") { + private static final String TAG = "FloatWindow"; + + @Override + public boolean checkPermission(final Context context) { + boolean result = true; + boolean booleanValue; + if (Build.VERSION.SDK_INT >= 23) { + try { + booleanValue = + (Boolean) + Settings.class + .getDeclaredMethod("canDrawOverlays", Context.class) + .invoke(null, new Object[] {context}); + RLog.i(TAG, "isFloatWindowOpAllowed allowed: " + booleanValue); + return booleanValue; + } catch (Exception e) { + RLog.e( + TAG, + String.format( + "getDeclaredMethod:canDrawOverlays! Error:%s, etype:%s", + e.getMessage(), e.getClass().getCanonicalName())); + return true; + } + } else if (Build.VERSION.SDK_INT < 19) { + return true; + } else if (Build.BRAND.toLowerCase().contains("xiaomi")) { + Method method; + Object systemService = context.getSystemService(Context.APP_OPS_SERVICE); + try { + method = + Class.forName("android.app.AppOpsManager") + .getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class); + } catch (NoSuchMethodException e) { + RLog.e( + TAG, + String.format( + "NoSuchMethodException method:checkOp! Error:%s", + e.getMessage())); + method = null; + } catch (ClassNotFoundException e) { + RLog.e(TAG, "canDrawOverlays", e); + method = null; + } + if (method != null) { + try { + Integer tmp = + (Integer) + method.invoke( + systemService, + new Object[] { + 24, + context.getApplicationInfo().uid, + context.getPackageName() + }); + result = tmp != null && tmp == 0; + } catch (Exception e) { + RLog.e( + TAG, + String.format( + "call checkOp failed: %s etype:%s", + e.getMessage(), e.getClass().getCanonicalName())); + } + } + RLog.i(TAG, "isFloatWindowOpAllowed allowed: " + result); + return result; + } + return true; + } + + @Override + public void gotoSettingPage(Context context) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + Intent intent = + new Intent( + Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + context.getPackageName())); + intent.setPackage(context.getPackageName()); + context.startActivity(intent); + } + } + }, + // 悬浮通知 + FloatNotification("FloatNotificationPermission") { + @Override + @Deprecated + public boolean checkPermission(Context context) { + return false; + } + + public boolean checkPermission(Context context, String channelId) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + return false; + } + NotificationManager mNotificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channel = + mNotificationManager.getNotificationChannel(channelId); // CHANNEL_ID是自己定义的渠道ID + return channel.getImportance() == NotificationManager.IMPORTANCE_HIGH; + } + + @Deprecated + @Override + public void gotoSettingPage(Context context) { + super.gotoSettingPage(context); + } + + public void gotoSettingPage(Context context, String channelId) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + return; + } + Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); + intent.setPackage(context.getPackageName()); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); + intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId); + context.startActivity(intent); + } + }, + // 通知锁屏显示 + DisplayLockScreen("DisplayLockScreen") { + @Override + public boolean checkPermission(Context context) { + return DeviceAdapter.getDeviceAdapter().checkLockScreenDisplayPermission(context); + } + + @Override + public void gotoSettingPage(Context context) { + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Intent intent = new Intent(); + intent.setPackage(context.getPackageName()); + intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); + intent.putExtra("app_package", context.getPackageName()); + intent.putExtra("app_uid", context.getApplicationInfo().uid); + context.startActivity(intent); + } else if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { + Intent intent = new Intent(); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.setPackage(context.getPackageName()); + intent.setData(Uri.parse("package:" + context.getPackageName())); + context.startActivity(intent); + } + } + }; + + private static final Map permissionMap = new HashMap<>(); + + static { + for (PermissionType value : PermissionType.values()) { + permissionMap.put(value.mPermissionName, value); + } + } + + @Nullable + public static PermissionType gerPermissionByName(String permissionName) { + return permissionMap.get(permissionName); + } + + private final String mPermissionName; + // 是否为必要权限 + private boolean isNecessary; + + PermissionType(@NonNull String permissionName) { + this.mPermissionName = permissionName; + } + + @NonNull + public String getPermissionName() { + return mPermissionName; + } + + /** 跳转到对应的设置页面 */ + public void gotoSettingPage(Context context) { + // 默认跳转到权限设置界面 + DeviceAdapter.getDeviceAdapter().gotoAppPermissionSettingPage(context); + } + + public boolean checkPermission(Context context) { + String opStr = AppOpsManagerCompat.permissionToOp(mPermissionName); + if (opStr == null && Build.VERSION.SDK_INT < 23) { + return true; + } + return context != null + && context.checkCallingOrSelfPermission(mPermissionName) + == PackageManager.PERMISSION_GRANTED; + } + + // 权限对应的版本 + public int getVersion() { + return 0; + } + + public boolean isNecessary() { + return isNecessary; + } + + public void setNecessary(boolean isNecessary) { + this.isNecessary = isNecessary; + } +} diff --git a/callkit/src/main/res/drawable-ldrtl-xhdpi/callkit_ic_nav_back_x.png b/callkit/src/main/res/drawable-ldrtl-xhdpi/callkit_ic_nav_back_x.png new file mode 100644 index 0000000000000000000000000000000000000000..9a91423e93afb55e8de352e4152f102c958381a1 GIT binary patch literal 634 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_mute.png b/callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_mute.png new file mode 100644 index 0000000000000000000000000000000000000000..87059956e6404202716992b0999558de19ca3e33 GIT binary patch literal 2833 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_status.png b/callkit/src/main/res/drawable-xhdpi/callkit_mult_video_user_status.png new file mode 100644 index 0000000000000000000000000000000000000000..a8f1b5b6ace392f9d1837c440d63453db2cce30b GIT binary patch literal 886 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 R5u5-3002ovPDHLkV1jd6Ozr>x literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/callkit_select_ic_nav_back_x.png b/callkit/src/main/res/drawable-xhdpi/callkit_select_ic_nav_back_x.png new file mode 100644 index 0000000000000000000000000000000000000000..31787cd2593917fb5ca06a9e6cd8e5fe3728072f GIT binary patch literal 652 zcmV;70(1R|P)WSObD?cg{jc)oe%?ak#G*=M}!VGuFL8)?8IGChZsNp)cmk@zc>=1$bp)oitT`Ltpx3We zz+`Fpid{IsKjFAJ-R*Bq!erePs0&UYU72JuYt7cZR*oEoyT4jx#2V|m2nrn7@YDI` zs<`uI{NFgRS8WH_hy%pGM#!92i4#E>5I@O`HN%PjmyDb)IAO!7o%?s?vVBEF6)b0n zYa+N~Y^5zasVM9yAz&uNi9aE60>bGmfk2}wP_=Wi2?%M^$gf6!b09g#J{QJCV|9z)Ct)Vs0*?!PzPj3plYNiph~1?pem#{{G7blPiuQTHpr&00DhTL_t(|+U?uhZo@DL24ISf!8!5%Z@Zl2 zY;M#$$TsoaH5dI$RACYcc&+AT02jkDZ+UCzIDw;S+(O3zTn*zII)St41v9vtVF7mw z4B&2n5JCtcgb+e_Mv|&nO9DSs^&}abuwIbBMbhukr&iP-DmWR~%&*&>vV znmg4jRN9w{cKG^H7878-J5aG5?PxPF`@G>ok+8K){1 zPDF{t{?Xz}b$*-?eTNLjQq_)Rut$R0V9DTw_-MtP!IPZ*AVU9sXfC+Z4elyCzRsXO?sxSx5Q;C5bW`keP~q P00000NkvXXu0mjf>z($R literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_ic_phone_pressed.png b/callkit/src/main/res/drawable-xhdpi/rc_ic_phone_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4bc26f00ed13af0105fdb953758a12ad1b143d GIT binary patch literal 4633 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 J22@Du{{e`bLIwZ; literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_audio_answer_hover.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_audio_answer_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..a26c91e914977f1cb705164f0aa44c4316e265c3 GIT binary patch literal 4184 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�g#Z&LGz9s=6khY^pkeBgoAE_mv_ja)&m2FZYyGX9E_Igknj zr(Zhkz!MwAe&M+=~UI?bpBq0)9itjHp5l* zJ!ni0ui-aBY8pI~*Y8Nvfnfd+nI(U}bE#-uGK-OpTiop~^Z7DOoFmHzOX#Cng&PTy z2cxx`49i8dzeig{YsF9(?kLm5$_?mkbMdQ*#SK_C`9aJe`HAeVN24<7vRzFC2sY@~ mE4#3~L?l*^u&zh2Z~zimE_NC4MpF0x^-T=Sk(GMx(fPx%DM>^@R7efAl}$?ux+n%3q%Be`y3kd`wFWo-fNZ*oPy+cPWaS@l zFZo(XAd9ZdT4<>Xc2PG<7pd6@MJ#P&$)X@>G^UyHIRPQ2N#;(l7cO(|Iq!S!d(WJi zt36O0>2!L`G|efO%k|VS3?H^n*Yz=Mx29=s)^16KeT996Df5DL6-*W0&sMATHIYbM z2+nF~!vL8~X4>I!_}lIFEVyUGur^|69OxMFhp|}fWDxHkVWm>(VXanMf)L=O6N8BN z;isD4nY&)EcRv^mUU%obBP^TEE)aapX~w%j|Jz1fjXmGSp3O432%~zZj;}ElVdLui4+lPIK_jg1fu3`COZTFg{H1F8jX`wDs?IRVzKD1 z*XvUxpJ6$R$d}?*8E6RPa=FJ~H#Cez9B)*JauUWa^IbBT{H4Mv6bet8&E_(k74R+< z4wy}izFOy0lPUyCosCAL2P)WJOg^8VruUlKb$a@_eP4C0C=9d&;P0lNLX#>4LQC^k9XEAkpru^(1o#2Zeh zbK44M758{NJBT~C!Vy0Qr+*j*MAS9n3*m6MIt-^03xz^*kFJBQSl~Z*ez4q$as@3* z(?R5+$wm8(Sw{FL8uzzFBHLm1ls|!=`HKDI9)85EV}E47tsCk3;|H3jpn(7Y002ov JPDHLkV1fk<9g+Y5 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_audio_left_connected.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_audio_left_connected.png new file mode 100644 index 0000000000000000000000000000000000000000..63444fc135274b9d330873910c9449461ea86431 GIT binary patch literal 912 zcmV;B18@9^P)Px&N=ZaPR9Fe^m_3LSK@`U?pQusM2y%joIf#v3;gLe3P0W`dh=`zIAvR(mq97+| zWpP?4DuQ?T0d^vyaEKuJx{wcJidcDAoP`Qn8ZgAmCt3e5WRBg<&SsO{?J}^;?t5?E z`{m8s*_ljCjN3Q^=4QacbDzuQw$^I3o6t|=$_s*UKN^kxYfxl^jO}l?+wV%H(gyh$GoJgvs@3WX zKzKR9X3FLAJV$4!STdEVRB8rU`8+5BrZp6aL@2AKHA%(*bwFdJS&eohn@PZsi7i?@ zVX6;nvD0HC2m7wkSw*AW$Yye|Wi6hN*{@pc^w>ziLZQ$Kf_@p~5L5Yfkd0ow1dN;k z?4_Dh=-=QAVEU5L2j+6Qo+9{P9vpNZc{(HIePDjSzl`8_c|kgz&Ox5eNO>O^IY;n^ z=zb{$0`$pbGPzetXQWIKthb9e2M9qP42ACi_yT&#S3_>6_gN8)oC0nM-2{F<#PXO62j|k``Tvx*3@W6#RolZ}-TCEf01HSSo7w(rv6Bs!{O-%zXj@wCk z7PsC@vWQ@F2-df4qO4Xbl{t*L2phX-Y{6=^UdNBhi)7tf&0u8R%UlA^r{s>4pNMLD_6}2hIaA1foNVT3dzk8$fr$ zcAJ`EPxl_1Ppaqc5;Zg!IYF&#Y&M(EaeKPw)Q}F-dI8h=jGU>ymAq(3c@?#E2EXnS zY??f~VdbddV{FVwU~Di_{}^zGaB<%*W~;IP!|Zf{krTj`91aJa6=nfA@_`s*1-sq; zgn^AzV{EXz$C9!eg?B#%S$HNc&RY!j37dO*EK z(NoQ?Z5m7gV*q%2*I}in_3IQaI$7-jtT^Tm$mWr$dtxZaCd5YcY-)?eVlD*mpeDg5 mRPjH^Pg4VqosTo1l7au4!W|0cGpn8e0000Px%VM#fi4Usy_;MGeJ*{x#$9-K<{ns;@u zl^ARE-C?29!%BIzH8}T5A&d5E%1Rl)h1CY-`bzeOCy02q(r>jjew3*iAnJ)`w_%<8J2zO2L1o>O>yC<|)6UD7L(E4B2x@^vH$VDt6y zl1Jku7wk6{Mbw2vPy3V~NJlq(#w-{HA4HX&_~F6l2VR4XrR_ctE{5txa4#y{Wi#HL zMm(`Lu;$K4ciR^~N2}4rZrdH=@KN-*{is?Py?GPb^LJdPqg_FB@HZj7&A`Y%sWt!r N002ovPDHLkV1h%wK(YV; literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_audio_right_connected.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_audio_right_connected.png new file mode 100644 index 0000000000000000000000000000000000000000..d17eb411a3d1046c76d673f1f301c87df753cde1 GIT binary patch literal 982 zcmV;{11bE8P)Px&kV!;AR9Fe^S4&7#VHEz)9VbV7(1X$-rGyGJXH;ASxhX=TAR@v9zSR46a9?(xno`L5RD2IQy*b`H$rAn0U-J!e(az z_bAbJy=2HR@8`rXubwZ~Hr1;vZ|ltqD)=c{5-9=pdrDnh(QsD$s*2I;%QZuW3f7px zS;44;Q6sH2Lq>m~zzog`CQKL`HA4mrCe7fiU{t~Y*?<``1U6&_X9c4Y=5gl?Q#Jad z5z>lz8VzIBuM!p_lkj0AQUG}3b-UueWoU#YI_$Se*dHTt0PLNSFP3(Vu*RaS36S8L zQ4(5_yN!IYv}=TMayoNv&@206vp|bjY*fN+28Buf~ys+{rUPn>(+?E zZXVq31D1H0`fXT~3UP&k!N=#?N7iV3F)*0w6S~c2umFCbJJ}{pPJnKk4Jw;Uol!UD zvW~%2ob?~!9CijhO|r}Iq%kFo6IHbLWd{TJn(kz&e6D(EkpRO^M5(^zgi~{E;#F0Y z>3WJeL)%S)hz+#~u!~+fr$^YtXj&K#2vyFHZ|D}1Aqc`pdhI<3(3F#z-FZ46{8b%a zlYBGdB$^e5W9R1*w4|gt&)4mRfUqq}7!Rs!8`?al_+L@w_(w{l=Pv^`LTB$5+FCY5 z0)~75FTApo_j72ATC^}uLcOwz%>?dJ!sAgBE&>3Obc)2?;UN)Mr4gsMC~Jxi@?uGn zDrgg)Gr}#}j(AAKEJ>IM_Q+0;4WvCJ&Tw@Jtho`!1&Oa;D1-(AFcNcmAGmDQUCw|07*qoM6N<$ Eg3!UnLjV8( literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_camera.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..a210f42c41cee66ab861affeaad0fdf43a57c52f GIT binary patch literal 4710 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_disable_camera.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_disable_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0e42afce91f26bd3d63af9f168b9dc37933e80 GIT binary patch literal 5043 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 JPDHLkV1jx|%WnVx literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_disable_camera_hover.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_disable_camera_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..c7beeb6a8a6512d2c3ead617cfb74304ba2d6032 GIT binary patch literal 4609 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_float_video.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_float_video.png new file mode 100644 index 0000000000000000000000000000000000000000..775af3347f81fd7b7ac05b12fe451e8a33f1c577 GIT binary patch literal 1567 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc$WX!DQqR!T z)ZE-iN5ROz&_v(BP~Xs4*U-|+#Kg+LKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7I$IMft0d=ry1 z^FV@{U|qhxR-SpqC5d^-sh%#jNJ>^PqZDaJj|B%?+nseV}9XLD7p8-7q0w8Uiuli5JL$C;!wuV45!iCT^!6rXLs> zn0h^3978H@y_w_hArdHaJUw@-hA$7ZxOK*a#>Pzx7A+Uq^Wv;t)2*e8nicPvTv#lm zR1qDh!GG;y{R74PtEvJ`3IX}6I|4%@7Os3S|K;!Gdxs3p}z>(8@f5CmN6+BZ|94_z%%sTYBIP~h#gAGEekKb)R@>+!@mh(dE@)Jjkmz=tF zK&zuMY4*45vT(!YZyNa@XsxhImaJCgP2jn*JbRJF`crT9I-0CL+-y(EYqb1uZ>@}Z zlbIv?kJKt3t(W`ykHm!E%?K@By+zMd>`Ka+S>_LBA3qus#+)C+d*q==z1{t@5+#$C zyuEPv^=bB3n`AAIzm6#gcGTq)$`0N$C(U^M!S3Qyg?EqUHG7_Zvq@&pryrM;le`=#9vr@PJ@4qd3$DsI}9;@nkL)MMmz#xMmXJ}AHcICWzDe`2F z+}RzLKc+R!*~~NRfb9l1$8!^R9}0cI`NPlgnhQXcW15j}E)^O3#S1DlQ}4H%N(TBHC*3lg5LXJBSvdzBR2%qZOoDzZIY{an^L HB{Ts5{_slw literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_handfree.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_handfree.png new file mode 100644 index 0000000000000000000000000000000000000000..a5ad6aba930baa8009947f23ff8fa5d2b688a839 GIT binary patch literal 4543 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_handfree_hover.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_handfree_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..ee2c9dab64515e4bdad946897422a85536083bb3 GIT binary patch literal 3995 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 Bo|FIp literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_handup.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_handup.png new file mode 100644 index 0000000000000000000000000000000000000000..1d9523abfc5e3523b51de7dcbc18b5070d2e02f6 GIT binary patch literal 1035 zcmV+m1oZofP)Px&#Ysd#RA>e5nLTI}K^TT}i3rAkqA`dD1q~_@#ZJ>%#M(v+NjjTE1RIH9t=KD) zLLoMaps@)4pd!~<1wjyOL=;4cu}JWb#F+JYmziU4Zuh+1o6TL|K6r0tzHjDzzuBGH zziVr2S?dU_o+A(hK?fKE)8M-))$Uj|vrw|22;!`W^8#r837SMHf{$PjbeU4^Br6hV z+}V;iaF@^wKG|S&8L1t5gW#8`yAvFX_Fu6&$y8fH%6V-x8MWng1!f zE_0Vq=!{Dw4Db_;(JW1n`pWMeBT7-Rgybtr)+QbXVq(@GQx@^%yLS*+Fv9K<3f(sO zXleRaOw#%(<1P;Q?j0*0O;q(Hf3;ZL7&9q_rdd2`Bkm6G=KUjqbi2`WyoX zz*jKEHU10b>M?;*UI_PF&qjPC<~!4ep72jklg=3T$fHvFO0%?ZmD!}X4`%O%7&>iT@Pjdp!!LrF1rc&`&NlR0Nd_3^DcO)^>gqO;Cu{>;iz zF%H54cwvYqD>~%hK&#j2eeg;T=?*Y&$WM7Ck0C?nu+j4W6$RqchJ2P%k1n|x{AZ2U z-CRT@3fnCP^9;wTz5V;0q6Xg*< zEqI4R_8@rchcST#k!?WtmPN2Lp<5<5eEPfMHIR*DB1tm{k*lFp5P02;aN14&je2LA zoHF%A#GVz+=VB%jXAnI5z?=xNVJDnl6S2`yG68pj5e%;^_SOPM=R&T6jY;Ju>K%4Xj zkSVb#Fai#O9-vo(UN8WLzyqMGo=p99@zAHI#v6(30=IzuTaIc~(@pgmI8<-;xx5&W z*j5tLyUS6aB=zXO0nCEW;1hTbCi$2#L)o&{5op#U@DGU994a)}#-#uN002ovPDHLk FV1lN<>2Ux6 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_hang_up.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_hang_up.png new file mode 100644 index 0000000000000000000000000000000000000000..5edc980da2453057035ecae2b0b9d7915264ff3c GIT binary patch literal 4194 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_hang_up_hover.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_hang_up_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..be532ef45ef9161b2602fab9559c3422474c20d2 GIT binary patch literal 4477 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 P00000NkvXXu0mjfc)y+L literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_add.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_add.png new file mode 100644 index 0000000000000000000000000000000000000000..448146ef1d2727778ed3df88e96c8aea75ddb945 GIT binary patch literal 1823 zcmaJ?X;c$e7>&phP+SpHt#yb+qJ+$3fsh0UA&UeIMu-)waxx@?L`-H(1`;V^r9xS> zxUmVYcv`BcD7bqnDY&3fT#Kk!prQy`aBo$#6BO-_(m7}5eea#`-fz3_OpY>YhP&GY zHxh~DE)SPP6Dyr~A+j^^UA(rqjaWXzrLlMnnt+>OBSI2s(Rc)q>)}O6Gy-dvEp0%8 zNTi`OohlZORm|jTP(1^-`!Fnej6jn}K|%`#YmyKgh({Lb48hc%<0q+rP8&>}>#u+m zm>5aag{K;knA9khCN)XJ(^7>YK#+w`5aBOzr386Sn;rqyqgecv3L+ zeNwRsB_KwP2;k4~_tQWuCcxz}nEw7;E{hJZASMTdm>`qw$K>%j96kgAA08?Z&8SV_ zM@wWMViCJwY9fwfd=NC7%?vY}ff^TqOdgL1LM)KQ@*_O_Ov?;7Z1FRgrVKDh5R=BJ z!*CsH0PKu#JerILQ;AI9m!QW!(i%)3+C(%Aw7?k1WI*r57P;|*a7nO-9j+zot3=oU^y9Uq{utsOF zA5QB>DHMFU!GyyG4I-BWQwbi1PN(H_n2(Xh(_K8&|q1&o*^r zJZhy<{1?3YV&jitm^V2u$0yXUcWP&mdzZDQQ{WI$=27O7b!yde^}16zhaM}sURqyGVBe1(RBA9%mg!uN|4-ksUYmRddgf(n|b?m#c=-3zy7X z7kj{~ZC}+*-j>$1wplcrbNbR>;Ib(?>(yTyV`#>)UZR$RDgYhV7Z zt-ZkO%s2Zhsus7s+~qOzH?KG4xsFY)?{d1*Eal`U+qLUG6MTD$wZd8lA7f66*Ri^b zDd*N6IUHXZ8Rae9?f#%Gd18rY$Jx#CtCtF9HC3v?`=hUXEn3$gKX<<(`l6sXt)s|3 zrElmijaHW7>bK)-A(y_f>Y~iykG@E33wSP&noO^~D~5O-hu2KMWzGt#=E$<$jIgdo zxZn==$%KFxd&Xt1jAM1&m{)i0!9hyJL>rf>WX`=Ps7>84dfPcAtL0#IR_R~K-TM~j z7d%Jmri(HYx!<7)O}%lKPQRTSlK$%9(vrXHdCkb<*H;Z5zD|=}lA3$&&fO5<>o6m9 zZwXCwK0cKGwq@6dKk3`hs3x20g37V5Iz6|#@oin{h-{zDnEc_`M_YD|dCLE85Y+rdKPopMrdQa9I7#9rlpOwzR>aUmg;0rgUc31a0 zA3NHpXA34R#}Bp^__*7At~5-K8w1v&+!?Md;dd2NH;g0=TTcd?=f%eE)_+PA^-qTao>&c zm8=PCuY$bfizL|&OBQX8YXHZOPT|B8SY&`Ri5^A7pe2wQDE@{0+j1a)kV4 zD!|JdjHa{5U>i#t3nB~w2iqYn;WjpQc8G0Y1PpEsg~6e4D+@RhWo?au!N7k%5J@x^ ziGuRQxcwbVa&m-3a5xMU6dE5NZy9f8NoR#a;YcJB3PV5<2nz|qf}I${AtYGDunoT} zV90DDi^||o=`r9nMM4-omg5MKIQ=UH8smp-4EyggNeTu{ATXeCOW0aU-+^9U{~t=D z{XnxhzT|)W{!d{xE|Eco`jXl7SQb&zIEvv~C`t7LHDj{$54z2s($(j-WHZ zX!N(Lfla*#L~6|1<<@U3FE5mP44XrUA(GuOju45CC6!7-+1a_mT@YxbE8GnMhr8N1 z+auv_R%k0*D_d7Pdu!|OTnwEUOC!f{zH>?caGih3T^k4*LlPN7W>MqFBsUhF2L6^f ziu!Xe5=TGt@)wu%b1(Kk~4pDUW!N8@ufyGC&6y+uj(^4^ag&F>73QH*>{8-Gj+4j-)PeWs6 z(3N4QYtNo6#)^kT$VD&gp+k<{fHV9*`F8MRcrxrdJU1glltKX}{;4g#DMC@2=Is}? z#CJsHyf3^XEqXj1pqyoBDPn+!=F9M&$t2aE6Sa$={1VYK(GlGEyL0A^0%T6&5#PPa zo0~)yA}>+CNW+XFp6(KKq#R9DwYqcpV{quX0qB~Dhn~loV%VWJ#2ax8nJ;{S4JrY)U6<8y`Znv^aZgK#cvsWA` zR`Ugn^8NT(6L-@qVK?_NHv<}$-NGhoI%atTyo)^DefQm_O&jpW4XnuQ9?VRz*y-Ut zjX1bDuQy0-IS!HB^bBWr(8)F`Px;x%x_gGVNg=qP)oJ5~&D4t>kBdI1J_%{+-!!`= zQ}gOC4txAu)CuqbfpMemyR8qWW3z`!Zh|!Jl8i2Uw>;Uf zymdIG&TA9o6p5Verh88+c(! zZZD+KI2@=rLb|P@su^2>x$^#Dx`BhouFupz1WuZZwjS(_)m3^ybrYzJ z8$$kTgQS8U5mK~(!n|-b*1W(_-M#hq=qljeNA}3vHx^5wkB$HE_+3!5-&$56Uw6)E z`>_Xl4nEznpbVjbjmf1>nrC!m_Ki}{!NSs;tt!Q%!miiX9_R(>ahosnryR#)C{YhK zirtS>yp^7Sl!{E?G;2)Zx)y^y{9CtmaE*hAd7-B*Ay?L`K{H_aU}sV%ecvP=QIL=^%iuU~b%QWC=(g{&c7SV9q~8 z8csK0hh)!Yl*;^?HGOG-8Moa&@yV-&*z(<3iN%RVZ&n{=jXmF!$y&L+s-SMOPBG|F z=cffhnYnc3trk;R?1#|6_c!kIUcgt4+2b?vz@s}M?M+v-ndh9`g+ML*`aX4$-3epJ zIn318(jE2i#Ut)wjc|)-eQOIB)vH_Pz9gK&i!Fw&qNNKsH#*-928C8N|MFqrWad-l zK*g_@%8u&3TqJE<4R+H1FkV(_O+ngN>TI7Tegs+jA8**la2?z8_EQkPYc#c1)Y~U$ z`8TW?Zwri0{ECX*kDfs08MIz>RXMN~M*;@lO|KuZ@7ma{)|}g8@Z2#Ve_$flML}?p znQieNTvw)(2YnhfmyZO`YpbB6eU!M+NS&};CADVkq*~wu=kZ@bS&t`-Wb4*69;z)L z?J>A&FU3`*NF7;Q`i>D3F&dD(U^eY2Zox0U{w~i-<0kd>N zVhB+q&Pb`vamo%F=PkkxrqG*ZH`ty2blE3V`CcVDWs$H>(V;D4?%d(ccBdz&2VE$y zi|4d59{ZCN;dzI3K^yWH41a678lLFdmUGZ@2A zyYgcJ=*4dCaP{^+UUBjaKZLu!m=Ai<2fu%@`LLY4f6+oQ4wJ4aYus@ow_=qvTNXgr~0-Tqmf?3%FB^u(#xQs zTT|x;>&%^^O?KC8jh0xhN{#%gRP8##wJ3q1fYAv36IFNiB>-pcF?$LA zbd*XbZKH|~W(G7KuR&CkW8~Ak<2nNx4MrDQBOgIZ_tX@~Eexb@68gb2^2#$PXF<~V zvz2_h{E9I_LHWZ8RpAOrW{O>TqOj&T4b3r|cMct$S8k%oyti7PewL8EnWBo7k8BH} z6wrwiVZphIecq0@h0TpGFVrmkzQynU=J~DPZvlR0t~nB8y@^T2nd zrU;y4&|0&5E-l0Tj)?uf q=|Fb$5Wyg5{u6wa;|N>*1qM+2sG;djn{iqD?RR&@V(MH%)BXczD^isJ literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_checked.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_checked.png new file mode 100644 index 0000000000000000000000000000000000000000..07d246cbcc776ee07ef3f7293950a298c0c25ba7 GIT binary patch literal 1172 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_normal.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_checkbox_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..cd297ff87e2598171f16c7cb8d6a22a3ddbe32ce GIT binary patch literal 985 zcmV;~119{5P)m)UiJwzje^!z9yrot=5_GjHd| z?pvql3~7FT{wCc=9LKp%nTcd+tp>T#Xlx=^rl+Sjbm3o;(`_fg0XBj0QTo=A*N{IW zSCOmz{rx|rb8m0&D)l}*^+Tq;Yuc}L3*9m3;^N}q!NI{ChK9*y*L7E?rl!6Ms?)Tv zuyCVZua5zpC$IPR_CC$!a@(Es|0^hf=~}Hehq6Z~F9GNBM0u+=p66Wxc!mKN zXtSJ7rv+SV)n4^&L4mvs=*s5Spy7mLN`C~LG*a+Z4ZJEc{b4KFDy#)n^x+%pV7BL0=d{A>N4r?yjiZB1g!_@KDgT2RAwu|Rt`vW`8R*fa+MHr@KFUc_vI zi?SHDst?M_(t@%w8MY%(2(1M*Y(D4~D{II~cLF6gyt?V~qZc^;Jhc(luvL6E&eQJ- z4%h}NCb5Z2i%IU)c{(Q9rX(h@iOC1Wy({FrA{e%SibYIf3qg6r+n{2d5zN>EDi$$` zEd-UIfE8{oD$H`;uwsCvAf|xDzxDdVJM=aqSXL~E^4yM8*%kvx%VIhOstQK%gpmv= z78Eo{x-@Yp1%Sx0n& literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_input_video.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_icon_input_video.png new file mode 100644 index 0000000000000000000000000000000000000000..3ebd5ab09b55163673d4227ed6f89e6da13a1704 GIT binary patch literal 540 zcmV+%0^|LOP){r&y@|NTr% zOvlJ9b^rhX5_D2dQ~dn?{`~&_0R8>_{st?P(~i5w(BPl|00DqWL_t(|+U?t0Zo?oD zh2b;Y0yv4?v;W1`sA;i!vHF0Am-!apUkt&PB7xiPv8_qxW0000VS)*P7ZI_W~aq8=I8Wl+e)7 zNs}fmUc9)sw^vnFmG{=6NT4!~k|4j}zYPEW{o8KKxvz5%&>Ti}PZ!6Kid%1QAIxhp z5MaJ=&^Yn$|M-}Yz}CAfzDz1zvi82@$qJ`Knj2-mi7DmY=W~CtxHX_!W}$8Hbg5|W zjoXgO6;*GUke!$Y2J;mdYgIfujDN1(GIM#4dh6=XH)pW?G2G`JUZ~-x_iNW0(>5{7 zwHed5`yR|(xaUA@@CVz4d$Lb;F8raoC1hcMsc+fJsLK*vT>I{MFa4D~zo{p(Mg7u^ zm5(^@Rebxl%KKlgWRSx2zsHo>_u6{1-oD!M< DH<`JL literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_iphone.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_iphone.png new file mode 100644 index 0000000000000000000000000000000000000000..787d44a72d439cb4949f218d0255fe6809073d25 GIT binary patch literal 5483 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 h=x literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_iphone_hover.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_iphone_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..aff88241d8a462030f84b2e6d16ce07819a072b2 GIT binary patch literal 4022 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 O7QtCLV5=>?Q~nL)18gM# literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_minimize.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_minimize.png new file mode 100644 index 0000000000000000000000000000000000000000..477bda1398083fad2276234f19faac1f2049baec GIT binary patch literal 2773 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 b^T7WBHP4Sg{IZaY00000NkvXXu0mjf)Ad+J literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_more.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_more.png new file mode 100644 index 0000000000000000000000000000000000000000..c97c1c8da646aaef63b2610b575fef38e6fdf772 GIT binary patch literal 939 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_notification_answer.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_notification_answer.png new file mode 100644 index 0000000000000000000000000000000000000000..fa473189b0e2840c6d637dd28478c43a5e9a9590 GIT binary patch literal 1633 zcmV-n2A=teP)Px*8%ab#RCr$HTYZQWWf=cGbGNgn^Z^yr%yvN%-OegTB^YRsXjw^SLV@@}A7&xm zRY*u>by`M5RA^<=my|*1AC^ZZ6>5@^kO}GC?1d6|-n;rwbQ0>$y7R>By6fJ$yYI~G z?B2r6UkmT=`TFfU?>x`*zAvE(&vj?xcTpR4f^h?gJ3)ot=**dC41sVQ%tK(x{pKtW zogA0k+i3Tw5eBY3+jV0*DfcpAHV88TT;|ixX)yOOlwG7MKMOiCAz1Z9 z!qy}}w~S8#JnqU^tAcFq5go~@`9f6!bSu6Bpt=){mf%IfL!#aMrjjoe3D7fL)4<9P z0LHgO0ChUSzzAT^N~wdtm#eBsKrCbIY?UOZ&e)6MPO>x{G4GcW;H0-iyd@~Zt)z#U z7L}*Xm&^doGJYGY+`iFdIkiJdHSZ|3Gm3y*RR?bMOs`I!sHe1wEE15f=j{VcD{1Qq zgQ$-ge-Ussz>j)T#W<>{%G5$Xp-6z9j`xD-RZq&s0&L?R(P92rFzvM4ls4Mq$ra*W z5lOCbWQqi6R$@1SXLwT7WH6C3b2!q!yWFg1#cwCjC7-w&?)@TE^UfjxI#23ECVRZe z@pv-FHqTCVB%R!(;uEtH#~3`pt$PSf8_S0~%#Aq$^mKd+h!!?GFjw{zo-5jueKmv6&)}q|%$4!2h??{A1X#uhfGb=% z)I<<7=BJ|Oc9}`tN^Aglg$!3V{-03I%gNU&>d}%PI59mk939vulhxDlS3s0o(Y-!) zmS>P=8H)+{!mDsY@d_4*cJphQjab@P&4kxvxN74JEFmpzyhMc8{VEAsj+qvxq65-e zM9U;zAm%sfvCoXvq*?Kg2=tU6MGW3Xz&_hnjwx-J2LHtl!-FoO68?~`sQo6L-~+E56k4s#~FAsrJA3}GumE<%lzSRo}3|^K}lOM}`h-Km{ndxmA&h0n@ zN1Pe(FR|xMjz5KJ-crku2NISF)pUA~H6P6~o+IEL8P3Z%6Gr?J&@WU|I%{MkxP9lf zbH+2I;5{$FxxwZM@b?M;WKVaq7gvo0Qm|yW-IS)^jcm>qUIAZ=AeeWEX!1cfOqY{T zsWnwek8T;u0es-bh9As@MbQ6e5QOa_V$OGCyhs9Lfrz?Da;(JD4BqHQw_i;DGgxmT zMARoDwRc|%4#v_6C%xS&b6B(D%LuedhO2k{LLwAED$Kk~M3aG>6=?LdFC{IP3I|vW z{UlWL?t1`kerueO?I8P5{%ZaoBgl+BmJIRXN0i12=) zCOw@Ji)9iknK`fw&lM4+4UwQ*VwE-^syU^nja8uf3maEKmw-mM#2V8SJt$OjO3idR zop_Om*Lih52>hs~sH3n!ZSh})YEG-|BhJD|k@0f` z9XwNTRJRhJd*0FU5oJ{o<~1Uk>~+SQwKaB#fy2Z&1%)Pqd3KQTc+ypEYb^gc4Dse@ zfyGd7kLMP{upf|cNC@>2ncP|s_Cr$n1u?|OAG%IvhXUk_qC@)Xf f>dLh8_4)q+*?-9G4)vaD00000NkvXXu0mjfD{K+C literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_notification_hangup.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_notification_hangup.png new file mode 100644 index 0000000000000000000000000000000000000000..05fede5c06df701b08528e421cc82634362924e2 GIT binary patch literal 1577 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_signal_1.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_signal_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f63b5a4182c3e4c2af8d6c9173f8387852a39c19 GIT binary patch literal 659 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_single_audio_answer.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_single_audio_answer.png new file mode 100644 index 0000000000000000000000000000000000000000..963939eb08fe0985089e2cd8367b610bf7a4e1bd GIT binary patch literal 4959 zcmV-l6QJygP)Px|8A(JzRCodHT@7$t)pb7i?XKkAmB3(PY(m<^VIpW{eoPF(7RJ~Cx1n(zwmIo!XO(XWAm0ctQ!Ol?f1&9|8el2u9d4P2$%435XIxO2%LTy;=C+Y3(```QIcW0!%``*3xoO{l<_vhSm?-evd!^&-PPN`gM(KWqAm((Ii zE|4USB9hHSqM0N$lR#V|&Oyil#0N;w0Mg)33?R>Y$n%mWs87?izDz3H_h`F#b0&&R z%!EpT-o7eG%%^0!7aWrEY>42z`RI140wK^Ru##@47*}6$-5g3ymcZ zmftFyN^)o!D;~010i~aYU$GXU+$^Moj#lJpJlM^^$cWsY?sa0&k{}k**Z|@3oicUk zP~iey&>ATIQYb#Fri4Wiz_?eF)HQ#8{*ilDi?W)0PUcE^AhdN3;@3`VB+*q;%6XI7 zSNod~q8|dj6I^!nbTo0Rp=?kR2vE3Kwr%K=vM#@ZU;bicrRRzKrovB{=#aE@)-cFYKbZ+ZbUC;A)DvV%kNaF+fV`s%O8{JQt!~!QtCIO|34`x zktLH5A6|hlC?cuFMHww}>NlC}l zqtdF<6oTHCq;0tHrrb9-3fLzi43Pq1dFRlHC0V`;L*}*!>liyyP)bimq^|7l$Q_J| z`N*tsOScs+8lm!22?%PdmSx1UVwu%W9ZZVQTLhjFj6PG?1dHH$3!am| zG2of~KA9vIgalZoEL)aw5an6R2owlyorUW#ApD`aOT^Zy$2E@ScgWa~b%0d}Y>dE+ z=~DkzfV?F|)sTQDwCj61@^{oo=IC`GKrosrpcMUB$`REhQ6Lh)0J2O%T(<9~{C$24 z^bG`K(Fpxk(jE9!h1dL|sHIaE`dzg01q5S?$g_iFVCYqgf#ib{-^n!4xqhaWo`GPj z8<75sWQrJwE`1kb*cnJW+pE#Z)2xBb#%wW6K;T<{ffc~IV4bjTycFsQ2)uTXn2o)N zJLEhtwygz-hBr_dUNvx~?L z=SkYi62NXOEK;5BX1w6IYuE_SB6ccCKu}r!%Dll3m375BbIOzBgzR3%4iiobPSVv^ z0<0_6nNuztbq$82DGl}|K88-kszy5Yfz+s}#fd|#qZYyNHclK()zGdBF8GJbx^t4H zW{WVs?_f_dOK>7i1=Fy*TPn4zmI=CQi@?T-@y#bS0i&P@5|&s3@DpVn)-p6z1p;qF zLqSUIKw?DB#)kM4juMng;OPwP(4nErDyb`qk~gHj(m(hsOc#~di^z)q>}eUguq92$ z%{`jo|RQvl?ji z=^1KBPsVM&5&Pv9H_+lgNYP*Ys7Qk&VM{Z{<>Lo!=#=O#yIRA2&`P3a(s$5e`*$CyLl3-NPu<9y0uGU3j{u-qMqjyq`}qNB@MLw z@+^I5wk?a(>T>3X()9T=Gt-_Y53CZ9tz){iJ{ybMN_p(0lIe+~c#?%KJ1@%`t$+rL zh?{T?x{0|>?((=Pej@z6v9>TE;Y8E=g?vLWK;Rmj^Wor{1h3-&ulXX;0Ca8We4N+>5cq84 zdT&z62iUdG4RF9{?fb3qS_-qKwZ?1Zi{`z|j_G`i+5`~B54etohYD00rW2Z8Jpl@U_8UT7vZ*65u`M9ZjbF$r{0>{0F$}}=6 ztNI?;@yYo%?mA3|a1~b)TuZ>vy~ekpVW6nQ7B+S_bKAG`0P}C}EBXe(>z0A4HSSuh z4l`J3SmO?}2bT=GXAEe3C0=l)`Y-8!4!Uzb-2eMB4GjCI`*n0HtPuX=c-SFode!Q~ z7)bNIh~&L%u2#OMcLxrR()DLMH!}=+v3SQAfWN0)pc1zw^bEUy<9y`LOV5)jn~Q-^?Swueoo@(s0r7i_rUYct%B^*-nPJ;{M0Jh+k3D5xz~K&xb%}t91RKb zUCC;Nr(f0S;5#~<=+J}tlGe1VR>W;>z4qr`^SR~Ee|p)B>i|TP|AK-q;XxN`1s{hi z`zgmKV+F5TU<_!mAt=`(aD^UvVU%<%9ytxX8!8DNB>)U)B-HB~xH_+60qU2S(m4%F zK9Z(ICx$#~v|+|N2(-p+lB)X%7(k04lxz`LYTrHJe9*}0zr3sg_j5-Z;xizuA{Ssl zEV*S6W;Cg6yL#K|Ed8+y@8(nm~VuZVf0hMd}o&R>Xq(m#xIYI0X8weiUvXo^ZELC|3gXlN4pf+#GCGKw${{QKkXyodPIm5r+!>6mQPrlu$) z5)2K-fTrnMY=FSk?*46=e)em32BSH7jW+&CGG3?z8^(Z^No8XN1g^}#b`R6rL+-i= zUZGsqrmO+Al8z#I&KS@hZ5MB1X#Hj+6aymi?qQ-WkGbn2nDmv48tBst6Z^s>H9+@_ z0do;QcCEtW=pycY)?F9D0{H9m8tMF#5-?c6VCdeEh#>6%cDyXHyo^PZZ3_$MYxL3M zoG(A8Ff!ut0{xWeu@`F_sm}Odimo^#13F{Ak-vxM)cw6BdJz5+GvU}@);%lRXc2H3 z)b3blehQPUh<|+Ouq&@;E+P#u{1d=%<)X?qhNE!8+dm`Cw$EhgT=+!J#;hZU6J1W8 zo1*nAX3<@1a`Z)lCnBU{} z`Inz)pldw3tCe87-uJsQ@h04sxf-2?L%ta(P6M9~fBVnfEsQxWJJfVSJo!XN(;}u} z9W`|rb$KFxS zM;DgNQAeR`L+9gkCxF1;u@u=AH9uj{>&Fp1?LR0QTinAazgn4miO9;2sozCR)%7GG z%%7isLDqnzcKv3E~`o}qqZmzqD|Vkftk^8Mtgq+8pW4qpkkw6pLGT-{s!5LGqrnb<7*Rk*Jm2hXLT z1N&57cXyG3JXbn69!2lIj{K<@EKYL=x0M7ZgsFYTwF;&{`Q)}W-yNbozpcFtZRTUIBRg(7e0($Hyz!fm?-Gwsr?h3loR-)?@Nsh>HlB!B+Q2KpQvPXTV^=l1+hDjA_&4maU<;NdVK+RK?HH7Kol|)BzElka?>@nXgOLP(L{c|PJd4c2E#Tzv_!&RBO&ICTUB zF6hFWa^FNhQnjCPLNG}ajRaU%tTU(790Osa5PC+Wu7qtNR=c8{3Svg3gN|5NtTU(e zats76u)8C75cAPBWMiUqN-#+mvIL+T))DK<4JB7V;DYzH=O2W3%N938lC;rDfOW$< za!b)Q5ST#v)cgi?5l^@!mZT3^0?>(}8xLeW0f8-44V1b93mC6@pqXR|K?1A`)=4$% zVKuUzfWQTEAC$?+RT!PVQ;k6KE_?~F4p0aC1E7IvdkNbWIt3cux z7e&?q>%tH3zJS1l*@lfBGoM4#RG%$Ierg}{yexB;eXVr_C)M-~1SW#z&HG@}{(=*N zNt)m!z%pmq2T>xrm*7HMXW=?5PTdAqH|Hl;1V{deDamLF0D_*5{2f76I#3`mQ*dUv z7#C094S&aMP)sJ}SS5fl0lI^rS^~4=z=6O8vk!wD9lakb^|MVv$)|q_@a%vGhCz%8 zrg9Ss5SYmF?E|f)lGufA;)JP0lke^&z;*&-is*B8P>FINgGIZ-c{-CJ?d-$?X(t_* z&tNfRS^AwKR-+nPi(nFEzsJ#M3Y&C6>yIRNH?#h}KH1F-YX@vL_G&S7Ns&J-!XBn}q zq5=VvkE}&7>$*`&?cuFMHww}>9f>}WrX1`(*~gIG%hZ`*4&P;X9P}!r34U6Mlatf zQ-}Hst940VnWcLv$FF+;X$O%Om#0e{*@??B`Cdd^iO0908JD5i d5sdk>{|7KHYmyq)SnL1*002ovPDHLkV1iqxo_+uT literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_single_audio_answer_hover.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_single_audio_answer_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..b062c3bc2945bc9f1b959186b5dec8fb1866291b GIT binary patch literal 4990 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 IM6N<$g3R4n6aWAK literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_switch_camera.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_switch_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..264e5169d8760c3ba118bedeb09d6879f2419486 GIT binary patch literal 2778 zcmV<03MKW4P)Pxe5nOjVi*%ikRcM1c;a8bFa%uqp`Iw%q)Wdx_0hLH)W?Wob1G`0_> zF|}$;YSXkylX=ia8=Km6IyBL@YGa}{!L-VZp;|Ak6BP#Ut7I{D-kq`|BD--<}c z7hp_P;k=2D5O`-+e%PXCe&tX#SB zJA3!;ZC4imw=+N!iE%6(w_?SL$$R$f*-vFmOw0_4KA~S26gV&AC2L3888bQVSwjIx zV69~Q`tIGkoBR9w&&r~`Sk{u--xlTzbA&gAnLbdap7ytG%$JoqXFX4zJo)VY{rf-m z&YJD$n7iXwB1P6N)!@&^TKwU|hbm#Kpj+%#{B zfWd>xpa99-Az{&?Md^nRAO0jUF%ioK?%lh0eEzcdwUP3q@kS<^Z~#sLkE0pKbZ}da)v|>mJA`FrW$&n5CVW-M6z9rCMzfr0aicwL%v5UB`w{?45{ztNeiQQs^fL*Q;n8w0PZE>mD_ zIEYf&JH}7tA_2~DcWw&-e0j1^?CZ$IRxB`)-O6r@RrV{uB)Cz^kt0Xu$Tb^nj&M>T zwJR+x4Mk7@A{YlF0Om4K&)RT+%RHOYE5jM?@hCyU6%4LIKjsnx$`h&VESN8&3}cuh z;o`-M@0XO6{2?|rHcdqPZr!@|=hLT8H#asmUTZq)&OkK5VRZ(?y^?TZ#2YQ1s z4%cH2Bw%hAg?xEs-5Mx|VwQ|A(j_LuWzf3Br|~S6^98n;od^!_^6Uf_OlxavTcL4- zjMXLj*X7HXzpHw7)Q`C;ZZ{NQCf!diDUKk4n;7}mUvi{1K z2ylk`s2x#xR5A-8NwyOx!~!UipbKhdX=!N#^m68g2L}h4BcRtplk&YeIXPe7x^*kAX92}onm&=F zXcb{j+l|DEii&Shp_{gG-@bkKm4&3;6WkSmGT<&iNp>peBKlV8Zf$LCR$XApk|lK# zaEeL^#zw0M3or(2CT3-2)kp?To;>+C30wh1AnYfNd(nmr=C542(x#p0YiVh@s;Kr) zwFPo>a|sBc$=ouuepK1{>8P6V3#JI;5|WaV3h936(4p%RxD`bGX9LR{5ez`yDYbOz z(odBCOh~P&s(Nkn=FI^;ji##18X&3^?T#?H?MS>1DVJG5;r1=v4gXO3hKi6i@-+Js zilMN%pgTvGFJHzj195S2TyB=4QYKnO%vw$vxduc6vuDq)lv1xKq~aR59qpk+OhI!& zdvEpVSx(3e5HyfVwod3ABdufnMyrS|!nk<7Lhn$Kk&#i1^g=3k1FmOeXtHEGf(zPt z>aVY_pGJqrk00NZ7;7BO~086j8J~&+M6*nKO}|A{IVF=e8X|89V&QL7kCm z#_L&gO2Yb46>*B@u$v+=r%s*v=7I$aKDL`#(%lI9f+X_k|`51JbW>l9bp!T#4KF6@Tg>^!1qLoK;ocw2w0Njlpe_jf2m{laK9wE z($D0Ui?x$I+qP}{wd(vXXS-s`t2umn#7AXOyAY+HSFTbCv?uOdJ-9c*l?}^3uz{wT-&-fCrjy5~M z5aHRJEld-LRy@n!6iVdp^KmhuOHYsA>v>-6OmYu8RyJ7)oZ4F!L)q0It7p7PU#Lg5Xe$di<*r+u=( zxyle2A3Eo&tjXHqaMbv~4UX#1oN$IaIyfs}btYty+4}!Sy59XUHPFV8uf}3&R>~X%j1%iZ~v0>+1s-UAk8F9ZPPck`Dn%G}kpMXHL zLkSBMl!F>V1{MM> z#9F(Wo?G%Og7pm;9a#G_E@fnq_@*D!kxY)1Chpf+TGJ!#e3~=`tWQ`{rVup!dCD&$ g8FAM3=Yw4S12Z?_Q^-rKE&u=k07*qoM6N<$f^3yoZ~y=R literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer.png new file mode 100644 index 0000000000000000000000000000000000000000..7bf266460134e0c95735ba02e1c40c408fca390c GIT binary patch literal 3491 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer_hover_new.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_video_answer_hover_new.png new file mode 100644 index 0000000000000000000000000000000000000000..3c1a74c4f7e28e33777ce20dd16215c6d31da52e GIT binary patch literal 5111 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

-!6Rf6*_0btJ;eRON2QPgt<@Jnu^G8(-9Q*nkiQ8>&?oy?<@eZ44NvAh zF5)b>so!JQ4WrWGnXv^Ax`xiJ`gQ|h!-KqVwsVQhMM^*+LO`BW#s<{-9W$tL0YBtB9pJ5b5O4PD;v8vn5MEWU*EjdjJ6kKk=@o)sY!8`M&Y!8JhP(W6H-2 zNdIwD2QO+V4uCF&u$S_xt&1=Hb~61$I;OK}lPbbfho2ie! z2(tsF5M+%))o*z<@!Y> z&+|HU!hR-cX+eh6Nq}`_>da<|wt?`3V2{@wtA3J1&SU%rOu^WZS}$ogq!Tk(;E9-VYHekW9OW z?4bkb!VT}PfPjKw!{#Z(9n6rr{#kA$r0}>ysro{bTr3oxga*vkcN1 z6yj!8S2y|B&Z~pQI>a$V2s@RUe@m9Jt{DS_Nakn!>|kDdbIWv{^m2Y)&eqEDJjnEI z-6XQ?-uFUhDY2|9!Y5B%qw7XFD}}?(8)bf( zvSIq=C7K$hza58O;JkzP9=RyPx|iAh93RCodHT@7>`)pfpaR;!;~2@D1!lcc4NPX#$LKPHA?%f^^uQ`%xm0tAy| zz@Z_Ih0^p?Esa}hdTO8KIHxVLjZacSYc(;%l*EBRFa#rP+4*r|{scq`;U~vnfy=M7 zT1%^)*YD11#7f$qc{?+^Z{&IBNIN_8=Dz#x{r3Ibci(-2rf9l&vz(qvC!0*eY%(P^ z36irUiQ|Z51CeMTNev`$Epg3B$bMY+lc0X&!Jp{IJ0IYkmkmL^hH3OhBXzxxw~Du? zqR7NlsMNB%}Fs@MQl&k8ZnTSArO~=0m4-~ zWaRMS#3iPnl~DW@P<)-95*A4SW2YghbLPzWWA|Mx(t7eao-6Hv(9$u0UpuXoL@T6} zjpNzZ`bcd>Hfae2C|oSsJh(h<%CF*=KTlifDKRDvL=3TEPiyRl z00?lcSJDayR`cJNxEiB;20*i3qVkFx(SupYhMA4=9XfRzS^#136S6ARGkCp}=B?=e zXL}`bt?3AQNeJU>(dO8;u8YJ-rFpG55L&h*Tg-I&PLgs?rG-(E@`ZTLh(x~By{4|a zBIS=3S}`Cj?2sp$GO|WwXXD*qpd*n9@&&ASkX{mJ!Q}WmY`5H#vN75qL&0@@!%~EQ0MA5c*!8H)7F* z3dRnwP;RU`GrrdEnT4;4;jRG4{vM`;^EDA|Fxe2aznUV~_}NwX286|1`$=OEo%`G;3h9F7i4fC+OTO_imm#|esr@N@=t=+M$-f!ujT$s1B%?;H3vri)taMP$W)=By|! zZK|RZVj27NKt7sE6hh$sXFG~xFn?6v$zWBuv*Hs0p7OCQFrWF0_I0}fZ6 zS4~%+9i{53@wkoGV87hFYMS>45&G*NBxzvSZ)paYK7P=aPKoZxRg0Wm0~RnuW@~z` zSIT#oD!i8e^yJ_ZXTur5@4OOZgXYH2?P#OQOWoORp4s% z{A${IRULh7T22-x)#coeRnc|lMkn15Z)8hAHfMC3eJ^vJQ_7i0C6hCk<4zrP*>Po^ z)e0D}h^V9+&`r#!S9?c={#3}DPq&kRkcnATxo|aKL`!hisinC-)3AFvc*=;yiWNnO`1W|w z$Ezsn(l}6s_pe765vKeSU>&orvvZ7_K5`sGNtFv>*W5Ucw`@L@u9v~qaL1k@8gdw! zhzF;C^{HyQ6s^fg@o~QmrE;?~|6jtSM_wGE|NPl7jg&RyMK%|?uQ79IWL@LwBX*8) zwYGv;+D|I*IX&)8lg?v>3;xhKs2Bu1MfC~D(=BSxqLUvPB9lD27(@$R=p|9^A zvR?oDB{fQ|i%OZ?ef=Hi&uB2ng!91mgDI8QUFRLux#i?K)*^uF64#Vn5_o42<5`c= zZ;zBdLSqmd8IabW4G53evdA2VY4UALYv>!x>nsrPO;zKWNBoTG+yVlhcYyH$2fwap zdb7WDM29wtp^0%T6zMSCE4%=-kph9$7%(LoYBsut zFWap*@hkKq-TPFEUU;)~P;qx~GECL{$Jbt_+b^vhTSoViZfUfnkE?&s$!OgYp!ibbD0yKga+fbNr1G0Y5Uo`cCP; z;>0lG(4lXC>^BarNPbixfHX&sKFYKR;J-fJYUJhRpC36&?|L{*&RdYe1I7T3Gc>gV!ofpoeLRm1f|T~YoTlr(lb}a?^_ku> z1`PPIX$6Gm`%FrvoGbUV6DvOJRmS1_M~QCVHAL;`(%u@ioxpQQnT}U4Fb3f7DQ9^_ z&#^bEUy>%3LqrR!?v3yof|=oyXuucCGM?jUXd)iB+;&)t;Q4O5H({G7z`Zix8t z?n5s)Z#LPby=9iWIY0Xj_?3#$9)$k400e9Vt6UPt0|(#H%vP8o^$0aZ*~U+ zb|CR9`AOS5o@E1$0}%Dz5%iAI!wPE!pM)#>8K;y!R$wop@BDI@iv4<3YR9ygCezkE zF$To^I|g1st8kib%(7eh{Wr!OugdLzWrW%v#3(FGB}hQLYLL*cYv7u^g$1Zzyyo1d zF#nILXzoV?I%+IIb)LQg3>YMZc4Gv)lHXNy)cEqEYMjpKzfdT?o=HI%8;P zr|W1Td?Ke|))7NQm(yoNsC`K--Lo=ApK#$7rHdSG-CID2*Va7=3!~cTOOu+gq3K^A zQ};~bmZ7z!hSpzJOEV{|R&p!TiO|0n|8ag}R3ldKw|=IMt~@h;9!*44fDK`0bPw&@ zx#o8a97IU|bL{Uy`{bZiHN2zE{%3n{bX1319fDje2J?JTtcBUYHa)8bD2b1*L zyOkO4v?IF8?32bss<{Y7GNbbhn`2yetq}tlG3?Zw`=ac9fN|sB>`Ws1O8LRS(NNes z%K7M`Xm$L{09{);A1z@F2>cyOk)8gPTt3Qu2*J~O|A!k)%U3dCqfG>}4gI@_iMk#K zgqbtrj|n0A$|*R%%6bFQQ(C`Y88BSoGQzxHGO_8hj#=0Ccm5m)1U~o)&D!?t3_-qr z{e4Mays!LY2DU@!oLI*b5BbW)ai`9eQ00w7_N~5ekX}&OAE8>t#Qa7ssZPvP+3%Bd zJc;G*w)$ri^7+b}*`@W1iY z^0r5Y=vzM>vf>{5S)+#(c5?g4M=sj=benUg!$-m`=tw*ZSNG;z#DaeBTx^!T4eo2j zBBz&9Pxh%?b#Icqj4NFVAGzNVJ^R|?XJW88$sIgri@+ISYM*kgf-M}5+_n-SYxexE z_%gKpj+0N0{dDV(j%o@5%nYE@Tp-}Ope?xBS8|ZrXQC{M-2oC|GMgYJT{+1TRl(bz*$J%DBCMVoX?P zP+u`8N)6a4RV)o6#^a{FL-fG&-gYs?%2j?Y#Bo#*toM#90tt94Sx^nF$ix_IXt!a5<$sEAw(+d`mrML8A3l*$Jk zv94HWPV40u2u!f6Ep`a=(Up|LMCr7^FrUv7fNoevtSgn0lz_m5_qE0!hIh+Gl|sV2 z<&yyGhIOP`qB0P;fT}a&YtcpQS1l~e@3RD;6H7NG6jKrq*g{oJk!!Gk@kR+{hOhV_ z0oDcUq>%NnP_ZQefeCUS6phMd7@fXXsDSX9{}Nywur5@`1=*aH3& z(Dy@R3nX~gBFQ>nUAW=h6%e>!wqaw(%xBRwRc4Eko7xBbU6wh^zSuf~lWMvK0vCei z%?Du9{(_SN!#v(efMw3I_ktq27w=L_M`9Hgr@jSOH|LQnyes~gp=7lL06}+K{BEx* z?I{qLDLAuSj)SM~g}-B+S4@U?86{OMjpgU{WQCv@YB5n zcy_=8Lodbz6S?sP2wceGt^LiZl-PxC;?#+ShTqjCz;*&_is*87kgsG<28+3f^K>Rk z#`&QIGM97|@4;fovUEE|EL5s*ErMMr`#p|4n^g3ZW+&56t45#32Rrry36eio1bmXdiDv6Ka*0#x%p@~vx_SRz*lw(zroywJI2 zqHrdBXBn}q$^`;0zHBXmUDtI|8jo%oyjhUB{#f*ZwB?ZNlYI=?y^KAJRGdn3(Neuv zb|BacF6@ven=-KxPVy^{`LP2#lOS3RI|)1WF|_6A)n~csFhwj3()sTB}x0dRbVMVkkgr%lO# zm}lP)_NO?&K`QpN#(oGZp?3S^v;;!7!dp59&cgSVklYFYq%r%M?$=Ow9|XJ|e0Jsv zSECdE+5^EBmep+>PFw;DC1x3Pg}$qsh+d0emaqtRatJ$}ntxlCxjq8}gly&)Z;|yW zIk*VR-AizP34noCLzc}rmdy+Ld=rXC05aOmv5h&bZFWS{@p<+A7DymW6z8(LgAJ9Sn+(`!LFOcI}>>d+V?2|gj_oS7{VvJ;16^0|mO l5|2+qvkpVcRbasH{XdM9WE@+GQKbL?002ovPDHLkV1f?ey@&t+ literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_video_left.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_video_left.png new file mode 100644 index 0000000000000000000000000000000000000000..f2fc8ad062fb831f8ec86161574eab154c0202d3 GIT binary patch literal 573 zcmV-D0>b@?P)Px$_en%SR7ef&SHDZcKom}{wxE+p0*Zq=l`1YSZaOFkE^YPx%DoI2^R7ef&S3gJ_VHAJw5~3NTBG^F$I|(XyiZ~Tf(b1)#f}qB3^>ivC;^bzF ziy}lj6p{#C+QCkaBAp941EO7OYjJRChYkUod;NW$ku&*_T+bs8eQ>$E-}nCf^4`ni zh3Q(Xv^`2fFNmZ^i0X@YkUJCoBI3`)w4F?tAN=@&Es>S7w}b?w!V@OmPR^LKl}2Ed zDG_;JsX-7uW*)0FbB0^KAmM!2UbRYP`cc(WI#qnTA2|Dtvu+WJ>va5M`dG>js>bsf z`?)ap6B(}zU893kavx>1?Z&K0I)Q-ijmBB!xYr z+?+0J;tdPq<6KZ@>l1CK!m_5(3k zMI0{__}R+j+AhA??~uhVkSg=1$(Yn$oaJ5?H5We~*P#LCi|_Y#7iZTcrT3`G82CHR z>)Dh&!Ulc){WCud2TgkOe@D^mt#?^#iMa;Shw9zb{VpeAoM}oKMi~D-{}U_C8D`~| zQq22awTwj~(P!8ovR*RY=c*Cgoa{Jy++y}(En3Ev_mWc2RU@W?uMF~^tr>GQ7Ewc% zKPgNJGI<_V%N*uZy$gl=sbc9OY)qLam}~uWJGlg==peE226GG>CdrV_;QlccOE35_ zAU~A4zEDc6y?WIUP#>`jwNa|IHv}5DTwbl#KK6c;-Ia&-XXGzebEqaRdH>@80000< KMNUMnLSTX%^dwCH literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable-xhdpi/rc_voip_whiteboard.png b/callkit/src/main/res/drawable-xhdpi/rc_voip_whiteboard.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1a9215fbe8db23199242279aefa19db7f0fe02 GIT binary patch literal 534 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^T<7d%}YLo!(3 zMq2wZ8w#Agw8X!$Wr~ul=qcL=d|&1$@U}k?S-7~lTHzpXz>61|5%=EQ654cZc4Ydd z&ECf@r6l*K-<#dfT$pAoKacTzLnhm+U3F@PstXzW6lN`axcc<*$mvC1R%QZACfssN zJ(9A*B75$J+*52q2iL;vUz3P`hA;-nXf%VR26SyZn6f_eod*Be0k#p4GhRp3uWizW!ZUu{4F5T!{c}Bx?_~K|NXFn(f&eGmUu zdLG!YyZMhphRu{88rv8bcnM5o_`@sTQzoExP{naia@-Zai8a4umKZTaI`G*EYyK>m z$5K5175_Zu2V73=n|>sCd;Z~k=9zUlTb?0oLZ$xVLuZ|nM1x8;Up{d_KdNxmiujUy RkAM-);OXk;vd$@?2>|hj^K1YB literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/drawable/bg_search.xml b/callkit/src/main/res/drawable/bg_search.xml new file mode 100644 index 000000000..c92572da8 --- /dev/null +++ b/callkit/src/main/res/drawable/bg_search.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/callkit_multiaudiouesrinfocontners.xml b/callkit/src/main/res/drawable/callkit_multiaudiouesrinfocontners.xml new file mode 100644 index 000000000..be7350762 --- /dev/null +++ b/callkit/src/main/res/drawable/callkit_multiaudiouesrinfocontners.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/callkit/src/main/res/drawable/callkit_selector_icon_search.xml b/callkit/src/main/res/drawable/callkit_selector_icon_search.xml new file mode 100644 index 000000000..ae75fa932 --- /dev/null +++ b/callkit/src/main/res/drawable/callkit_selector_icon_search.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/callkit_voip_iphone.xml b/callkit/src/main/res/drawable/callkit_voip_iphone.xml new file mode 100644 index 000000000..fc4874007 --- /dev/null +++ b/callkit/src/main/res/drawable/callkit_voip_iphone.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_ic_phone_selector.xml b/callkit/src/main/res/drawable/rc_ic_phone_selector.xml new file mode 100644 index 000000000..d2965bff9 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_ic_phone_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_ic_video_selector.xml b/callkit/src/main/res/drawable/rc_ic_video_selector.xml new file mode 100644 index 000000000..e9c324e42 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_ic_video_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_audio_answer_selector.xml b/callkit/src/main/res/drawable/rc_voip_audio_answer_selector.xml new file mode 100644 index 000000000..f0b5e72fb --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_audio_answer_selector.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_audio_answer_selector_new.xml b/callkit/src/main/res/drawable/rc_voip_audio_answer_selector_new.xml new file mode 100644 index 000000000..26b4245bd --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_audio_answer_selector_new.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_camera_selector.xml b/callkit/src/main/res/drawable/rc_voip_camera_selector.xml new file mode 100644 index 000000000..c86a84de9 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_camera_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_checkbox.xml b/callkit/src/main/res/drawable/rc_voip_checkbox.xml new file mode 100644 index 000000000..e907894d8 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_checkbox.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_dialog_bg.xml b/callkit/src/main/res/drawable/rc_voip_dialog_bg.xml new file mode 100644 index 000000000..d8d2088a6 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_dialog_bg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_disable_camera_selector.xml b/callkit/src/main/res/drawable/rc_voip_disable_camera_selector.xml new file mode 100644 index 000000000..c86a84de9 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_disable_camera_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_float_bg.xml b/callkit/src/main/res/drawable/rc_voip_float_bg.xml new file mode 100644 index 000000000..35f8824a2 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_float_bg.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_hangup_selector.xml b/callkit/src/main/res/drawable/rc_voip_hangup_selector.xml new file mode 100644 index 000000000..4a258ec0e --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_hangup_selector.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_item_selector.xml b/callkit/src/main/res/drawable/rc_voip_item_selector.xml new file mode 100644 index 000000000..1cfefb642 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_item_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_mute_selector.xml b/callkit/src/main/res/drawable/rc_voip_mute_selector.xml new file mode 100644 index 000000000..57d77398c --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_mute_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_speaker_selector.xml b/callkit/src/main/res/drawable/rc_voip_speaker_selector.xml new file mode 100644 index 000000000..677e66734 --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_speaker_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_vedio_answer_selector.xml b/callkit/src/main/res/drawable/rc_voip_vedio_answer_selector.xml new file mode 100644 index 000000000..3c43d864b --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_vedio_answer_selector.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/drawable/rc_voip_vedio_answer_selector_new.xml b/callkit/src/main/res/drawable/rc_voip_vedio_answer_selector_new.xml new file mode 100644 index 000000000..3c43d864b --- /dev/null +++ b/callkit/src/main/res/drawable/rc_voip_vedio_answer_selector_new.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/activity_call_select_member2.xml b/callkit/src/main/res/layout/activity_call_select_member2.xml new file mode 100644 index 000000000..0a4299426 --- /dev/null +++ b/callkit/src/main/res/layout/activity_call_select_member2.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/callkit_actionbar_option_text_layout.xml b/callkit/src/main/res/layout/callkit_actionbar_option_text_layout.xml new file mode 100644 index 000000000..664778b81 --- /dev/null +++ b/callkit/src/main/res/layout/callkit_actionbar_option_text_layout.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/callkit_conference_search_top_layout.xml b/callkit/src/main/res/layout/callkit_conference_search_top_layout.xml new file mode 100644 index 000000000..003f444c5 --- /dev/null +++ b/callkit/src/main/res/layout/callkit_conference_search_top_layout.xml @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/callkit_multivideo_gaussianblur.xml b/callkit/src/main/res/layout/callkit_multivideo_gaussianblur.xml new file mode 100644 index 000000000..b4d2e0883 --- /dev/null +++ b/callkit/src/main/res/layout/callkit_multivideo_gaussianblur.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/callkit/src/main/res/layout/callkit_rc_voip_activity_select_member.xml b/callkit/src/main/res/layout/callkit_rc_voip_activity_select_member.xml new file mode 100644 index 000000000..768ee55bd --- /dev/null +++ b/callkit/src/main/res/layout/callkit_rc_voip_activity_select_member.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/callkit_rc_voip_activity_select_member_layout.xml b/callkit/src/main/res/layout/callkit_rc_voip_activity_select_member_layout.xml new file mode 100644 index 000000000..99e304d62 --- /dev/null +++ b/callkit/src/main/res/layout/callkit_rc_voip_activity_select_member_layout.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/callkit_view_search_bar_layout.xml b/callkit/src/main/res/layout/callkit_view_search_bar_layout.xml new file mode 100644 index 000000000..07aecf8d7 --- /dev/null +++ b/callkit/src/main/res/layout/callkit_view_search_bar_layout.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_ac_muti_audio.xml b/callkit/src/main/res/layout/rc_voip_ac_muti_audio.xml new file mode 100644 index 000000000..d1e2924e6 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_ac_muti_audio.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_activity_select_member.xml b/callkit/src/main/res/layout/rc_voip_activity_select_member.xml new file mode 100644 index 000000000..f8ffaad4a --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_activity_select_member.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_activity_single_call.xml b/callkit/src/main/res/layout/rc_voip_activity_single_call.xml new file mode 100644 index 000000000..6fca718a9 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_activity_single_call.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_audio_call_user_info.xml b/callkit/src/main/res/layout/rc_voip_audio_call_user_info.xml new file mode 100644 index 000000000..175f75e26 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_audio_call_user_info.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_audio_call_user_info_incoming.xml b/callkit/src/main/res/layout/rc_voip_audio_call_user_info_incoming.xml new file mode 100644 index 000000000..cc5471472 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_audio_call_user_info_incoming.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_call_bottom_connected_button_layout.xml b/callkit/src/main/res/layout/rc_voip_call_bottom_connected_button_layout.xml new file mode 100644 index 000000000..728db6947 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_call_bottom_connected_button_layout.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_call_bottom_incoming_button_layout.xml b/callkit/src/main/res/layout/rc_voip_call_bottom_incoming_button_layout.xml new file mode 100644 index 000000000..d06097e3d --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_call_bottom_incoming_button_layout.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_call_user_info_incoming.xml b/callkit/src/main/res/layout/rc_voip_call_user_info_incoming.xml new file mode 100644 index 000000000..61d49b348 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_call_user_info_incoming.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_contact_container.xml b/callkit/src/main/res/layout/rc_voip_contact_container.xml new file mode 100644 index 000000000..79b523f33 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_contact_container.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_dialog_popup_prompt.xml b/callkit/src/main/res/layout/rc_voip_dialog_popup_prompt.xml new file mode 100644 index 000000000..b4b188690 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_dialog_popup_prompt.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_float_box.xml b/callkit/src/main/res/layout/rc_voip_float_box.xml new file mode 100644 index 000000000..83c510b3a --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_float_box.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_item_incoming_maudio.xml b/callkit/src/main/res/layout/rc_voip_item_incoming_maudio.xml new file mode 100644 index 000000000..6465cb9a8 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_item_incoming_maudio.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_item_outgoing_maudio.xml b/callkit/src/main/res/layout/rc_voip_item_outgoing_maudio.xml new file mode 100644 index 000000000..448305eac --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_item_outgoing_maudio.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_listitem_select_member.xml b/callkit/src/main/res/layout/rc_voip_listitem_select_member.xml new file mode 100644 index 000000000..f7ed8879e --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_listitem_select_member.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_msg_multi_call_end.xml b/callkit/src/main/res/layout/rc_voip_msg_multi_call_end.xml new file mode 100644 index 000000000..45183c1e3 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_msg_multi_call_end.xml @@ -0,0 +1,10 @@ + + + + diff --git a/callkit/src/main/res/layout/rc_voip_multi_video_call.xml b/callkit/src/main/res/layout/rc_voip_multi_video_call.xml new file mode 100644 index 000000000..9a07db6bd --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_multi_video_call.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view.xml b/callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view.xml new file mode 100644 index 000000000..f10dce656 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view_rtl.xml b/callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view_rtl.xml new file mode 100644 index 000000000..18939b8ec --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_multi_video_calling_bottom_view_rtl.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_multi_video_top_view.xml b/callkit/src/main/res/layout/rc_voip_multi_video_top_view.xml new file mode 100644 index 000000000..f24edb7ad --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_multi_video_top_view.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_observer_hint.xml b/callkit/src/main/res/layout/rc_voip_observer_hint.xml new file mode 100644 index 000000000..f218fa527 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_observer_hint.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_pop_menu.xml b/callkit/src/main/res/layout/rc_voip_pop_menu.xml new file mode 100644 index 000000000..361db191c --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_pop_menu.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/callkit/src/main/res/layout/rc_voip_user_info.xml b/callkit/src/main/res/layout/rc_voip_user_info.xml new file mode 100644 index 000000000..2675936b2 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_user_info.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_user_info_mutlaudio.xml b/callkit/src/main/res/layout/rc_voip_user_info_mutlaudio.xml new file mode 100644 index 000000000..100c71d35 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_user_info_mutlaudio.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_user_portrait.xml b/callkit/src/main/res/layout/rc_voip_user_portrait.xml new file mode 100644 index 000000000..8996b1506 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_user_portrait.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_video_call_user_info.xml b/callkit/src/main/res/layout/rc_voip_video_call_user_info.xml new file mode 100644 index 000000000..0cde00db2 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_video_call_user_info.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/layout/rc_voip_viewlet_remote_user.xml b/callkit/src/main/res/layout/rc_voip_viewlet_remote_user.xml new file mode 100644 index 000000000..dda915d21 --- /dev/null +++ b/callkit/src/main/res/layout/rc_voip_viewlet_remote_user.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/raw/voip_incoming_ring.mp3 b/callkit/src/main/res/raw/voip_incoming_ring.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..21472a705fab5be08a9f1d328334e286f6b0d78e GIT binary patch literal 432295 zcmeEtbx>SS*XCe@4KTQd3>uuloeTtbcNyH>ebC^+-2()7cZcAf;1(bxAwhzM!1DXP zcdPc>s;#Zst*zQW-e;=&-o7<`=bUrz)90L?Zh0vlWWY1k$G`2pMj9)Rid86Ut3U;(fOm;;0Wg3li=faPA%75eE7WlUX{%wJOTj1Xo__qcA zuPpHNN9}*xU(e3j=J`u_007c80GRXv2?_fdM9-k6rhfGdu4jmdh)6#}vUaan0m~s6jnKOaPohWOHNrMS zr4HpKMe=xMokQ)Bap7&W?D&q1ICj*$iP1!ATJR4dk3Gy;a<*MmBfEP%neVb+_SdhT z?LY5tZg!pod@pjIj($;#mN6@c+JwAxr53FwFS2D}8LQVFQz2~f_Nw05zUfhL*uL53 z47i8I=zcX1O=0X~IyZR~`-Stk%ewOGM)n=cnC%NJH1kHiniw3A8n^w;CYm|*+v>HQ z{t&ABPyh^!cZkIE#DswizkU6nf)~DfOLG?Z5`7Ru{3VA=)Gjk%f&dxp$pro_dJNeo z!9T|noEy*#&7<0<=CEYTPi_2;1Iq!2?MBhWe$1LdkpNkK_<`1-JUZQ3v9|K<+V`&a zSHQifZgc;;fF0l9XTbute^G0smGSw!V^$7{eH{{T^pE)4Pe

^(V^42a}qnizqke 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 z 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 literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/raw/voip_network_error_sound.wav b/callkit/src/main/res/raw/voip_network_error_sound.wav new file mode 100644 index 0000000000000000000000000000000000000000..5cb8fdfa6d276de5ad77bc555fc202bdfdf3a996 GIT binary patch literal 72082 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 V0jY1J#1NoKWdlU`UwQ)W{{VHfm0|z@ literal 0 HcmV?d00001 diff --git a/callkit/src/main/res/values-ar-rIL/strings.xml b/callkit/src/main/res/values-ar-rIL/strings.xml new file mode 100644 index 000000000..2450248dc --- /dev/null +++ b/callkit/src/main/res/values-ar-rIL/strings.xml @@ -0,0 +1,96 @@ + + + تم اختيار %d أشخاص + تأكيد + مكالمة فيديو + مكالمة صوتية + جاري الاتصال + جاري الاتصال... + الخط مشغول + مكالمة ملغية + تم الإلغاء + الشبكة غير متوفرة، يرجى التحقق من شبكتك + تم الإلغاء + " انتهت المكالمة" + بدء الاتصال + اختر الأعضاء + مكالمة صوتية جارية , حاول مرة اخرى + مكالمة فيديو جارية , حاول مرة اخرى + مكالمة صوتية في التقدم ، دعوة جديدة غير مسموح + " مكالمات الفيديو في التقدم ، مكالمات جديدة لا يسمح" + تم الرد على الأجهزة الأخرى . + + يدعوك إلى مكالمة صوتية + يدعوك إلى مكالمة فيديو + + يدعوك الى مكالمة فيديو + يدعوك إلى مكالمة صوتية + لديك دعوة مكالمة صوتية + لديك دعوة مكالمة فيديو + + + " انتهت المكالمة" + مكالمة ملغية + تم إلغاء المكالمة + " انتهت المكالمة" + مكالمة ملغية + تم إلغاء المكالمة + صامت + إنهاء المحادثة + قبول + كاميرا + مكبر صوت + اغلق الكاميرا + تشغيل الكاميرا + اعضاء + تم الإلغاء + رفض + لا يوجد إجابة + تم الإلغاء + رفض + لايوجد اجابة + المدة  + الخط مشغول + قد يكون المستخدم الآخر مشغول الآن , حاول مرة اخرى . + [مكالمة صوتية] + [مكالمة فيديو] + حول إلى مكالمة صوتية + المستخدم الآخر حول المكالمة الى مكالمة صوتية . + حول إلى مكالمة صوتية . + يرجى تفعيل خاصية النوافذ العائمة . + جاري تنفيذ المكالمة + مكالمة صوتية جارية , اضغط للاستمرار + مكالمة فيديو جارية , اضغط للاستمرار + Up to %d اعضاء + جاري الاتصال... + الشبكة غير مستقرة + اختر الأعضاء + خدمات الصوت والفيديو غير مفعله + تم إضافتها إلى القائمة السوداء + + اختر الأعضاء + بحث + تم إغلاق التطبيق، يرجى تفعيل تصريح عرض نوافذ منبثقة في الخلفية من صفحة الإعدادات" + + المكالمة الصوتية مرفوضة + مكالمة الفيديو مرفوضة + ارفع يدك للتحدث + حسناً + حسناً + الإلغاء + ميكروفون + كاميرا وميكروفون + مفتوح + إغلاق + يجب أن تنضم إلى الإجتماع كجمهور، استمر أو لا + يرجى رفع يدك للتحدث + Up to %d اعضاء + Up to %d اعضاء + الرجاء تعيين الأذونات ذات الصلة + تحميل اللوحة البيضاء … + شهادة صفحة الويب التي قمت بزيارتها غير صالحة, هل ترغب في متابعة زيارتك؟ + " الإتصال بالرسائل الفورية غير طبيعي الرجاء التحقق من الشبكة والمحاولة مرة أخرى" + لا توجد نتائج بحث + [تم إنهاء المكالمة] + الإلغاء + \ No newline at end of file diff --git a/callkit/src/main/res/values-en/colors.xml b/callkit/src/main/res/values-en/colors.xml new file mode 100644 index 000000000..298004b58 --- /dev/null +++ b/callkit/src/main/res/values-en/colors.xml @@ -0,0 +1,4 @@ + + + #72767B + \ No newline at end of file diff --git a/callkit/src/main/res/values-en/dimens.xml b/callkit/src/main/res/values-en/dimens.xml new file mode 100644 index 000000000..e6926c283 --- /dev/null +++ b/callkit/src/main/res/values-en/dimens.xml @@ -0,0 +1,8 @@ + + + 18sp + 90dp + 17dp + 17dp + 8dp + \ No newline at end of file diff --git a/callkit/src/main/res/values-en/rc_voipkit_string.xml b/callkit/src/main/res/values-en/rc_voipkit_string.xml new file mode 100644 index 000000000..f97a4e3b2 --- /dev/null +++ b/callkit/src/main/res/values-en/rc_voipkit_string.xml @@ -0,0 +1,97 @@ + + + %d members selected + Confirm + Video Call + Voice Call + Awaiting response... + Connecting + Busy line + No answer + Cancelled + Network is unavailable, please check your network + Interrupt + Call ended + Call started + Select Members + Voice call is on. Try again later. + Video call is on. Try again later. + A voice call is in progress. New calls are not allowed + A video call is in progress. New calls are not allowed + Other devices have been answered + + Invites you to voice call + Invites you to video call + + Invites you to video call + Invites you to voice call + You\'ve got a voice chat invitation + You\'ve got a video chat invitation + + + Call ended + Call No answer + Call Cancelled + Call ended + Call No answer + Call Cancelled + Mute + Hang up + Accept + Camera + Speaker + Turn off camera + Turn on camera + Members + Cancelled + Declined + No answer + Remote Cancelled + Remote Declined + Remote No answer + Duration  + Busy line + The other user may be busy now, Try again later. + [Voice Call] + [Video Call] + Switch to voice call + Other user switched to voice call. + Switched to voice call + Please enable floating windows + Call in progress + Tap to continue as voice call is on + Tap to continue as video call is on + Up to %d members + Connecting... + Network is unstable + Select Members + Audio and video services are turned off + Has been blacklisted by receiver + + Select Members + Search + Your system turned off \""Display pop-up windows while running in the background\"" permission, +Please turn it on in the application permission management page of \""Settings\"" + + Voice call rejected + Video call rejected + Please set the relevant permissions + Whiteboard loading... + The web page certificate you visited is invalid, Do you want to continue your visit? + IM connection is abnormal. Please check the network and try again + no search results + + [Call ended] + Raise hand to speak + whiteboard + ok + cancel + microphone + camera and mic + open + close + Need to join the meeting as an audience, continue or not + You are an observer, please raise your hand if you wish to speak + Up to %d members + Up to %d members + diff --git a/callkit/src/main/res/values/callkit_callUserGridViewStyle.xml b/callkit/src/main/res/values/callkit_callUserGridViewStyle.xml new file mode 100644 index 000000000..7d650a398 --- /dev/null +++ b/callkit/src/main/res/values/callkit_callUserGridViewStyle.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/values/colors.xml b/callkit/src/main/res/values/colors.xml new file mode 100644 index 000000000..7930705ad --- /dev/null +++ b/callkit/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #72767B + #999999 + + \ No newline at end of file diff --git a/callkit/src/main/res/values/dimens.xml b/callkit/src/main/res/values/dimens.xml new file mode 100644 index 000000000..00d7fa941 --- /dev/null +++ b/callkit/src/main/res/values/dimens.xml @@ -0,0 +1,16 @@ + + + 18sp + 90dp + 17dp + + 12dp + 13dp + 14dp + 40dp + 48dp + 60dp + 80dp + 17dp + 8dp + \ No newline at end of file diff --git a/callkit/src/main/res/values/rc_voipkit_color.xml b/callkit/src/main/res/values/rc_voipkit_color.xml new file mode 100644 index 000000000..0ba33baa4 --- /dev/null +++ b/callkit/src/main/res/values/rc_voipkit_color.xml @@ -0,0 +1,38 @@ + + + #000000 + + #141C24 + #1f4a76 + #FFFFFF + #0099ff + #33000000 + #00000000 + #262626 + #B3000000 + #E5E5E5 + #3A91F3 + #E6141C24 + + #FAFAFA + #e5e5e5 + #DFDFDF + #B2B2B2 + #FAFAFA + #262626 + #3A91F3 + + #FAFAFA + #262626 + + #3A91F3 + #7CA1C9 + #939393 + #262626 + #939393 + #3a91f3 + #000000 + #803A91F3 + #939393 + #3F81BC + \ No newline at end of file diff --git a/callkit/src/main/res/values/rc_voipkit_ids.xml b/callkit/src/main/res/values/rc_voipkit_ids.xml new file mode 100644 index 000000000..41bbeb495 --- /dev/null +++ b/callkit/src/main/res/values/rc_voipkit_ids.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/values/rc_voipkit_string.xml b/callkit/src/main/res/values/rc_voipkit_string.xml new file mode 100644 index 000000000..74d9a5aca --- /dev/null +++ b/callkit/src/main/res/values/rc_voipkit_string.xml @@ -0,0 +1,97 @@ + + + 已选择 %d 人 + 确定 + 视频通话 + 语音通话 + 等待对方接受邀请... + 连接中 + 对方忙 + 通话未接听 + 挂断 + 当前网络不可用,请检查你的网络设置 + 异常挂断 + 通话已结束 + 开始通话 + 添加成员 + 正在进行语音通话,请稍后再试 + 正在进行视频通话,请稍后再试 + 正在进行语音通话,不允许发起新的通话 + 正在进行视频通话,不允许发起新的通话 + 其他设备已处理 + 用户被开发者后台封禁 + + 邀请您进行语音通话... + 邀请您进行视频通话... + 邀请您进行视频通话 + 邀请您进行语音通话 + 您有一个语音通话邀请 + 您有一个视频通话邀请 + 通话已结束 + 通话未接听 + 已取消通话 + 通话已结束 + 通话未接听 + 已取消通话 + 静音 + 挂断 + 接听 + 摄像头 + 免提 + 关闭摄像头 + 开启摄像头 + 群聊成员 + 已取消 + 已拒绝 + 未接听 + 对方已取消 + 对方已拒绝 + 对方未接听 + 通话时长  + 对方忙 + 对方忙,请稍后再试 + [语音通话] + [视频通话] + 语音通话 + 对方已切换到语音通话 + 已切换到语音通话 + 请打开悬浮窗权限 + 通话中... + 语音通话中,轻击以继续 + 视频通话中,轻击以继续 + 您最多只能选择%d人 + 举手发言 + 添加成员 + 白板 + 确认 + 取消 + 主持人邀请您参与讨论 是否接受? + 主持人请求您%1$s%2$s 是否接受? + 麦克风 + 摄像头和麦克风 + 打开 + 关闭 + 为了保障会议流畅进行,需要您以观众模式加入,是否继续? + 您的身份为观察者,如需发言请举手 + 您最多只能选择%d人 + 您最多只能选择%d人 + 网络质量不佳 + 连接中... + 音视频服务已关闭 + 已被对方加入黑名单 + + 添加成员 + 搜索 + 您的系统当前关闭了【后台启动界面】权限,请到系统设置的应用权限管理页面开启。 + + 语音通话已拒绝 + 视频通话已拒绝 + + 请设置相关权限 + 白板加载中... + 您访问的网页证书无效,是否继续访问? + IM连接异常,请检查网络后重试 + 无搜索结果 + + [结束通话] + \ No newline at end of file diff --git a/callkit/src/main/res/values/rc_voipkit_style.xml b/callkit/src/main/res/values/rc_voipkit_style.xml new file mode 100644 index 000000000..34e966e0d --- /dev/null +++ b/callkit/src/main/res/values/rc_voipkit_style.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/callkit/src/main/res/values/strings.xml b/callkit/src/main/res/values/strings.xml new file mode 100644 index 000000000..f33ea0a51 --- /dev/null +++ b/callkit/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Cancel + diff --git a/common/src/main/java/com/yunbao/common/activity/MyWalletActivity.java b/common/src/main/java/com/yunbao/common/activity/MyWalletActivity.java index 522d04cc6..a58c5bd2b 100644 --- a/common/src/main/java/com/yunbao/common/activity/MyWalletActivity.java +++ b/common/src/main/java/com/yunbao/common/activity/MyWalletActivity.java @@ -66,7 +66,11 @@ public class MyWalletActivity extends AbsActivity { GoogleBillingUtilNew.getInstance().initGooglePay(mContext); vp_content = (ViewPager) findViewById(R.id.vp_content); TextView rView = (TextView) findViewById(R.id.rView); - findViewById(R.id.redPacketMain).setVisibility(View.VISIBLE); + if(getPackageName().equals("com.pdlive.shayu")) { + findViewById(R.id.redPacketMain).setVisibility(View.VISIBLE); + }else{ + findViewById(R.id.redPacketMain).setVisibility(View.GONE); + } findViewById(R.id.redPacketMain).setOnClickListener(v -> { RouteUtil.forwardRedPacketList(); }); diff --git a/settings.gradle b/settings.gradle index 64dd6d751..bbd306ed2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,3 +7,4 @@ include ':pluginsForAnchor' include ':OneToOne' include ':ViewPager2Delegate' include ':TabLayout' +include ':callkit'