MuntashirAkon/AppManager · error · FileNotFoundException
Uri inaccessible or empty.
Error message
Uri inaccessible or empty.
What it means
FileNotFoundException thrown by FileUtils.getFdFromUri when ContentResolver.openFileDescriptor returns null for the given Uri and mode. A null descriptor means the content provider could not supply a readable/writable file for the request — the Uri is inaccessible (no provider, revoked grant, missing file) or resolves to empty content.
Solutions
- Verify and re-acquire access: re-run the SAF picker (ACTION_OPEN_DOCUMENT) and takePersistableUriPermission for long-lived access
- Check ContentResolver.acquireContentProviderClient(uri) / query metadata before opening to confirm the Uri is still valid
- Ensure the requested mode ("r", "w") matches what the grant allows
- Catch FileNotFoundException around getFdFromUri and prompt the user to re-select the file
Example fix
// before
ParcelFileDescriptor fd = FileUtils.getFdFromUri(context, uri, "r");
// after
ParcelFileDescriptor fd;
try {
fd = FileUtils.getFdFromUri(context, uri, "r");
} catch (FileNotFoundException e) {
Toast.makeText(context, R.string.uri_no_longer_accessible, Toast.LENGTH_LONG).show();
launchDocumentPicker(); // re-acquire the Uri
return;
} Defensive patterns
Strategy: try-catch
Validate before calling
// check the Uri still resolves before opening
try (Cursor c = context.getContentResolver().query(uri, null, null, null, null)) {
if (c == null || !c.moveToFirst()) {
// Uri no longer accessible; re-acquire via SAF picker
}
} Type guard
boolean isUriOpenable(Context ctx, Uri uri) {
try (ParcelFileDescriptor pfd = ctx.getContentResolver().openFileDescriptor(uri, "r")) {
return pfd != null;
} catch (FileNotFoundException | SecurityException e) {
return false;
}
} Try / catch
try {
pfd = FileUtils.getFdFromUri(context, uri, "r");
} catch (FileNotFoundException e) {
promptUserToReSelectFile();
} Prevention
- Call takePersistableUriPermission with FLAG_GRANT_READ_URI_PERMISSION when using SAF
- Re-validate persisted Uris on startup instead of assuming they survive reboot/reinstall
- Match the open mode to the granted flags (read vs read-write)
- Handle provider revocation gracefully with a re-pick flow
When it happens
Trigger: Calling getFdFromUri with a content:// Uri whose provider is unavailable, whose granted permission (FLAG_GRANT_READ_URI_PERMISSION) was revoked or never granted, or with a mode the provider cannot honor; openFileDescriptor returns null instead of throwing and the helper converts it to FileNotFoundException.
Common situations: Persisted Uri permissions lost after app reinstall/reboot without takePersistableUriPermission; SAF Uri pointing to a deleted document; sharing a Uri from another app that no longer exports its provider.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Could not create BackupItem.
- Could not delete
- Could not move to
- Could not resolve Uri:
- Couldn't delete old file
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/cccfb2bbb77c0767.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/utils/FileUtils.java:71
byte[] headerBytes = new byte[4];
is.read(headerBytes);
header = new BigInteger(headerBytes).intValue();
}
return header == 0x504B0304 || header == 0x504B0506 || header == 0x504B0708;
}
@AnyThread
@NonNull
public static String getFilenameFromZipEntry(@NonNull ZipEntry zipEntry) {
return Paths.getLastPathSegment(zipEntry.getName());
}
@NonNull
public static ParcelFileDescriptor getFdFromUri(@NonNull Context context, @NonNull Uri uri, String mode)
throws FileNotFoundException {
ParcelFileDescriptor fd = context.getContentResolver().openFileDescriptor(uri, mode);
if (fd == null) {
throw new FileNotFoundException("Uri inaccessible or empty.");
}
return fd;
}
@AnyThread
@NonNull
public static File getFileFromFd(@NonNull ParcelFileDescriptor fd) {
return new File("/proc/self/fd/" + fd.getFd());
}
@AnyThread
public static void deleteSilently(@Nullable Path path) {
if (path == null || !path.exists()) return;
if (!path.delete()) {
Log.w(TAG, "Unable to delete %s", path);
}
}
View on GitHub (pinned to 0152f468fc)