add UI to switch audio output in call

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2022-01-31 16:01:15 +01:00
parent 953528d3c9
commit 9b889d232f
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
7 changed files with 268 additions and 13 deletions

View File

@ -32,6 +32,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.media.AudioAttributes; import android.media.AudioAttributes;
import android.media.MediaPlayer; import android.media.MediaPlayer;
@ -82,6 +83,8 @@ import com.nextcloud.talk.models.json.signaling.Signaling;
import com.nextcloud.talk.models.json.signaling.SignalingOverall; import com.nextcloud.talk.models.json.signaling.SignalingOverall;
import com.nextcloud.talk.models.json.signaling.settings.IceServer; import com.nextcloud.talk.models.json.signaling.settings.IceServer;
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall; import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
import com.nextcloud.talk.ui.dialog.AudioOutputDialog;
import com.nextcloud.talk.ui.dialog.ScopeDialog;
import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.NotificationUtils; import com.nextcloud.talk.utils.NotificationUtils;
@ -142,6 +145,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.drawable.DrawableCompat;
import autodagger.AutoInjector; import autodagger.AutoInjector;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.Observer; import io.reactivex.Observer;
@ -327,16 +331,20 @@ public class CallActivity extends CallBaseActivity {
private void initClickListeners() { private void initClickListeners() {
binding.pictureInPictureButton.setOnClickListener(l -> enterPipMode()); binding.pictureInPictureButton.setOnClickListener(l -> enterPipMode());
binding.speakerButton.setOnClickListener(l -> { binding.audioOutputButton.setOnClickListener(v -> new AudioOutputDialog(
if (audioManager != null) { this
audioManager.toggleUseSpeakerphone(); ).show());
if (audioManager.isSpeakerphoneAutoOn()) {
binding.speakerButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_up_white_24dp); // binding.audioOutputButton.setOnClickListener(l -> {
} else { // if (audioManager != null) {
binding.speakerButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_mute_white_24dp); // audioManager.toggleUseSpeakerphone();
} // if (audioManager.isSpeakerphoneAutoOn()) {
} // binding.audioOutputButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_up_white_24dp);
}); // } else {
// binding.audioOutputButton.getHierarchy().setPlaceholderImage(R.drawable.ic_volume_mute_white_24dp);
// }
// }
// });
binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick()); binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick());
binding.microphoneButton.setOnLongClickListener(l -> { binding.microphoneButton.setOnLongClickListener(l -> {
@ -373,6 +381,11 @@ public class CallActivity extends CallBaseActivity {
}); });
} }
public void setAudioOutputIcon(Drawable drawable){
binding.audioOutputButton.getHierarchy().setPlaceholderImage(drawable);
DrawableCompat.setTint(drawable, Color.WHITE);
}
private void createCameraEnumerator() { private void createCameraEnumerator() {
boolean camera2EnumeratorIsSupported = false; boolean camera2EnumeratorIsSupported = false;
try { try {
@ -496,7 +509,7 @@ public class CallActivity extends CallBaseActivity {
} }
if (isVoiceOnlyCall) { if (isVoiceOnlyCall) {
binding.speakerButton.setVisibility(View.VISIBLE); binding.audioOutputButton.setVisibility(View.VISIBLE);
binding.switchSelfVideoButton.setVisibility(View.GONE); binding.switchSelfVideoButton.setVisibility(View.GONE);
binding.cameraButton.setVisibility(View.GONE); binding.cameraButton.setVisibility(View.GONE);
binding.selfVideoRenderer.setVisibility(View.GONE); binding.selfVideoRenderer.setVisibility(View.GONE);
@ -513,7 +526,7 @@ public class CallActivity extends CallBaseActivity {
params.setMargins(0, 0, 0, 0); params.setMargins(0, 0, 0, 0);
binding.gridview.setLayoutParams(params); binding.gridview.setLayoutParams(params);
binding.speakerButton.setVisibility(View.GONE); binding.audioOutputButton.setVisibility(View.GONE);
if (cameraEnumerator.getDeviceNames().length < 2) { if (cameraEnumerator.getDeviceNames().length < 2) {
binding.switchSelfVideoButton.setVisibility(View.GONE); binding.switchSelfVideoButton.setVisibility(View.GONE);
} }

View File

@ -0,0 +1,77 @@
/*
* Nextcloud Talk application
*
* @author Marcel Hibbe
* @author Andy Scherzinger
* Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
* Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.ui.dialog
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.CallActivity
import com.nextcloud.talk.databinding.DialogAudioOutputBinding
class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(callActivity) {
private lateinit var dialogAudioOutputBinding: DialogAudioOutputBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dialogAudioOutputBinding = DialogAudioOutputBinding.inflate(layoutInflater)
setContentView(dialogAudioOutputBinding.root)
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
dialogAudioOutputBinding.audioOutputBluetooth.setOnClickListener {
Log.d(TAG, "bluetooth button clicked")
callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputBluetoothIcon.drawable)
dismiss()
}
dialogAudioOutputBinding.audioOutputSpeaker.setOnClickListener {
Log.d(TAG, "speaker button clicked")
callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputSpeakerIcon.drawable)
dismiss()
}
dialogAudioOutputBinding.audioOutputEarspeaker.setOnClickListener {
Log.d(TAG, "earspeaker button clicked")
callActivity.setAudioOutputIcon(dialogAudioOutputBinding.audioOutputEarspeakerIcon.drawable)
dismiss()
}
}
override fun onStart() {
super.onStart()
val bottomSheet = findViewById<View>(R.id.design_bottom_sheet)
val behavior = BottomSheetBehavior.from(bottomSheet as View)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
companion object {
private const val TAG = "AudioOutputDialog"
}
}

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M14.24,12.01l2.32,2.32c0.28,-0.72 0.44,-1.51 0.44,-2.33 0,-0.82 -0.16,-1.59 -0.43,-2.31l-2.33,2.32zM19.53,6.71l-1.26,1.26c0.63,1.21 0.98,2.57 0.98,4.02s-0.36,2.82 -0.98,4.02l1.2,1.2c0.97,-1.54 1.54,-3.36 1.54,-5.31 -0.01,-1.89 -0.55,-3.67 -1.48,-5.19zM15.71,7.71L10,2L9,2v7.59L4.41,5 3,6.41 8.59,12 3,17.59 4.41,19 9,14.41L9,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM11,5.83l1.88,1.88L11,9.59L11,5.83zM12.88,16.29L11,18.17v-3.76l1.88,1.88z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57 -0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1L4,3c-0.55,0 -1,0.45 -1,1 0,9.39 7.61,17 17,17 0.55,0 1,-0.45 1,-1v-3.5c0,-0.55 -0.45,-1 -1,-1zM19,12h2c0,-4.97 -4.03,-9 -9,-9v2c3.87,0 7,3.13 7,7zM15,12h2c0,-2.76 -2.24,-5 -5,-5v2c1.66,0 3,1.34 3,3z"/>
</vector>

View File

@ -153,7 +153,7 @@
app:roundAsCircle="true" /> app:roundAsCircle="true" />
<com.facebook.drawee.view.SimpleDraweeView <com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/speakerButton" android:id="@+id/audioOutputButton"
android:layout_width="60dp" android:layout_width="60dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud Talk application
~
~ @author Marcel Hibbe
~ @author Andy Scherzinger
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
~ Copyright (C) 2021 Marcel Hibbe <marcel.hibbe@nextcloud.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#121212"
android:orientation="vertical"
android:paddingBottom="@dimen/standard_padding">
<TextView
android:id="@+id/upload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/standard_padding"
android:text="@string/audio_output_dialog_headline"
android:textAlignment="viewStart"
android:textColor="#99ffffff"
android:textSize="@dimen/bottom_sheet_text_size" />
<LinearLayout
android:id="@+id/audio_output_bluetooth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingLeft="@dimen/standard_padding"
android:paddingTop="@dimen/standard_half_padding"
android:paddingRight="@dimen/standard_padding"
android:paddingBottom="@dimen/standard_half_padding"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/audio_output_bluetooth_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_baseline_bluetooth_audio_24"
app:tint="@color/colorPrimary" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/audio_output_bluetooth_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="@dimen/standard_margin"
android:text="@string/audio_output_bluetooth"
android:textAlignment="viewStart"
android:textColor="#99ffffff"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/audio_output_speaker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingLeft="@dimen/standard_padding"
android:paddingTop="@dimen/standard_half_padding"
android:paddingRight="@dimen/standard_padding"
android:paddingBottom="@dimen/standard_half_padding"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/audio_output_speaker_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_volume_up_white_24dp"
app:tint="@color/colorPrimary" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/audio_output_speaker_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="@dimen/standard_margin"
android:text="@string/audio_output_speaker"
android:textAlignment="viewStart"
android:textColor="#99ffffff"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/audio_output_earspeaker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingLeft="@dimen/standard_padding"
android:paddingTop="@dimen/standard_half_padding"
android:paddingRight="@dimen/standard_padding"
android:paddingBottom="@dimen/standard_half_padding"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/audio_output_earspeaker_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_baseline_phone_in_talk_24"
app:tint="@color/colorPrimary" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/audio_output_earspeaker_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="@dimen/standard_margin"
android:text="@string/audio_output_phone"
android:textAlignment="viewStart"
android:textColor="#99ffffff"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
</LinearLayout>

View File

@ -494,5 +494,9 @@
<string name="take_photo_send">Send</string> <string name="take_photo_send">Send</string>
<string name="take_photo_error_deleting_picture">Error taking picture</string> <string name="take_photo_error_deleting_picture">Error taking picture</string>
<string name="take_photo_permission">Taking a photo is not possible without permissions</string> <string name="take_photo_permission">Taking a photo is not possible without permissions</string>
<string name="audio_output_bluetooth">Bluetooth</string>
<string name="audio_output_speaker">Speaker</string>
<string name="audio_output_phone">Phone</string>
<string name="audio_output_dialog_headline">Audio output</string>
</resources> </resources>