Skip to content

Commit c44a81f

Browse files
author
doubleangels
committed
Bug fix for issue when sharing files to Redact
1 parent a045e8a commit c44a81f

3 files changed

Lines changed: 42 additions & 37 deletions

File tree

app/src/main/java/com/doubleangels/redact/ShareHandlerActivity.java

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,13 @@ private void dismissProgressDialog() {
391391
}
392392
}
393393

394+
private static final int REQUEST_SHARE = 1001;
395+
394396
/**
395397
* Creates and launches a share intent for the processed (clean) media file.
396-
* The temporary file will be deleted after sharing completes (when activity resumes).
398+
* Uses startActivityForResult so we only clean up after the chooser returns,
399+
* not when it merely pauses this activity (which would delete the file before
400+
* the receiving app has read it).
397401
*
398402
* @param isVideo Whether the processed file is a video (true) or image (false)
399403
* @param cleanedFileUri The URI of the processed file to share
@@ -403,60 +407,57 @@ private void shareCleanFile(boolean isVideo, Uri cleanedFileUri) {
403407
SentryManager.setCustomKey("cleaned_uri", cleanedFileUri != null ? cleanedFileUri.toString() : "null");
404408

405409
if (cleanedFileUri != null) {
406-
// Create a share intent with the appropriate MIME type
410+
String mimeType = isVideo ? "video/*" : "image/*";
411+
407412
Intent shareIntent = new Intent(Intent.ACTION_SEND);
408-
shareIntent.setType(isVideo ? "video/*" : "image/*");
413+
shareIntent.setType(mimeType);
409414
shareIntent.putExtra(Intent.EXTRA_STREAM, cleanedFileUri);
410415
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
411416

412-
// Mark that sharing has been initiated
413-
sharingInitiated = true;
417+
// Proactively grant read permission to every app that can handle this intent.
418+
// This is required because some apps receive the URI through the chooser's
419+
// indirection layer, which doesn't automatically forward FLAG_GRANT_READ_URI_PERMISSION.
420+
for (android.content.pm.ResolveInfo resolveInfo :
421+
getPackageManager().queryIntentActivities(shareIntent, 0)) {
422+
String packageName = resolveInfo.activityInfo.packageName;
423+
grantUriPermission(packageName, cleanedFileUri,
424+
Intent.FLAG_GRANT_READ_URI_PERMISSION);
425+
}
414426

415-
// Launch the share intent
416-
// Note: We don't finish() immediately so we can cleanup in onResume()
427+
Intent chooser = Intent.createChooser(shareIntent, getString(R.string.share_chooser_title));
428+
// The chooser itself is a separate process; it also needs the flag so it
429+
// can forward the URI to whichever app the user picks.
430+
chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
431+
432+
sharingInitiated = true;
417433
SentryManager.log("Launching share intent");
418-
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_chooser_title)));
434+
startActivityForResult(chooser, REQUEST_SHARE);
419435
} else {
420-
// Handle case where processing didn't produce a valid file
421436
SentryManager.log("Cleaned file URI is null");
422437
finishWithError("Failed to get cleaned file");
423438
}
424439
} catch (Exception e) {
425-
// Log and handle any errors during sharing
426440
SentryManager.recordException(e);
427441
finishWithError("Error sharing clean file: " + e.getMessage());
428442
}
429443
}
430444

431445
/**
432-
* Called when the activity is paused (e.g., when share chooser is shown).
433-
* This is where we can detect that sharing has started.
446+
* Called when the share chooser returns. This is the correct place to clean up
447+
* the temporary file — it fires only after the chooser is fully dismissed, so the
448+
* receiving app has already obtained its copy of the file via the FileProvider URI.
434449
*/
435450
@Override
436-
protected void onPause() {
437-
super.onPause();
438-
// When activity pauses, it means the share chooser or target app is shown
439-
// We'll cleanup when the activity resumes (user returns from sharing)
440-
}
441-
442-
/**
443-
* Called when the activity resumes (e.g., when user returns from share chooser).
444-
* This is where we cleanup the temporary file after sharing is complete.
445-
*/
446-
@Override
447-
protected void onResume() {
448-
super.onResume();
449-
450-
// If sharing was initiated and we're resuming, it means the user has
451-
// interacted with the share chooser (either shared or cancelled)
452-
// Clean up the temporary file now
453-
if (sharingInitiated) {
451+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
452+
super.onActivityResult(requestCode, resultCode, data);
453+
if (requestCode == REQUEST_SHARE) {
454+
SentryManager.log("Share chooser returned, cleaning up");
454455
cleanupProcessedFile();
455-
// Finish the activity since sharing is complete
456456
finish();
457457
}
458458
}
459-
459+
460+
460461
/**
461462
* Deletes the temporary processed file from disk.
462463
* This is called after sharing completes to avoid saving files to disk.

app/src/main/res/values-night/themes.xml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<resources>
2-
<!-- Main theme -->
2+
<!-- Main theme (night) -->
33
<style name="Theme.Redact" parent="Theme.Material3.DayNight.NoActionBar">
44
<item name="colorPrimary">@color/primary</item>
55
<item name="colorPrimaryDark">@color/primary_dark</item>
@@ -13,8 +13,10 @@
1313
<item name="bottomNavigationStyle">@style/Widget.Redact.BottomNavigationView</item>
1414
</style>
1515

16-
<!-- Transparent theme for ShareHandlerActivity -->
17-
<style name="Theme.Transparent" parent="Theme.MaterialComponents.DayNight.NoActionBar">
16+
<!-- Transparent theme for ShareHandlerActivity (night).
17+
Must inherit Material3 (not MaterialComponents/Material2) so dialog_progress.xml
18+
can resolve ?attr/colorSurfaceContainerHigh, textAppearanceBodyMedium, etc. -->
19+
<style name="Theme.Transparent" parent="Theme.Material3.DayNight.NoActionBar">
1820
<item name="android:windowIsTranslucent">true</item>
1921
<item name="android:windowBackground">@android:color/transparent</item>
2022
<item name="android:windowContentOverlay">@null</item>

app/src/main/res/values/themes.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
<item name="bottomNavigationStyle">@style/Widget.Redact.BottomNavigationView</item>
1414
</style>
1515

16-
<!-- Transparent theme for ShareHandlerActivity -->
17-
<style name="Theme.Transparent" parent="Theme.MaterialComponents.DayNight.NoActionBar">
16+
<!-- Transparent theme for ShareHandlerActivity.
17+
Must inherit Material3 (not MaterialComponents/Material2) so dialog_progress.xml
18+
can resolve ?attr/colorSurfaceContainerHigh, textAppearanceBodyMedium, etc. -->
19+
<style name="Theme.Transparent" parent="Theme.Material3.DayNight.NoActionBar">
1820
<item name="android:windowIsTranslucent">true</item>
1921
<item name="android:windowBackground">@android:color/transparent</item>
2022
<item name="android:windowContentOverlay">@null</item>

0 commit comments

Comments
 (0)