diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 401fae57..25956ffc 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -8,6 +8,7 @@
+
+ Log.d(TAG, "onRequestPermissionsResult: Microphone foreground permission granted: $granted");
+ });
logEventPermission("Microphone", true)
} else {
Log.d(TAG, "Microphone permission not granted")
@@ -281,6 +286,14 @@ class TwilioVoicePlugin : FlutterPlugin, MethodCallHandler, EventChannel.StreamH
Log.d(TAG, "Call Phone permission not granted")
logEventPermission("Call Phone State", false)
}
+ } else if (requestCode == REQUEST_CODE_MICROPHONE_FOREGROUND) {
+ if (permissions.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ Log.d(TAG, "Microphone foreground permission granted")
+ logEventPermission("Microphone", true)
+ } else {
+ Log.d(TAG, "Microphone foreground permission not granted")
+ logEventPermission("Microphone", false)
+ }
}
return true
}
@@ -1435,6 +1448,23 @@ class TwilioVoicePlugin : FlutterPlugin, MethodCallHandler, EventChannel.StreamH
)
}
+ /// Request permission for microphone on Android 14 and higher.
+ /// Source: https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE_MICROPHONE
+ private fun requestPermissionForMicrophoneForeground(onPermissionResult: (Boolean) -> Unit) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ Log.d(TAG, "requestPermissionForMicrophoneForeground: Microphone foreground permission automatically requested.");
+ return requestPermissionOrShowRationale(
+ "Microphone Foreground",
+ "Microphone Foreground permission is required to make or receive phone calls on Android 14 and higher.",
+ Manifest.permission.FOREGROUND_SERVICE_MICROPHONE,
+ REQUEST_CODE_MICROPHONE_FOREGROUND,
+ onPermissionResult
+ )
+ } else {
+ Log.d(TAG, "requestPermissionForMicrophoneForeground: Microphone foreground permission skipped.");
+ }
+ }
+
private fun requestPermissionForPhoneState(onPermissionResult: (Boolean) -> Unit) {
return requestPermissionOrShowRationale(
"Read Phone State",