diff --git a/CHANGELOG.md b/CHANGELOG.md index 5781694..9e53f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.5.0-beta.2] - 2026-10-04 + +> **Pre-release.** Replaces 1.5.0-beta.1, which crashes at launch on Android under NativePHP +> Mobile v4. Scanning itself still has not been run on a physical device. Install with +> `composer require ikromjon/nativephp-mobile-document-scanner:^1.5@beta`. + +### Fixed + +- Android: the app crashed at launch on NativePHP for Mobile v4. v4 creates bridge functions + after the activity has resumed, and the scanner registered its result launcher with + `registerForActivityResult()`, which Android only allows before the activity starts. The + launcher is now registered with the activity's result registry directly, which is valid at + any point. NativePHP v3 creates bridge functions in `onCreate` and was not affected + ## [1.5.0-beta.1] - 2026-10-03 > **Pre-release.** The native fixes below compile in a NativePHP Mobile v4 app on iOS and diff --git a/resources/android/src/DocumentScannerFunctions.kt b/resources/android/src/DocumentScannerFunctions.kt index 570c2df..19ff8cb 100644 --- a/resources/android/src/DocumentScannerFunctions.kt +++ b/resources/android/src/DocumentScannerFunctions.kt @@ -23,9 +23,11 @@ import org.json.JSONArray import org.json.JSONObject import java.io.File import java.io.FileOutputStream +import java.lang.ref.WeakReference object DocumentScannerFunctions { private const val TAG = "DocumentScanner" + private const val SCAN_LAUNCHER_KEY = "com.nativephp.documentscanner.scan" private var defaultMaxPages = 0 private var defaultOutputFormat = "jpeg" @@ -36,6 +38,7 @@ object DocumentScannerFunctions { private var defaultScannerMode = "full" private var scannerLauncher: ActivityResultLauncher? = null + private var launcherOwner: WeakReference? = null private var currentOutputFormat = "jpeg" private var currentJpegQuality = 90 @@ -67,11 +70,20 @@ object DocumentScannerFunctions { } } + /** + * Registers with the activity's result registry directly rather than + * through registerForActivityResult(). That call is only legal before the + * activity is STARTED, and NativePHP v4 creates bridge functions after the + * activity has resumed, so it crashed the app at launch. + */ fun registerLauncher(activity: FragmentActivity) { - if (scannerLauncher != null) return + if (scannerLauncher != null && launcherOwner?.get() === activity) return + scannerLauncher?.unregister() + launcherOwner = WeakReference(activity) scannerLauncher = - activity.registerForActivityResult( + activity.activityResultRegistry.register( + SCAN_LAUNCHER_KEY, ActivityResultContracts.StartIntentSenderForResult(), ) { result: ActivityResult -> if (result.resultCode == Activity.RESULT_OK) {