{"record":{"id":"cccfb2bbb77c0767","repo":"MuntashirAkon/AppManager","slug":"uri-inaccessible-or-empty","errorCode":null,"errorMessage":"Uri inaccessible or empty.","messagePattern":"Uri inaccessible or empty\\.","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/utils/FileUtils.java","lineNumber":71,"sourceCode":"            byte[] headerBytes = new byte[4];\n            is.read(headerBytes);\n            header = new BigInteger(headerBytes).intValue();\n        }\n        return header == 0x504B0304 || header == 0x504B0506 || header == 0x504B0708;\n    }\n\n    @AnyThread\n    @NonNull\n    public static String getFilenameFromZipEntry(@NonNull ZipEntry zipEntry) {\n        return Paths.getLastPathSegment(zipEntry.getName());\n    }\n\n    @NonNull\n    public static ParcelFileDescriptor getFdFromUri(@NonNull Context context, @NonNull Uri uri, String mode)\n            throws FileNotFoundException {\n        ParcelFileDescriptor fd = context.getContentResolver().openFileDescriptor(uri, mode);\n        if (fd == null) {\n            throw new FileNotFoundException(\"Uri inaccessible or empty.\");\n        }\n        return fd;\n    }\n\n    @AnyThread\n    @NonNull\n    public static File getFileFromFd(@NonNull ParcelFileDescriptor fd) {\n        return new File(\"/proc/self/fd/\" + fd.getFd());\n    }\n\n    @AnyThread\n    public static void deleteSilently(@Nullable Path path) {\n        if (path == null || !path.exists()) return;\n        if (!path.delete()) {\n            Log.w(TAG, \"Unable to delete %s\", path);\n        }\n    }\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/utils/FileUtils.java#L53-L89","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nParcelFileDescriptor fd = FileUtils.getFdFromUri(context, uri, \"r\");\n// after\nParcelFileDescriptor fd;\ntry {\n    fd = FileUtils.getFdFromUri(context, uri, \"r\");\n} catch (FileNotFoundException e) {\n    Toast.makeText(context, R.string.uri_no_longer_accessible, Toast.LENGTH_LONG).show();\n    launchDocumentPicker(); // re-acquire the Uri\n    return;\n}","handlingStrategy":"try-catch","validationCode":"// check the Uri still resolves before opening\ntry (Cursor c = context.getContentResolver().query(uri, null, null, null, null)) {\n    if (c == null || !c.moveToFirst()) {\n        // Uri no longer accessible; re-acquire via SAF picker\n    }\n}","typeGuard":"boolean isUriOpenable(Context ctx, Uri uri) {\n    try (ParcelFileDescriptor pfd = ctx.getContentResolver().openFileDescriptor(uri, \"r\")) {\n        return pfd != null;\n    } catch (FileNotFoundException | SecurityException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    pfd = FileUtils.getFdFromUri(context, uri, \"r\");\n} catch (FileNotFoundException e) {\n    promptUserToReSelectFile();\n}","preventionTips":["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"],"tags":["android","contentresolver","uri","file-io"],"backgroundTag":"resource-not-found","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}