Skip to content

Commit

Permalink
Merge pull request #25 from voximplant/voximplant_sdk_37.0.0
Browse files Browse the repository at this point in the history
Voximplant SDK 37.0.0
  • Loading branch information
jedi1150 authored Sep 29, 2023
2 parents e5fded7 + c760524 commit d187e25
Show file tree
Hide file tree
Showing 45 changed files with 1,476 additions and 1,476 deletions.
21 changes: 9 additions & 12 deletions audiocall/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ plugins {
}

android {
compileSdkVersion 31
compileSdk 33

defaultConfig {
applicationId "com.voximplant.demos.kotlin.audio_call"
minSdkVersion 26
targetSdkVersion 31
minSdk 26
targetSdk 33
multiDexEnabled true
versionCode 1
versionName "1.3.10"
versionName "1.4.0"
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand All @@ -34,22 +34,23 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}
buildFeatures {
viewBinding true
dataBinding true
}
namespace 'com.voximplant.demos.kotlin.audio_call'
}

dependencies {
implementation project(':shared')
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.core:core-ktx:$core_ctx_version"
implementation "androidx.constraintlayout:constraintlayout:$constraintLayout_version"
Expand All @@ -72,8 +73,4 @@ dependencies {
implementation "androidx.multidex:multidex:$multidex_version"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_ktx_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_ktx_version"

testImplementation "junit:junit:$junit_version"
androidTestImplementation "androidx.test.ext:junit:$juint_ext_version"
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_core_version"
}
16 changes: 12 additions & 4 deletions audiocall/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.voximplant.demos.kotlin.audio_call">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<application
android:name=".AudioCallApplication"
android:allowBackup="false"
android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
Expand Down Expand Up @@ -75,6 +73,16 @@
</intent-filter>
</service>

<receiver
android:name=".services.AudioCallBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="action_answer_incoming_call" />
<action android:name="action_decline_incoming_call" />
<action android:name="action_hangup_ongoing_call" />
</intent-filter>
</receiver>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.voximplant.demos.kotlin.audio_call.fileprovider"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ class AudioCallApplication : MultiDexApplication(), LifecycleObserver {
ClientConfig().also { it.packageName = packageName },
)

val requiredPermissions = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.MANAGE_OWN_CALLS)
} else {
arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.MANAGE_OWN_CALLS, Manifest.permission.BLUETOOTH_CONNECT)
}
val requiredPermissions =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.MANAGE_OWN_CALLS, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.POST_NOTIFICATIONS)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.MANAGE_OWN_CALLS, Manifest.permission.BLUETOOTH_CONNECT)
} else {
arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.MANAGE_OWN_CALLS)
}

