diff --git a/CHANGELOG.md b/CHANGELOG.md index 636af59..e5b4c45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### 3.0.2 + [Android] Fix false "no email Managers available" when sending without attachments on Android 11+ by removing + PackageManager pre-query for ACTION_SENDTO and launching intent directly + [Example] Migrate Android build to Flutter's declarative Gradle plugin (dev.flutter.flutter-plugin-loader / + dev.flutter.flutter-gradle-plugin), update to Android compileSdk 36, and migrate embedding to v2. + ### 3.0.1 [root] add analysis options [test] remove usage of deprecated `setMockMethodCallHandler` in tests diff --git a/android/src/main/java/com/dataxad/flutter_mailer/MethodCallHandlerImpl.java b/android/src/main/java/com/dataxad/flutter_mailer/MethodCallHandlerImpl.java index d81798d..96a81a0 100644 --- a/android/src/main/java/com/dataxad/flutter_mailer/MethodCallHandlerImpl.java +++ b/android/src/main/java/com/dataxad/flutter_mailer/MethodCallHandlerImpl.java @@ -4,8 +4,8 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.ActivityNotFoundException; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; @@ -70,7 +70,12 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result mResult = result; try { final Intent intent = mail(call); - activity.startActivityForResult(intent, MAIL_ACTIVITY_REQUEST_CODE); + try { + activity.startActivityForResult(intent, MAIL_ACTIVITY_REQUEST_CODE); + } catch (ActivityNotFoundException e) { + result.error("not_available", "no email Managers available", null); + mResult = null; + } } catch (FlutterMailerException e) { result.error(e.errorCode, e.errorMessage, e.errorDetails); mResult = null; @@ -164,20 +169,13 @@ private Intent mail(MethodCall options) throws FlutterMailerException { } } - PackageManager manager = context.getPackageManager(); - List list = manager.queryIntentActivities(intent, 0); - - if (list == null || list.size() == 0) { - Log.e(TAG, "size is null or Zero"); - throw new FlutterMailerException("not_available", "no email Managers available", null); - } - - if (list.size() == 1) { - return intent; - } else if (options.hasArgument(APP_SCHEMA) && options.argument(APP_SCHEMA) != null && isAppInstalled((String) options.argument(APP_SCHEMA))) { + // If a specific package schema is requested, set it directly and let the system + // resolve it; avoid pre-querying PackageManager to keep compatibility with + // Android 11+ package visibility restrictions. + if (options.hasArgument(APP_SCHEMA) && options.argument(APP_SCHEMA) != null) { intent.setPackage((String) options.argument(APP_SCHEMA)); - return intent; } + return intent; } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index f3685d9..7caba83 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,37 +1,26 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'dev.flutter.flutter-gradle-plugin' +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } + localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') ?: '1' +def flutterVersionName = localProperties.getProperty('flutter.versionName') ?: '1.0' android { - compileSdk = 35 + compileSdk = 36 namespace 'com.dataxad.flutter_mailer_example' defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.dataxad.flutter_mailer_example" - minSdkVersion flutter.minSdkVersion + minSdkVersion flutter.minSdkVersion targetSdkVersion 35 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -47,10 +36,6 @@ android { } } -flutter { - source '../..' -} - dependencies { testImplementation 'junit:junit:4.12' diff --git a/example/android/app/src/main/java/com/dataxad/flutter_mailer_example/EmbeddingV1Activity.java b/example/android/app/src/main/java/com/dataxad/flutter_mailer_example/EmbeddingV1Activity.java index c0fb07a..1736b98 100644 --- a/example/android/app/src/main/java/com/dataxad/flutter_mailer_example/EmbeddingV1Activity.java +++ b/example/android/app/src/main/java/com/dataxad/flutter_mailer_example/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ // import dev.flutter.plugins.integration_test.IntegrationTestPlugin; // import io.flutter.plugins.imagepicker.ImagePickerPlugin; // import io.flutter.plugins.pathprovider.PathProviderPlugin; -import io.flutter.app.FlutterActivity; +import io.flutter.embedding.android.FlutterActivity; public class EmbeddingV1Activity extends FlutterActivity { // @Override diff --git a/example/android/build.gradle b/example/android/build.gradle index 6b8449d..bc157bd 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,19 +1,3 @@ -buildscript { - ext { - agp_version = '8.7.0' - kotlin_version = '2.1.0' - } - repositories { - google() - mavenCentral() - } - - dependencies { - classpath "com.android.tools.build:gradle:$agp_version" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - allprojects { repositories { google() diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 44e62bc..cb71091 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,11 +1,27 @@ -include ':app' +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + def localPropertiesFile = new File(rootProject.projectDir, "local.properties") + def properties = new Properties() -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + assert localPropertiesFile.exists() + localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null : "flutter.sdk not set in local.properties" + + // Make the Flutter Gradle plugin available to this build without applying it imperatively. + includeBuild("${flutterSdkPath}/packages/flutter_tools/gradle") +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.7.0" apply false + id "org.jetbrains.kotlin.android" version "2.1.0" apply false +} + +include ":app" diff --git a/pubspec.yaml b/pubspec.yaml index 4b8a0ed..108d721 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_mailer description: Share an email to device Email - Client supports multiple Attachments -version: 3.0.1 +version: 3.0.2 homepage: https://github.com/taljacobson/flutter_mailer dependencies: