Android reads built-in and external storage file content Uri

Record the process of Android reading the contents of built-in, external SD card and external USB files.

1. The first thing I thought of was to get the file path and read it through FileInputStream. It is found that the internal and external SD card paths are different, and it can also be realized through judgment. But reading the USB requires a permission application, and after the permission application, the system file does not display the USB content. It can only be displayed by reading the file or folder through the code. The path is still the same as the external SD card, so it is not easy to judge. Whether to use OTG to read the USB or directly read the external SD card, decisively gave up reading the content of the USB file, and only kept reading the content of the SD card.

2. Later, I thought about why Uri should be converted into a path, why not read the file content directly through Uri, try it when you think of it, and find that you don’t need to judge anything, whether it is a built-in or external SD card or an external USB, you can read it directly , couldn't be simpler. code show as below:

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_KML && resultCode == RESULT_OK && data != null) {
        String path = data.getData().getPath();
        if (path != null && (path.toUpperCase().endsWith(".KML") || path.toUpperCase().endsWith(".OVKML"))) {
            new Thread(() -> {
                try {
                    KmlReader reader = new KmlReader(kmlReaderCallback);
                    //Read the content of the file directly through Uri, no need to judge whether it is a built-in or external SD card or USB
                    InputStream inputStream = getContentResolver().openInputStream(data.getData());
                    reader.read(inputStream);
                } catch (IOException | XmlPullParserException e) {
                    e.printStackTrace();
                    Logs.e(e.toString());
                    AndroidUtilities.runOnUIThread(() -> ToastUtils.show(getString(R.string.file_open_error)));
                }
            }).start();
        } else {
            ToastUtils.show(getString(R.string.wrong_format));
        }
    }
}

3. Does anyone know why this is? View source code:

public final @Nullable InputStream openInputStream(@NonNull Uri uri)
        throws FileNotFoundException {
    Objects.requireNonNull(uri, "uri");
    // The Uri protocol obtained here has always been content, whether it is built-in or external storage 
    String scheme = uri.getScheme();
    if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
        // Note: left here to avoid breaking compatibility.  May be removed
        // with sufficient testing.
        OpenResourceIdResult r = getResourceId(uri);
        try {
            InputStream stream = r.r.openRawResource(r.id);
            return stream;
        } catch (Resources.NotFoundException ex) {
            throw new FileNotFoundException("Resource does not exist: " + uri);
        }
    } else if (SCHEME_FILE.equals(scheme)) {
        // Note: left here to avoid breaking compatibility.  May be removed
        // with sufficient testing.
        return new FileInputStream(uri.getPath());
    } else {
        // This is to read the file as an Asset resource file? 
        AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r", null);
        try {
            return fd != null ? fd.createInputStream() : null;
        } catch (IOException e) {
            throw new FileNotFoundException("Unable to create stream");
        }
    }
}
public FileInputStream createInputStream() throws IOException {
    if (mLength < 0) {
        // ParcelFileDescriptor.AutoCloseInputStream继承自FileInputStream
        return new ParcelFileDescriptor.AutoCloseInputStream(mFd);
    }
    // AutoCloseInputStream inherits from ParcelFileDescriptor.AutoCloseInputStream
    return new AutoCloseInputStream(this);
}

Guess you like

Origin blog.csdn.net/CHEN_ZL0125/article/details/128083414