permissionsHelper = PermissionsHelper(applicationContext, requiredPermissions)
telecomManager = TelecomManager(applicationContext).apply { registerAccount() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
import android.telecom.Connection
import android.telecom.DisconnectCause
import android.util.Log
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.startActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
Expand Down Expand Up @@ -55,7 +55,7 @@ class AudioCallManager(
private val _callDuration = MutableLiveData(0L)
val callDuration: LiveData<Long>
get() = _callDuration
val callBroadcastReceiver: BroadcastReceiver = AudioCallBroadcastReceiver()
private val callBroadcastReceiver: BroadcastReceiver = AudioCallBroadcastReceiver()
private val callSettings: CallSettings
get() = CallSettings().apply { videoFlags = VideoFlags(false, false) }

Expand Down Expand Up @@ -404,7 +404,7 @@ class AudioCallManager(
val filter = IntentFilter().apply {
addAction(ACTION_HANGUP_ONGOING_CALL)
}
appContext.registerReceiver(callBroadcastReceiver, filter)
ContextCompat.registerReceiver(appContext, callBroadcastReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED)
notificationHelper.createOngoingCallNotification(
appContext,
endpointDisplayName ?: endpointUsername,
Expand Down Expand Up @@ -447,7 +447,7 @@ class AudioCallManager(
addAction(ACTION_ANSWER_INCOMING_CALL)
addAction(ACTION_DECLINE_INCOMING_CALL)
}
appContext.registerReceiver(callBroadcastReceiver, filter)
ContextCompat.registerReceiver(appContext, callBroadcastReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED)
notificationHelper.showIncomingCallNotification(
appContext,
intent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class CallActivity : AppCompatActivity() {
binding = ActivityCallBinding.inflate(layoutInflater)
setContentView(binding.root)

val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
navController.setGraph(R.navigation.nav_call_graph, intent.extras)
when {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,32 +60,32 @@ class CallFailedFragment : Fragment() {
false
}

viewModel.showProgress.observe(viewLifecycleOwner, { textID ->
showProgressHUD(resources.getString(textID))
})
viewModel.showProgress.observe(viewLifecycleOwner) { stringId ->
showProgressHUD(resources.getString(stringId))
}

viewModel.hideProgress.observe(viewLifecycleOwner, {
viewModel.hideProgress.observe(viewLifecycleOwner) {
hideProgressHUD()
})
}

viewModel.showStringSnackbar.observe(viewLifecycleOwner, { value ->
Snackbar.make(view, value, Snackbar.LENGTH_LONG).show()
})
viewModel.showStringSnackbar.observe(viewLifecycleOwner) { text ->
Snackbar.make(view, text, Snackbar.LENGTH_LONG).show()
}

viewModel.showIntSnackbar.observe(viewLifecycleOwner, { value ->
Snackbar.make(view, getString(value), Snackbar.LENGTH_LONG).show()
})
viewModel.showIntSnackbar.observe(viewLifecycleOwner) { stringId ->
Snackbar.make(view, getString(stringId), Snackbar.LENGTH_LONG).show()
}

viewModel.moveToCall.observe(viewLifecycleOwner, {
viewModel.moveToCall.observe(viewLifecycleOwner) {
findNavController().navigate(
R.id.action_callFailedFragment_to_callFragment,
bundleOf(IS_OUTGOING_CALL to true),
)
})
}

viewModel.finishActivity.observe(viewLifecycleOwner, {
viewModel.finishActivity.observe(viewLifecycleOwner) {
activity?.finish()
})
}
}

private fun animate(view: View, animator: Animator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,53 +57,35 @@ class IncomingCallFragment : Fragment() {
}

permissionsHelper.allPermissionsGranted = { viewModel.answer() }
permissionsHelper.permissionDenied =
{ _, openAppSettings ->
Snackbar.make(
binding.root,
requireContext().getString(R.string.permission_mic_to_call),
Snackbar.LENGTH_LONG
)
.setAction(requireContext().getString(R.string.settings)) { openAppSettings() }
.show()
}
permissionsHelper.permissionDenied = { _, openAppSettings ->
Snackbar.make(binding.root, requireContext().getString(R.string.permission_mic_to_call), Snackbar.LENGTH_LONG).setAction(requireContext().getString(R.string.settings)) { openAppSettings() }.show()
}

binding.answerButton.setOnClickListener {
if (permissionsHelper.allPermissionsGranted()) {
viewModel.answer()
} else {
ActivityCompat.requestPermissions(
requireActivity(),
permissionsHelper.requiredPermissions,
1
)
ActivityCompat.requestPermissions(requireActivity(), permissionsHelper.requiredPermissions, 1)
}
}

binding.declineButton.setOnClickListener {
viewModel.decline()
}

viewModel.moveToCall.observe(viewLifecycleOwner, {
findNavController().navigate(
R.id.action_incomingCallFragment_to_callFragment,
arguments,
)
})
viewModel.moveToCall.observe(viewLifecycleOwner) {
findNavController().navigate(R.id.action_incomingCallFragment_to_callFragment, arguments)
}

viewModel.finishActivity.observe(viewLifecycleOwner, {
viewModel.finishActivity.observe(viewLifecycleOwner) {
activity?.finish()
})
}

if (arguments?.getBoolean(ACTION_ANSWER_INCOMING_CALL, false) == true) {
if (permissionsHelper.allPermissionsGranted()) {
viewModel.answer()
} else {
ActivityCompat.requestPermissions(
requireActivity(),
permissionsHelper.requiredPermissions,
1
)
ActivityCompat.requestPermissions(requireActivity(), permissionsHelper.requiredPermissions, 1)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import com.voximplant.demos.kotlin.audio_call.R
import com.voximplant.demos.kotlin.audio_call.databinding.FragmentOngoingCallBinding
import com.voximplant.demos.kotlin.utils.*
import com.voximplant.sdk.hardware.AudioDevice
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

class OngoingCallFragment : Fragment() {
Expand All @@ -51,10 +50,10 @@ class OngoingCallFragment : Fragment() {
val reducer = AnimatorInflater.loadAnimator(context, R.animator.reduce_size)
val increaser = AnimatorInflater.loadAnimator(context, R.animator.regain_size)

viewModel.onHideKeypadPressed.observe(viewLifecycleOwner, {
viewModel.onHideKeypadPressed.observe(viewLifecycleOwner) {
shouldClearTextView = true
showKeypad(false)
})
}

lifecycleScope.launch {
viewModel.selectedAudioDevice.collect { audioDevice ->
Expand Down Expand Up @@ -116,30 +115,30 @@ class OngoingCallFragment : Fragment() {
showKeypad(false)
}

viewModel.charDTMF.observe(viewLifecycleOwner, { symbol ->
viewModel.charDTMF.observe(viewLifecycleOwner) { symbol ->
if (shouldClearTextView) {
binding.callerNameTextView.text = symbol
} else {
binding.callerNameTextView.text = if (binding.callerNameTextView.text.length < 15) binding.callerNameTextView.text.toString() + symbol else binding.callerNameTextView.text.toString().substring(1) + symbol
}
shouldClearTextView = false
})
}

viewModel.enableButtons.observe(viewLifecycleOwner, { enabled ->
viewModel.enableButtons.observe(viewLifecycleOwner) { enabled ->
val alpha = if (enabled) 1.0 else 0.25
binding.holdButton.alpha = alpha.toFloat()
binding.keypadButton.alpha = alpha.toFloat()
binding.holdButton.isEnabled = enabled
binding.keypadButton.isEnabled = enabled
})
}

viewModel.enableKeypad.observe(viewLifecycleOwner, { enabled ->
viewModel.enableKeypad.observe(viewLifecycleOwner) { enabled ->
val alpha = if (enabled) 1.0 else 0.25
binding.keypadButton.alpha = alpha.toFloat()
binding.keypadButton.isEnabled = enabled
})
}

viewModel.muted.observe(viewLifecycleOwner, { muted ->
viewModel.muted.observe(viewLifecycleOwner) { muted ->
if (muted) {
binding.muteButton.setCardBackgroundColor(
ContextCompat.getColor(
Expand All @@ -157,46 +156,39 @@ class OngoingCallFragment : Fragment() {
binding.muteButtonIcon.setImageResource(R.drawable.ic_micon)
binding.muteValue = getString(R.string.mute)
}
})
}

viewModel.onHold.observe(viewLifecycleOwner, { onHold ->
viewModel.onHold.observe(viewLifecycleOwner) { onHold ->
binding.holdButton.isEnabled = true
if (onHold) {
binding.holdButton.setCardBackgroundColor(
ContextCompat.getColor(
requireContext(), R.color.colorRed
)
)
binding.holdButton.setCardBackgroundColor(ContextCompat.getColor(requireContext(), R.color.colorRed))
binding.holdValue = getString(R.string.resume)
} else {
binding.holdButton.setCardBackgroundColor(
ContextCompat.getColor(
requireContext(), R.color.call_option_default_back
)
)
binding.holdButton.setCardBackgroundColor(ContextCompat.getColor(requireContext(), R.color.call_option_default_back))
binding.holdValue = getString(R.string.hold)
}
})
}

viewModel.finishActivity.observe(viewLifecycleOwner, {
viewModel.finishActivity.observe(viewLifecycleOwner) {
activity?.finish()
})
}

viewModel.moveToCallFailed.observe(viewLifecycleOwner, { reason ->
viewModel.moveToCallFailed.observe(viewLifecycleOwner) { reason ->
findNavController().navigate(
R.id.action_callFragment_to_callFailedFragment, bundleOf(
R.id.action_callFragment_to_callFailedFragment,
bundleOf(
ENDPOINT_USERNAME to viewModel.userName.value,
ENDPOINT_DISPLAY_NAME to viewModel.displayName.value,
FAIL_REASON to reason,
)
),
)
})
}

arguments?.let {
arguments?.run {
viewModel.onCreateWithCall(
it.getBoolean(IS_ONGOING_CALL, false),
it.getBoolean(IS_OUTGOING_CALL, false),
it.getBoolean(IS_INCOMING_CALL, false),
isOngoing = getBoolean(IS_ONGOING_CALL, false),
isOutgoing = getBoolean(IS_OUTGOING_CALL, false),
isIncoming = getBoolean(IS_INCOMING_CALL, false),
)
}

Expand Down
Loading

0 comments on commit d187e25

Please sign in to comment.