diff --git a/dialer/android/app/src/main/AndroidManifest.xml b/dialer/android/app/src/main/AndroidManifest.xml
index fcaf71f..9a9247e 100644
--- a/dialer/android/app/src/main/AndroidManifest.xml
+++ b/dialer/android/app/src/main/AndroidManifest.xml
@@ -12,6 +12,12 @@
+
+
+
+
+
+
{
Log.d(TAG, "Received permissionsGranted from Flutter")
checkAndRequestDefaultDialer()
+ checkAndRequestVoicemailPermissions() // Add this line
result.success(true)
}
"makeGsmCall" -> {
@@ -95,6 +97,9 @@ class MainActivity : FlutterActivity() {
result.notImplemented()
}
}
+
+ MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "voicemail_service")
+ .setMethodCallHandler(VoicemailService(this))
}
private fun checkAndRequestDefaultDialer() {
@@ -129,6 +134,27 @@ class MainActivity : FlutterActivity() {
}
}
+ private fun checkAndRequestVoicemailPermissions() {
+ Log.d(TAG, "Checking voicemail permissions")
+
+ val permissions = arrayOf(
+ Manifest.permission.READ_VOICEMAIL,
+ Manifest.permission.WRITE_VOICEMAIL,
+ Manifest.permission.ADD_VOICEMAIL // Added this permission
+ )
+
+ val permissionsToRequest = permissions.filter {
+ ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
+ }.toTypedArray()
+
+ if (permissionsToRequest.isNotEmpty()) {
+ Log.d(TAG, "Requesting voicemail permissions: ${permissionsToRequest.joinToString()}")
+ requestPermissions(permissionsToRequest, 105) // Use a unique code
+ } else {
+ Log.d(TAG, "All voicemail permissions already granted")
+ }
+ }
+
private fun launchDefaultAppsSettings() {
val settingsIntent = Intent(android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
startActivity(settingsIntent)
diff --git a/dialer/android/app/src/main/kotlin/com/icing/dialer/services/VoicemailService.kt b/dialer/android/app/src/main/kotlin/com/icing/dialer/services/VoicemailService.kt
new file mode 100644
index 0000000..84ad585
--- /dev/null
+++ b/dialer/android/app/src/main/kotlin/com/icing/dialer/services/VoicemailService.kt
@@ -0,0 +1,189 @@
+package com.icing.dialer.services
+
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageManager
+import android.database.Cursor
+import android.net.Uri
+import android.os.Build
+import android.provider.VoicemailContract
+import android.telecom.TelecomManager
+import android.util.Log
+import androidx.core.content.ContextCompat
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import java.io.File
+import java.io.FileOutputStream
+
+class VoicemailService(private val context: Context) : MethodChannel.MethodCallHandler {
+ companion object {
+ private const val TAG = "VoicemailService"
+ }
+
+ override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
+ when (call.method) {
+ "getVoicemails" -> {
+ try {
+ Log.d(TAG, "Getting voicemails...")
+
+ // Check if app is default dialer
+ if (!isDefaultDialer()) {
+ Log.e(TAG, "App is not the default dialer, cannot access voicemails")
+ result.error("NOT_DEFAULT_DIALER", "App must be set as default dialer to access voicemails", null)
+ return
+ }
+
+ // Check permissions
+ if (!hasVoicemailPermissions()) {
+ Log.e(TAG, "Missing voicemail permissions")
+ result.error("MISSING_PERMISSIONS", "App doesn't have required voicemail permissions", null)
+ return
+ }
+
+ val voicemails = getVoicemails()
+ Log.d(TAG, "Found ${voicemails.size} voicemails")
+ result.success(voicemails)
+ } catch (e: Exception) {
+ Log.e(TAG, "Error getting voicemails", e)
+ result.error("VOICEMAIL_ERROR", e.message, null)
+ }
+ }
+ "markVoicemailAsRead" -> {
+ try {
+ val id = call.argument("id")
+ val isRead = call.argument("isRead") ?: true
+ if (id != null) {
+ val success = markVoicemailAsRead(id, isRead)
+ result.success(success)
+ } else {
+ result.error("INVALID_ARGUMENTS", "Missing voicemail id", null)
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Error marking voicemail as read", e)
+ result.error("VOICEMAIL_ERROR", e.message, null)
+ }
+ }
+ "deleteVoicemail" -> {
+ try {
+ val id = call.argument("id")
+ if (id != null) {
+ val success = deleteVoicemail(id)
+ result.success(success)
+ } else {
+ result.error("INVALID_ARGUMENTS", "Missing voicemail id", null)
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Error deleting voicemail", e)
+ result.error("VOICEMAIL_ERROR", e.message, null)
+ }
+ }
+ else -> result.notImplemented()
+ }
+ }
+
+ private fun hasVoicemailPermissions(): Boolean {
+ val permissions = arrayOf(
+ Manifest.permission.READ_VOICEMAIL,
+ Manifest.permission.WRITE_VOICEMAIL,
+ Manifest.permission.ADD_VOICEMAIL // Added this permission
+ )
+
+ return permissions.all {
+ ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
+ }
+ }
+
+ private fun isDefaultDialer(): Boolean {
+ val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
+ return telecomManager.defaultDialerPackage == context.packageName
+ }
+
+ private fun getVoicemails(): List