@capgo/capacitor-inappbrowser 8.15.0 → 8.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/CapgoInAppBrowserPlugin.java +1 -3
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/FileChooserRequestSupport.java +57 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +124 -58
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +1 -1
- package/package.json +1 -1
|
@@ -574,9 +574,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
574
574
|
}
|
|
575
575
|
|
|
576
576
|
// Send the result to WebView and clean up
|
|
577
|
-
webViewDialog.
|
|
578
|
-
webViewDialog.mFilePathCallback = null;
|
|
579
|
-
webViewDialog.tempCameraUri = null;
|
|
577
|
+
webViewDialog.completeLegacyFileChooserResult(results);
|
|
580
578
|
}
|
|
581
579
|
}
|
|
582
580
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package ee.forgr.capacitor_inappbrowser;
|
|
2
|
+
|
|
3
|
+
import android.net.Uri;
|
|
4
|
+
import android.webkit.ValueCallback;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Request-scoped state for Android WebView file-chooser flows.
|
|
8
|
+
* Prevents overlapping chooser/camera requests from cross-delivering results.
|
|
9
|
+
*/
|
|
10
|
+
final class FileChooserRequestSupport {
|
|
11
|
+
|
|
12
|
+
static final class FileChooserRequest {
|
|
13
|
+
|
|
14
|
+
private static long nextId = 0;
|
|
15
|
+
|
|
16
|
+
final long id;
|
|
17
|
+
final ValueCallback<Uri[]> callback;
|
|
18
|
+
final String acceptType;
|
|
19
|
+
final boolean multiple;
|
|
20
|
+
Uri tempCameraUri;
|
|
21
|
+
|
|
22
|
+
FileChooserRequest(ValueCallback<Uri[]> callback, String acceptType, boolean multiple) {
|
|
23
|
+
this.id = ++nextId;
|
|
24
|
+
this.callback = callback;
|
|
25
|
+
this.acceptType = acceptType;
|
|
26
|
+
this.multiple = multiple;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private FileChooserRequestSupport() {}
|
|
31
|
+
|
|
32
|
+
static boolean isActive(FileChooserRequest request, FileChooserRequest active) {
|
|
33
|
+
return request != null && request == active;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static void cancel(FileChooserRequest request) {
|
|
37
|
+
if (request != null && request.callback != null) {
|
|
38
|
+
request.callback.onReceiveValue(null);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static boolean completeIfActive(FileChooserRequest request, FileChooserRequest active, Uri[] results) {
|
|
43
|
+
if (!isActive(request, active)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
request.callback.onReceiveValue(results);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static boolean cancelIfActive(FileChooserRequest request, FileChooserRequest active) {
|
|
51
|
+
if (!isActive(request, active)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
request.callback.onReceiveValue(null);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -412,6 +412,7 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
412
412
|
public static final int FILE_CHOOSER_REQUEST_CODE = 1000;
|
|
413
413
|
public ValueCallback<Uri> mUploadMessage;
|
|
414
414
|
public ValueCallback<Uri[]> mFilePathCallback;
|
|
415
|
+
FileChooserRequestSupport.FileChooserRequest activeFileChooserRequest;
|
|
415
416
|
private boolean openWebViewResolved;
|
|
416
417
|
private boolean isDismissing = false;
|
|
417
418
|
private PermissionRequest pendingCameraLaunchPermissionRequest;
|
|
@@ -2348,12 +2349,9 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2348
2349
|
);
|
|
2349
2350
|
|
|
2350
2351
|
// Check if the file chooser is already open
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
}
|
|
2355
|
-
|
|
2356
|
-
mFilePathCallback = filePathCallback;
|
|
2352
|
+
final boolean isMultiple = fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE;
|
|
2353
|
+
beginFileChooserRequest(filePathCallback, acceptType, isMultiple);
|
|
2354
|
+
final FileChooserRequestSupport.FileChooserRequest request = activeFileChooserRequest;
|
|
2357
2355
|
|
|
2358
2356
|
// Direct check for capture attribute in URL (fallback method)
|
|
2359
2357
|
boolean isCaptureInUrl;
|
|
@@ -2428,12 +2426,16 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2428
2426
|
""";
|
|
2429
2427
|
|
|
2430
2428
|
webView.evaluateJavascript(js, (value) -> {
|
|
2429
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2431
2433
|
Log.d("InAppBrowser", "Capture attribute JS result: " + value);
|
|
2432
2434
|
|
|
2433
2435
|
// If we already found capture in URL, use that directly
|
|
2434
2436
|
if (isCaptureInUrl) {
|
|
2435
2437
|
Log.d("InAppBrowser", "Using capture from URL: " + captureMode);
|
|
2436
|
-
launchCamera(captureMode.equals("user"));
|
|
2438
|
+
launchCamera(captureMode.equals("user"), request);
|
|
2437
2439
|
return;
|
|
2438
2440
|
}
|
|
2439
2441
|
|
|
@@ -2444,7 +2446,7 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2444
2446
|
Log.d("InAppBrowser", "Found capture attribute: " + captureValue);
|
|
2445
2447
|
|
|
2446
2448
|
if (!captureValue.isEmpty()) {
|
|
2447
|
-
activity.runOnUiThread(() -> launchCamera(captureValue.equals("user")));
|
|
2449
|
+
activity.runOnUiThread(() -> launchCamera(captureValue.equals("user"), request));
|
|
2448
2450
|
return;
|
|
2449
2451
|
}
|
|
2450
2452
|
}
|
|
@@ -2452,6 +2454,10 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2452
2454
|
// Look for hints in the web page source
|
|
2453
2455
|
Log.d("InAppBrowser", "Looking for camera hints in page content");
|
|
2454
2456
|
webView.evaluateJavascript("(function() { return document.documentElement.innerHTML; })()", (htmlSource) -> {
|
|
2457
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2455
2461
|
if (htmlSource != null && htmlSource.length() > 10) {
|
|
2456
2462
|
boolean hasCameraOrSelfieKeyword =
|
|
2457
2463
|
htmlSource.contains("capture=") || htmlSource.contains("camera") || htmlSource.contains("selfie");
|
|
@@ -2464,25 +2470,21 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2464
2470
|
(currentUrl.contains("selfie") || currentUrl.contains("camera") || currentUrl.contains("photo"))
|
|
2465
2471
|
) {
|
|
2466
2472
|
Log.d("InAppBrowser", "URL suggests camera usage, launching camera");
|
|
2467
|
-
activity.runOnUiThread(() -> launchCamera(currentUrl.contains("selfie")));
|
|
2473
|
+
activity.runOnUiThread(() -> launchCamera(currentUrl.contains("selfie"), request));
|
|
2468
2474
|
return;
|
|
2469
2475
|
}
|
|
2470
2476
|
}
|
|
2471
2477
|
|
|
2472
2478
|
// If all detection methods fail, fall back to regular file picker
|
|
2473
2479
|
Log.d("InAppBrowser", "No capture attribute detected, using file picker");
|
|
2474
|
-
openFileChooser(
|
|
2475
|
-
filePathCallback,
|
|
2476
|
-
acceptType,
|
|
2477
|
-
fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE
|
|
2478
|
-
);
|
|
2480
|
+
openFileChooser(request);
|
|
2479
2481
|
});
|
|
2480
2482
|
});
|
|
2481
2483
|
return true;
|
|
2482
2484
|
}
|
|
2483
2485
|
|
|
2484
2486
|
// For non-image types, use regular file picker
|
|
2485
|
-
openFileChooser(
|
|
2487
|
+
openFileChooser(request);
|
|
2486
2488
|
return true;
|
|
2487
2489
|
}
|
|
2488
2490
|
|
|
@@ -2490,7 +2492,11 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2490
2492
|
* Launch the camera app for capturing images
|
|
2491
2493
|
* @param useFrontCamera true to use front camera, false for back camera
|
|
2492
2494
|
*/
|
|
2493
|
-
private void launchCamera(boolean useFrontCamera) {
|
|
2495
|
+
private void launchCamera(boolean useFrontCamera, FileChooserRequestSupport.FileChooserRequest request) {
|
|
2496
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2494
2500
|
Log.d("InAppBrowser", "Launching camera, front camera: " + useFrontCamera);
|
|
2495
2501
|
|
|
2496
2502
|
// First check if we have camera permission
|
|
@@ -2514,8 +2520,11 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2514
2520
|
Log.d("InAppBrowser", "Ignoring delayed camera permission grant during dismiss");
|
|
2515
2521
|
return;
|
|
2516
2522
|
}
|
|
2523
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2524
|
+
return;
|
|
2525
|
+
}
|
|
2517
2526
|
// Permission granted, now launch the camera
|
|
2518
|
-
launchCameraWithPermission(useFrontCamera);
|
|
2527
|
+
launchCameraWithPermission(useFrontCamera, request);
|
|
2519
2528
|
}
|
|
2520
2529
|
|
|
2521
2530
|
@Override
|
|
@@ -2525,9 +2534,12 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2525
2534
|
Log.d("InAppBrowser", "Ignoring delayed camera permission denial during dismiss");
|
|
2526
2535
|
return;
|
|
2527
2536
|
}
|
|
2537
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2528
2540
|
// Permission denied, fall back to file picker
|
|
2529
2541
|
Log.e("InAppBrowser", "Camera permission denied, falling back to file picker");
|
|
2530
|
-
fallbackToFilePicker();
|
|
2542
|
+
fallbackToFilePicker(request);
|
|
2531
2543
|
}
|
|
2532
2544
|
};
|
|
2533
2545
|
|
|
@@ -2539,13 +2551,17 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2539
2551
|
}
|
|
2540
2552
|
|
|
2541
2553
|
// If we can't request permission, try launching directly
|
|
2542
|
-
launchCameraWithPermission(useFrontCamera);
|
|
2554
|
+
launchCameraWithPermission(useFrontCamera, request);
|
|
2543
2555
|
}
|
|
2544
2556
|
|
|
2545
2557
|
/**
|
|
2546
2558
|
* Launch camera after permission is granted
|
|
2547
2559
|
*/
|
|
2548
|
-
private void launchCameraWithPermission(boolean useFrontCamera) {
|
|
2560
|
+
private void launchCameraWithPermission(boolean useFrontCamera, FileChooserRequestSupport.FileChooserRequest request) {
|
|
2561
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2562
|
+
return;
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2549
2565
|
try {
|
|
2550
2566
|
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
2551
2567
|
if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
|
|
@@ -2554,17 +2570,18 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2554
2570
|
photoFile = createImageFile();
|
|
2555
2571
|
} catch (IOException ex) {
|
|
2556
2572
|
Log.e("InAppBrowser", "Error creating image file", ex);
|
|
2557
|
-
fallbackToFilePicker();
|
|
2573
|
+
fallbackToFilePicker(request);
|
|
2558
2574
|
return;
|
|
2559
2575
|
}
|
|
2560
2576
|
|
|
2561
2577
|
if (photoFile != null) {
|
|
2562
|
-
tempCameraUri = FileProvider.getUriForFile(
|
|
2578
|
+
request.tempCameraUri = FileProvider.getUriForFile(
|
|
2563
2579
|
activity,
|
|
2564
2580
|
activity.getPackageName() + ".fileprovider",
|
|
2565
2581
|
photoFile
|
|
2566
2582
|
);
|
|
2567
|
-
|
|
2583
|
+
syncFileChooserPublicFields();
|
|
2584
|
+
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, request.tempCameraUri);
|
|
2568
2585
|
|
|
2569
2586
|
if (useFrontCamera) {
|
|
2570
2587
|
takePictureIntent.putExtra("android.intent.extras.CAMERA_FACING", 1);
|
|
@@ -2580,15 +2597,23 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2580
2597
|
"camera_capture",
|
|
2581
2598
|
new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
|
|
2582
2599
|
(result) -> {
|
|
2583
|
-
if (
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2600
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2601
|
+
return;
|
|
2602
|
+
}
|
|
2603
|
+
Uri[] results = null;
|
|
2604
|
+
if (result.getResultCode() == Activity.RESULT_OK && request.tempCameraUri != null) {
|
|
2605
|
+
results = new Uri[] { request.tempCameraUri };
|
|
2606
|
+
}
|
|
2607
|
+
if (
|
|
2608
|
+
FileChooserRequestSupport.completeIfActive(
|
|
2609
|
+
request,
|
|
2610
|
+
activeFileChooserRequest,
|
|
2611
|
+
results
|
|
2612
|
+
)
|
|
2613
|
+
) {
|
|
2614
|
+
request.tempCameraUri = null;
|
|
2615
|
+
clearActiveFileChooserRequest(request);
|
|
2589
2616
|
}
|
|
2590
|
-
mFilePathCallback = null;
|
|
2591
|
-
tempCameraUri = null;
|
|
2592
2617
|
}
|
|
2593
2618
|
)
|
|
2594
2619
|
.launch(takePictureIntent);
|
|
@@ -2598,26 +2623,27 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2598
2623
|
}
|
|
2599
2624
|
} catch (SecurityException e) {
|
|
2600
2625
|
Log.e("InAppBrowser", "Security exception launching camera: " + e.getMessage(), e);
|
|
2601
|
-
fallbackToFilePicker();
|
|
2626
|
+
fallbackToFilePicker(request);
|
|
2602
2627
|
}
|
|
2603
2628
|
} else {
|
|
2604
2629
|
Log.e("InAppBrowser", "Failed to create photo URI, falling back to file picker");
|
|
2605
|
-
fallbackToFilePicker();
|
|
2630
|
+
fallbackToFilePicker(request);
|
|
2606
2631
|
}
|
|
2607
2632
|
}
|
|
2608
2633
|
} catch (Exception e) {
|
|
2609
2634
|
Log.e("InAppBrowser", "Camera launch failed: " + e.getMessage(), e);
|
|
2610
|
-
fallbackToFilePicker();
|
|
2635
|
+
fallbackToFilePicker(request);
|
|
2611
2636
|
}
|
|
2612
2637
|
}
|
|
2613
2638
|
|
|
2614
2639
|
/**
|
|
2615
2640
|
* Fall back to file picker when camera launch fails
|
|
2616
2641
|
*/
|
|
2617
|
-
private void fallbackToFilePicker() {
|
|
2618
|
-
if (
|
|
2619
|
-
|
|
2642
|
+
private void fallbackToFilePicker(FileChooserRequestSupport.FileChooserRequest request) {
|
|
2643
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2644
|
+
return;
|
|
2620
2645
|
}
|
|
2646
|
+
openFileChooser(request);
|
|
2621
2647
|
}
|
|
2622
2648
|
|
|
2623
2649
|
// Grant permissions for cam
|
|
@@ -4065,8 +4091,43 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4065
4091
|
}
|
|
4066
4092
|
}
|
|
4067
4093
|
|
|
4068
|
-
private void
|
|
4069
|
-
|
|
4094
|
+
private void beginFileChooserRequest(ValueCallback<Uri[]> filePathCallback, String acceptType, boolean isMultiple) {
|
|
4095
|
+
if (activeFileChooserRequest != null) {
|
|
4096
|
+
FileChooserRequestSupport.cancel(activeFileChooserRequest);
|
|
4097
|
+
}
|
|
4098
|
+
activeFileChooserRequest = new FileChooserRequestSupport.FileChooserRequest(filePathCallback, acceptType, isMultiple);
|
|
4099
|
+
syncFileChooserPublicFields();
|
|
4100
|
+
}
|
|
4101
|
+
|
|
4102
|
+
private void clearActiveFileChooserRequest(FileChooserRequestSupport.FileChooserRequest request) {
|
|
4103
|
+
if (activeFileChooserRequest == request) {
|
|
4104
|
+
activeFileChooserRequest = null;
|
|
4105
|
+
syncFileChooserPublicFields();
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
|
|
4109
|
+
private void syncFileChooserPublicFields() {
|
|
4110
|
+
mFilePathCallback = activeFileChooserRequest != null ? activeFileChooserRequest.callback : null;
|
|
4111
|
+
tempCameraUri = activeFileChooserRequest != null ? activeFileChooserRequest.tempCameraUri : null;
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4114
|
+
void completeLegacyFileChooserResult(Uri[] results) {
|
|
4115
|
+
FileChooserRequestSupport.FileChooserRequest request = activeFileChooserRequest;
|
|
4116
|
+
if (request == null) {
|
|
4117
|
+
return;
|
|
4118
|
+
}
|
|
4119
|
+
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4120
|
+
request.tempCameraUri = null;
|
|
4121
|
+
clearActiveFileChooserRequest(request);
|
|
4122
|
+
}
|
|
4123
|
+
}
|
|
4124
|
+
|
|
4125
|
+
private void openFileChooser(FileChooserRequestSupport.FileChooserRequest request) {
|
|
4126
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4127
|
+
return;
|
|
4128
|
+
}
|
|
4129
|
+
String acceptType = request.acceptType;
|
|
4130
|
+
boolean isMultiple = request.multiple;
|
|
4070
4131
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
4071
4132
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
4072
4133
|
|
|
@@ -4114,26 +4175,29 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4114
4175
|
"file_chooser",
|
|
4115
4176
|
new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
|
|
4116
4177
|
(result) -> {
|
|
4178
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4179
|
+
return;
|
|
4180
|
+
}
|
|
4181
|
+
Uri[] results = null;
|
|
4117
4182
|
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
4118
4183
|
Intent data = result.getData();
|
|
4119
4184
|
if (data != null) {
|
|
4120
4185
|
if (data.getClipData() != null) {
|
|
4121
4186
|
// Handle multiple files
|
|
4122
4187
|
int count = data.getClipData().getItemCount();
|
|
4123
|
-
|
|
4188
|
+
results = new Uri[count];
|
|
4124
4189
|
for (int i = 0; i < count; i++) {
|
|
4125
4190
|
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
4126
4191
|
}
|
|
4127
|
-
mFilePathCallback.onReceiveValue(results);
|
|
4128
4192
|
} else if (data.getData() != null) {
|
|
4129
4193
|
// Handle single file
|
|
4130
|
-
|
|
4194
|
+
results = new Uri[] { data.getData() };
|
|
4131
4195
|
}
|
|
4132
4196
|
}
|
|
4133
|
-
} else {
|
|
4134
|
-
mFilePathCallback.onReceiveValue(null);
|
|
4135
4197
|
}
|
|
4136
|
-
|
|
4198
|
+
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4199
|
+
clearActiveFileChooserRequest(request);
|
|
4200
|
+
}
|
|
4137
4201
|
}
|
|
4138
4202
|
)
|
|
4139
4203
|
.launch(Intent.createChooser(intent, "Select File"));
|
|
@@ -4154,26 +4218,29 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4154
4218
|
"file_chooser",
|
|
4155
4219
|
new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
|
|
4156
4220
|
(result) -> {
|
|
4221
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4222
|
+
return;
|
|
4223
|
+
}
|
|
4224
|
+
Uri[] results = null;
|
|
4157
4225
|
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
4158
4226
|
Intent data = result.getData();
|
|
4159
4227
|
if (data != null) {
|
|
4160
4228
|
if (data.getClipData() != null) {
|
|
4161
4229
|
// Handle multiple files
|
|
4162
4230
|
int count = data.getClipData().getItemCount();
|
|
4163
|
-
|
|
4231
|
+
results = new Uri[count];
|
|
4164
4232
|
for (int i = 0; i < count; i++) {
|
|
4165
4233
|
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
4166
4234
|
}
|
|
4167
|
-
mFilePathCallback.onReceiveValue(results);
|
|
4168
4235
|
} else if (data.getData() != null) {
|
|
4169
4236
|
// Handle single file
|
|
4170
|
-
|
|
4237
|
+
results = new Uri[] { data.getData() };
|
|
4171
4238
|
}
|
|
4172
4239
|
}
|
|
4173
|
-
} else {
|
|
4174
|
-
mFilePathCallback.onReceiveValue(null);
|
|
4175
4240
|
}
|
|
4176
|
-
|
|
4241
|
+
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4242
|
+
clearActiveFileChooserRequest(request);
|
|
4243
|
+
}
|
|
4177
4244
|
}
|
|
4178
4245
|
)
|
|
4179
4246
|
.launch(Intent.createChooser(intent, "Select File"));
|
|
@@ -4184,9 +4251,8 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4184
4251
|
} catch (ActivityNotFoundException ex) {
|
|
4185
4252
|
// If still failing, report error
|
|
4186
4253
|
Log.e("InAppBrowser", "No app can handle file picker", ex);
|
|
4187
|
-
if (
|
|
4188
|
-
|
|
4189
|
-
mFilePathCallback = null;
|
|
4254
|
+
if (FileChooserRequestSupport.cancelIfActive(request, activeFileChooserRequest)) {
|
|
4255
|
+
clearActiveFileChooserRequest(request);
|
|
4190
4256
|
}
|
|
4191
4257
|
}
|
|
4192
4258
|
}
|
|
@@ -6258,11 +6324,11 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
6258
6324
|
}
|
|
6259
6325
|
|
|
6260
6326
|
// Clear any pending callbacks to prevent memory leaks
|
|
6261
|
-
if (
|
|
6262
|
-
|
|
6263
|
-
|
|
6327
|
+
if (activeFileChooserRequest != null) {
|
|
6328
|
+
FileChooserRequestSupport.cancel(activeFileChooserRequest);
|
|
6329
|
+
activeFileChooserRequest = null;
|
|
6330
|
+
syncFileChooserPublicFields();
|
|
6264
6331
|
}
|
|
6265
|
-
tempCameraUri = null;
|
|
6266
6332
|
|
|
6267
6333
|
// Clear file inputs for security/privacy before destroying WebView
|
|
6268
6334
|
try {
|
|
@@ -415,7 +415,7 @@ public class CapgoInAppBrowserPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
415
415
|
case aware = "AWARE"
|
|
416
416
|
case fakeVisible = "FAKE_VISIBLE"
|
|
417
417
|
}
|
|
418
|
-
private let pluginVersion: String = "8.15.
|
|
418
|
+
private let pluginVersion: String = "8.15.1"
|
|
419
419
|
public let identifier = "CapgoInAppBrowserPlugin"
|
|
420
420
|
public let jsName = "CapgoInAppBrowser"
|
|
421
421
|
public let pluginMethods: [CAPPluginMethod] = [
|