From 496f153ce7898278138767f730810e249f1f81ad Mon Sep 17 00:00:00 2001
From: Coronon <33808743+Coronon@users.noreply.github.com>
Date: Fri, 28 Oct 2022 22:41:21 +0200
Subject: [PATCH 1/3] fix(share_plus): return correct share result on android
---
.../android/src/main/AndroidManifest.xml | 9 ++++
.../dev/fluttercommunity/plus/share/Share.kt | 10 ++---
.../plus/share/SharePlusPendingIntent.kt | 43 +++++++++++++++++++
.../plus/share/SharePlusPlugin.kt | 2 -
.../plus/share/ShareSuccessManager.kt | 34 ++++-----------
5 files changed, 65 insertions(+), 33 deletions(-)
create mode 100644 packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt
diff --git a/packages/share_plus/share_plus/android/src/main/AndroidManifest.xml b/packages/share_plus/share_plus/android/src/main/AndroidManifest.xml
index 8bbbe44d82..40801f1d83 100644
--- a/packages/share_plus/share_plus/android/src/main/AndroidManifest.xml
+++ b/packages/share_plus/share_plus/android/src/main/AndroidManifest.xml
@@ -1,6 +1,8 @@
+
+
+
+
+
+
+
diff --git a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt
index e2c1d3248b..9375657953 100644
--- a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt
+++ b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt
@@ -33,7 +33,7 @@ internal class Share(
*/
private val immutabilityIntentFlags: Int by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- PendingIntent.FLAG_IMMUTABLE
+ PendingIntent.FLAG_MUTABLE
} else {
0
}
@@ -71,9 +71,9 @@ internal class Share(
PendingIntent.getBroadcast(
context,
0,
- Intent(ShareSuccessManager.BROADCAST_CHANNEL),
+ Intent(context, SharePlusPendingIntent::class.java),
PendingIntent.FLAG_UPDATE_CURRENT or immutabilityIntentFlags
- ).intentSender
+ ).getIntentSender()
)
} else {
Intent.createChooser(shareIntent, null /* dialog title optional */)
@@ -129,9 +129,9 @@ internal class Share(
PendingIntent.getBroadcast(
context,
0,
- Intent(ShareSuccessManager.BROADCAST_CHANNEL),
+ Intent(context, SharePlusPendingIntent::class.java),
PendingIntent.FLAG_UPDATE_CURRENT or immutabilityIntentFlags
- ).intentSender
+ ).getIntentSender()
)
} else {
Intent.createChooser(shareIntent, null /* dialog title optional */)
diff --git a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt
new file mode 100644
index 0000000000..a3b035a411
--- /dev/null
+++ b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt
@@ -0,0 +1,43 @@
+package dev.fluttercommunity.plus.share
+
+import android.content.*
+import android.os.Build
+
+/**
+ * This helper class allows us to use FLAG_MUTABLE on the PendingIntent used in the Share class,
+ * as it allows us to make the underlying Intent explicit, therefore avoiding any risks an implicit
+ * mutable Intent may carry.
+ *
+ * When the PendingIntent is sent, the system will instantiate this class and call `onReceive` on it.
+ */
+internal class SharePlusPendingIntent: BroadcastReceiver() {
+ /**
+ * Companion object to achieve static behaviour.
+ */
+ companion object {
+ @JvmField
+ /**
+ * Static result to access the result of the system instantiated instance
+ */
+ var result: String = ""
+ }
+
+ /**
+ * Handler called after an action was chosen. Called only on success.
+ */
+ override fun onReceive(context: Context, intent: Intent) {
+ // Extract chosen ComponentName
+ val chosenComponent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ // Only available from API level 33 onwards
+ intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT, ComponentName::class.java)
+ } else {
+ // Deprecated in API level 33
+ intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT)
+ }
+
+ // Unambiguously identify the chosen action
+ if (chosenComponent != null) {
+ result = chosenComponent.flattenToString()
+ }
+ }
+}
diff --git a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPlugin.kt b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPlugin.kt
index b3b831ed10..d53a508ddb 100644
--- a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPlugin.kt
+++ b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPlugin.kt
@@ -15,14 +15,12 @@ class SharePlusPlugin : FlutterPlugin, ActivityAware {
override fun onAttachedToEngine(binding: FlutterPluginBinding) {
methodChannel = MethodChannel(binding.binaryMessenger, CHANNEL)
manager = ShareSuccessManager(binding.applicationContext)
- manager.register()
share = Share(context = binding.applicationContext, activity = null, manager = manager)
val handler = MethodCallHandler(share, manager)
methodChannel.setMethodCallHandler(handler)
}
override fun onDetachedFromEngine(binding: FlutterPluginBinding) {
- manager.discard()
methodChannel.setMethodCallHandler(null)
}
diff --git a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/ShareSuccessManager.kt b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/ShareSuccessManager.kt
index 36e1a4c50e..3ac7116f0b 100644
--- a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/ShareSuccessManager.kt
+++ b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/ShareSuccessManager.kt
@@ -9,31 +9,18 @@ import java.util.concurrent.atomic.AtomicBoolean
* Handles the callback based status information about a successful or dismissed
* share. Used to link multiple different callbacks together for easier use.
*/
-internal class ShareSuccessManager(private val context: Context) : BroadcastReceiver(),
- ActivityResultListener {
+internal class ShareSuccessManager(private val context: Context) : ActivityResultListener {
private var callback: MethodChannel.Result? = null
private var isCalledBack: AtomicBoolean = AtomicBoolean(true)
- /**
- * Register listener. Must be called before any share sheet is opened.
- */
- fun register() {
- context.registerReceiver(this, IntentFilter(BROADCAST_CHANNEL))
- }
-
- /**
- * Deregister listener. Must be called before the base activity is invalidated.
- */
- fun discard() {
- context.unregisterReceiver(this)
- }
-
/**
* Set result callback that will wait for the share-sheet to close and get either
* the componentname of the chosen option or an empty string on dismissal.
*/
fun setCallback(callback: MethodChannel.Result): Boolean {
return if (isCalledBack.compareAndSet(true, false)) {
+ // Prepare all state for new share
+ SharePlusPendingIntent.result = ""
isCalledBack.set(false)
this.callback = callback
true
@@ -51,7 +38,7 @@ internal class ShareSuccessManager(private val context: Context) : BroadcastRece
* Must be called if `.startActivityForResult` is not available to avoid deadlocking.
*/
fun unavailable() {
- returnResult("dev.fluttercommunity.plus/share/unavailable")
+ returnResult(RESULT_UNAVAILABLE)
}
/**
@@ -70,7 +57,7 @@ internal class ShareSuccessManager(private val context: Context) : BroadcastRece
*/
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
return if (requestCode == ACTIVITY_CODE) {
- returnResult("")
+ returnResult(SharePlusPendingIntent.result)
true
} else {
false
@@ -78,16 +65,11 @@ internal class ShareSuccessManager(private val context: Context) : BroadcastRece
}
/**
- * Handler called after a sharesheet was closed. Called only on success.
+ * Companion object holds constants used throughout the plugin when attempting to return
+ * the share result.
*/
- override fun onReceive(context: Context, intent: Intent) {
- returnResult(
- intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT).toString()
- )
- }
-
companion object {
- const val BROADCAST_CHANNEL = "dev.fluttercommunity.plus/share/success"
const val ACTIVITY_CODE = 17062003
+ const val RESULT_UNAVAILABLE = "dev.fluttercommunity.plus/share/unavailable"
}
}
From eee78eafc4324509470cfdfb6b872f443706b5a0 Mon Sep 17 00:00:00 2001
From: Coronon <33808743+Coronon@users.noreply.github.com>
Date: Fri, 28 Oct 2022 22:41:40 +0200
Subject: [PATCH 2/3] docs(share_plus): improve file_path.xml documentation
---
.../android/src/main/res/xml/flutter_share_file_paths.xml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/share_plus/share_plus/android/src/main/res/xml/flutter_share_file_paths.xml b/packages/share_plus/share_plus/android/src/main/res/xml/flutter_share_file_paths.xml
index 4e78448e9e..cb820aec00 100644
--- a/packages/share_plus/share_plus/android/src/main/res/xml/flutter_share_file_paths.xml
+++ b/packages/share_plus/share_plus/android/src/main/res/xml/flutter_share_file_paths.xml
@@ -1,4 +1,5 @@
-
-
+
+
+
From 488a27c5a6ca2cadb1a27591b5c17a1986cbd8b1 Mon Sep 17 00:00:00 2001
From: Coronon <33808743+Coronon@users.noreply.github.com>
Date: Sat, 29 Oct 2022 15:00:30 +0200
Subject: [PATCH 3/3] style(share_plus): adapt to Kotlin style and enhance
comments
---
.../main/kotlin/dev/fluttercommunity/plus/share/Share.kt | 4 ++--
.../fluttercommunity/plus/share/SharePlusPendingIntent.kt | 6 +-----
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt
index 9375657953..95cfca5f06 100644
--- a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt
+++ b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/Share.kt
@@ -73,7 +73,7 @@ internal class Share(
0,
Intent(context, SharePlusPendingIntent::class.java),
PendingIntent.FLAG_UPDATE_CURRENT or immutabilityIntentFlags
- ).getIntentSender()
+ ).intentSender
)
} else {
Intent.createChooser(shareIntent, null /* dialog title optional */)
@@ -131,7 +131,7 @@ internal class Share(
0,
Intent(context, SharePlusPendingIntent::class.java),
PendingIntent.FLAG_UPDATE_CURRENT or immutabilityIntentFlags
- ).getIntentSender()
+ ).intentSender
)
} else {
Intent.createChooser(shareIntent, null /* dialog title optional */)
diff --git a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt
index a3b035a411..284ccd507a 100644
--- a/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt
+++ b/packages/share_plus/share_plus/android/src/main/kotlin/dev/fluttercommunity/plus/share/SharePlusPendingIntent.kt
@@ -11,13 +11,9 @@ import android.os.Build
* When the PendingIntent is sent, the system will instantiate this class and call `onReceive` on it.
*/
internal class SharePlusPendingIntent: BroadcastReceiver() {
- /**
- * Companion object to achieve static behaviour.
- */
companion object {
- @JvmField
/**
- * Static result to access the result of the system instantiated instance
+ * Static member to access the result of the system instantiated instance
*/
var result: String = ""
}