如何在 Android 11 和 12 中获取 PDF 文件路径

How to get PDF File Path In Android 11 and 12

我尝试了很多代码来获取 android 11 或 12 中的 pdf 路径,但只适用于 android 10 或以下设备。 你能帮我么?我分享我的行代码

意向这样调用

Intent intent = new Intent();
            intent.setType("application/pdf");
            statusAdapter = "pdf";
            pos = position;
            intent.setAction(Intent.ACTION_GET_CONTENT);
            someActivityResultLauncher.launch(Intent.createChooser(intent, "Select PDF"));

someActivityResultLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == Activity.RESULT_OK) {
                        // There are no request codes
                        Intent data = result.getData();
                        if (data == null) {
                            //error
                            return;
                        }
                        try {
                            final Uri pdfUri= data.getData();
                            File pdfFile = new File(getPath(pdfUri));
                            long length = pdfFile.length();
                            length = length / 1024;
                            Toast.makeText(CreateSubEventActivity.this, "File Path : " + pdfFile.getPath() + ", File size : " + length + " KB", Toast.LENGTH_SHORT).show();
//                            uploadFile(imageFile);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Toast.makeText(CreateSubEventActivity.this, "Something went wrong", Toast.LENGTH_LONG).show();
                        }
                    }
                });

像这样调用getPath

public String getPath(Uri uri) {
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        if (cursor == null) return null;
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String s = cursor.getString(column_index);
        cursor.close();
        return s;
    }

让我分享一下我在阅读所有内容后修复此问题的经验。

从 URI 获取输入流

final Uri pdfUri= data.getData();
getContentResolver().openInputStream(pdfUri)

然后用 InputStream 做你的事情,就像我用 okHttp 上传 pdf 一样

try {

RequestBody pdffile = new RequestBody() {
    @Override public MediaType contentType() { return MediaType.parse("application/pdf"); }
    @Override public void writeTo(BufferedSink sink) throws IOException {
        Source source = null;
        try {
            source = Okio.source(inputStream);
            sink.writeAll(source);
        } finally {
            Util.closeQuietly(source);
        }
    }
    @Override
    public long contentLength() {
        try {
            return inputStream.available();
        } catch (IOException e) {
            return 0;
        }
    }
};

RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
        .addFormDataPart("file", "fname.pdf", pdffile)
        //.addFormDataPart("Documents", value) // uncomment if you want to send Json along with file
        .build();

Request request = new Request.Builder()
        .url(serverURL)
        .post(requestBody)
        .build();

OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).writeTimeout(180, TimeUnit.SECONDS).readTimeout(180, TimeUnit.SECONDS)
        .addInterceptor(chain -> {
            Request original = chain.request();
            Request.Builder builder = original.newBuilder().method(original.method(), original.body());
            builder.header("key", key);
            return chain.proceed(builder.build());
        })
        .build();

client.newCall(request).enqueue(new Callback() {

    @Override
    public void onFailure(final Call call, final IOException e) {
        // Handle the error
        setIsLoading(false);
        getNavigator().uploadIssue("Facing some issue to upload this file.");
    }

    @Override
    public void onResponse(final Call call, final Response response) throws IOException {
        setIsLoading(false);
        if (!response.isSuccessful()) {
            getNavigator().uploadIssue("Facing some issue to upload this file.");

        }else {
            // Upload successful
            getNavigator().uploadedSucessfully();
        }

    }
});

return true;
} catch (Exception ex) {
    // Handle the error
    ex.printStackTrace();
}

如果您想访问一个文件或想要一个从 MediaStore 返回的 Uri 的文件路径,我有一个 library 可以处理您可能遇到的所有异常。这包括磁盘、内部和可移动磁盘上的所有文件。例如,当从 Dropbox 选择一个文件时,该文件将被复制到您具有完全访问权限的应用程序目录,然后将返回复制的文件路径。