Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ private interface ActivityResultListener {
void onActivityResult(ActivityResult result);
}

// Static variables to store pending file chooser state to survive activity recreation
private static ValueCallback<Uri[]> pendingFilePathCallback;
private static Uri pendingImageFileUri;
private static FileChooserType pendingFileChooserType;

private enum FileChooserType {
IMAGE_CAPTURE,
VIDEO_CAPTURE,
FILE_PICKER
}

private ActivityResultLauncher permissionLauncher;
private ActivityResultLauncher activityLauncher;
private PermissionListener permissionListener;
Expand All @@ -70,10 +81,70 @@ public BridgeWebChromeClient(Bridge bridge) {
activityLauncher = bridge.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), (result) -> {
if (activityListener != null) {
activityListener.onActivityResult(result);
} else if (pendingFilePathCallback != null) {
// Handle case where activity was recreated and instance callback is null
// Use the static callback instead
handlePendingFileChooserResult(result);
}
});
}

/**
* Handle file chooser result when the activity was recreated and instance callbacks were lost.
* This uses the static pending callback to deliver the result.
*/
private void handlePendingFileChooserResult(ActivityResult result) {
if (pendingFilePathCallback == null) {
return;
}

try {
Uri[] uriResult = null;
if (result.getResultCode() == Activity.RESULT_OK) {
switch (pendingFileChooserType) {
case IMAGE_CAPTURE:
if (pendingImageFileUri != null) {
uriResult = new Uri[] { pendingImageFileUri };
}
break;
case VIDEO_CAPTURE:
Intent videoData = result.getData();
if (videoData != null && videoData.getData() != null) {
uriResult = new Uri[] { videoData.getData() };
}
break;
case FILE_PICKER:
Intent fileData = result.getData();
if (fileData != null) {
if (fileData.getClipData() != null) {
final int numFiles = fileData.getClipData().getItemCount();
uriResult = new Uri[numFiles];
for (int i = 0; i < numFiles; i++) {
uriResult[i] = fileData.getClipData().getItemAt(i).getUri();
}
} else {
uriResult = WebChromeClient.FileChooserParams.parseResult(result.getResultCode(), fileData);
}
}
break;
}
}
pendingFilePathCallback.onReceiveValue(uriResult);
} finally {
// Clear the static state after handling
clearPendingFileChooserState();
}
}

/**
* Clear the static pending file chooser state.
*/
private static void clearPendingFileChooserState() {
pendingFilePathCallback = null;
pendingImageFileUri = null;
pendingFileChooserType = null;
}

/**
* Render web content in `view`.
*
Expand Down Expand Up @@ -340,12 +411,19 @@ private boolean showImageCapturePicker(final ValueCallback<Uri[]> filePathCallba
return false;
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);

// Store in static variables to survive activity recreation
pendingFilePathCallback = filePathCallback;
pendingImageFileUri = imageFileUri;
pendingFileChooserType = FileChooserType.IMAGE_CAPTURE;

activityListener = (activityResult) -> {
Uri[] result = null;
if (activityResult.getResultCode() == Activity.RESULT_OK) {
result = new Uri[] { imageFileUri };
}
filePathCallback.onReceiveValue(result);
clearPendingFileChooserState();
};
activityLauncher.launch(takePictureIntent);

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

// Store in static variables to survive activity recreation
pendingFilePathCallback = filePathCallback;
pendingImageFileUri = null;
pendingFileChooserType = FileChooserType.VIDEO_CAPTURE;

activityListener = (activityResult) -> {
Uri[] result = null;
if (activityResult.getResultCode() == Activity.RESULT_OK) {
result = new Uri[] { activityResult.getData().getData() };
}
filePathCallback.onReceiveValue(result);
clearPendingFileChooserState();
};
activityLauncher.launch(takeVideoIntent);

Expand All @@ -383,6 +467,12 @@ private void showFilePicker(final ValueCallback<Uri[]> filePathCallback, FileCho
intent.setType(validTypes[0]);
}
}

// Store in static variables to survive activity recreation
pendingFilePathCallback = filePathCallback;
pendingImageFileUri = null;
pendingFileChooserType = FileChooserType.FILE_PICKER;

try {
activityListener = (activityResult) -> {
Uri[] result;
Expand All @@ -397,10 +487,12 @@ private void showFilePicker(final ValueCallback<Uri[]> filePathCallback, FileCho
result = WebChromeClient.FileChooserParams.parseResult(activityResult.getResultCode(), resultIntent);
}
filePathCallback.onReceiveValue(result);
clearPendingFileChooserState();
};
activityLauncher.launch(intent);
} catch (ActivityNotFoundException e) {
filePathCallback.onReceiveValue(null);
clearPendingFileChooserState();
}
}

Expand Down