Skip to content

Commit 7daec8d

Browse files
author
Capacitor+ Bot
committed
chore: sync upstream PR ionic-team#8275 from @Suryansh0910
2 parents c062981 + 8fcdc32 commit 7daec8d

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ private interface ActivityResultListener {
4646
void onActivityResult(ActivityResult result);
4747
}
4848

49+
// Static variables to store pending file chooser state to survive activity recreation
50+
private static ValueCallback<Uri[]> pendingFilePathCallback;
51+
private static Uri pendingImageFileUri;
52+
private static FileChooserType pendingFileChooserType;
53+
54+
private enum FileChooserType {
55+
IMAGE_CAPTURE,
56+
VIDEO_CAPTURE,
57+
FILE_PICKER
58+
}
59+
4960
private ActivityResultLauncher permissionLauncher;
5061
private ActivityResultLauncher activityLauncher;
5162
private PermissionListener permissionListener;
@@ -70,10 +81,70 @@ public BridgeWebChromeClient(Bridge bridge) {
7081
activityLauncher = bridge.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), (result) -> {
7182
if (activityListener != null) {
7283
activityListener.onActivityResult(result);
84+
} else if (pendingFilePathCallback != null) {
85+
// Handle case where activity was recreated and instance callback is null
86+
// Use the static callback instead
87+
handlePendingFileChooserResult(result);
7388
}
7489
});
7590
}
7691

92+
/**
93+
* Handle file chooser result when the activity was recreated and instance callbacks were lost.
94+
* This uses the static pending callback to deliver the result.
95+
*/
96+
private void handlePendingFileChooserResult(ActivityResult result) {
97+
if (pendingFilePathCallback == null) {
98+
return;
99+
}
100+
101+
try {
102+
Uri[] uriResult = null;
103+
if (result.getResultCode() == Activity.RESULT_OK) {
104+
switch (pendingFileChooserType) {
105+
case IMAGE_CAPTURE:
106+
if (pendingImageFileUri != null) {
107+
uriResult = new Uri[] { pendingImageFileUri };
108+
}
109+
break;
110+
case VIDEO_CAPTURE:
111+
Intent videoData = result.getData();
112+
if (videoData != null && videoData.getData() != null) {
113+
uriResult = new Uri[] { videoData.getData() };
114+
}
115+
break;
116+
case FILE_PICKER:
117+
Intent fileData = result.getData();
118+
if (fileData != null) {
119+
if (fileData.getClipData() != null) {
120+
final int numFiles = fileData.getClipData().getItemCount();
121+
uriResult = new Uri[numFiles];
122+
for (int i = 0; i < numFiles; i++) {
123+
uriResult[i] = fileData.getClipData().getItemAt(i).getUri();
124+
}
125+
} else {
126+
uriResult = WebChromeClient.FileChooserParams.parseResult(result.getResultCode(), fileData);
127+
}
128+
}
129+
break;
130+
}
131+
}
132+
pendingFilePathCallback.onReceiveValue(uriResult);
133+
} finally {
134+
// Clear the static state after handling
135+
clearPendingFileChooserState();
136+
}
137+
}
138+
139+
/**
140+
* Clear the static pending file chooser state.
141+
*/
142+
private static void clearPendingFileChooserState() {
143+
pendingFilePathCallback = null;
144+
pendingImageFileUri = null;
145+
pendingFileChooserType = null;
146+
}
147+
77148
/**
78149
* Render web content in `view`.
79150
*
@@ -340,12 +411,19 @@ private boolean showImageCapturePicker(final ValueCallback<Uri[]> filePathCallba
340411
return false;
341412
}
342413
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
414+
415+
// Store in static variables to survive activity recreation
416+
pendingFilePathCallback = filePathCallback;
417+
pendingImageFileUri = imageFileUri;
418+
pendingFileChooserType = FileChooserType.IMAGE_CAPTURE;
419+
343420
activityListener = (activityResult) -> {
344421
Uri[] result = null;
345422
if (activityResult.getResultCode() == Activity.RESULT_OK) {
346423
result = new Uri[] { imageFileUri };
347424
}
348425
filePathCallback.onReceiveValue(result);
426+
clearPendingFileChooserState();
349427
};
350428
activityLauncher.launch(takePictureIntent);
351429

@@ -359,12 +437,18 @@ private boolean showVideoCapturePicker(final ValueCallback<Uri[]> filePathCallba
359437
return false;
360438
}
361439

440+
// Store in static variables to survive activity recreation
441+
pendingFilePathCallback = filePathCallback;
442+
pendingImageFileUri = null;
443+
pendingFileChooserType = FileChooserType.VIDEO_CAPTURE;
444+
362445
activityListener = (activityResult) -> {
363446
Uri[] result = null;
364447
if (activityResult.getResultCode() == Activity.RESULT_OK) {
365448
result = new Uri[] { activityResult.getData().getData() };
366449
}
367450
filePathCallback.onReceiveValue(result);
451+
clearPendingFileChooserState();
368452
};
369453
activityLauncher.launch(takeVideoIntent);
370454

@@ -383,6 +467,12 @@ private void showFilePicker(final ValueCallback<Uri[]> filePathCallback, FileCho
383467
intent.setType(validTypes[0]);
384468
}
385469
}
470+
471+
// Store in static variables to survive activity recreation
472+
pendingFilePathCallback = filePathCallback;
473+
pendingImageFileUri = null;
474+
pendingFileChooserType = FileChooserType.FILE_PICKER;
475+
386476
try {
387477
activityListener = (activityResult) -> {
388478
Uri[] result;
@@ -397,10 +487,12 @@ private void showFilePicker(final ValueCallback<Uri[]> filePathCallback, FileCho
397487
result = WebChromeClient.FileChooserParams.parseResult(activityResult.getResultCode(), resultIntent);
398488
}
399489
filePathCallback.onReceiveValue(result);
490+
clearPendingFileChooserState();
400491
};
401492
activityLauncher.launch(intent);
402493
} catch (ActivityNotFoundException e) {
403494
filePathCallback.onReceiveValue(null);
495+
clearPendingFileChooserState();
404496
}
405497
}
406498

0 commit comments

Comments
 (0)