如何从指向PDF文档的URI获取文件路径?

时间:2016-03-20 02:11:15

标签: android pdf

现在我的代码打开了默认下载视图,它只显示我下载的PDF。我选择了一个PDF文件,我得到了这个:

  

内容://com.android.providers.downloads.documents/document/1171

我想得到这个:

  

/storage/emulated/0/Download/ch22Databases.pdf

我的问题是如何在Android中执行此操作?

我的代码:

public void PDF() {
    PDF = (Button) findViewById(R.id.FindPDFBtn);//Finds the button in design and put it into a button variable.
    PDF.setOnClickListener(//Listens for a button click.
        new View.OnClickListener() {//Creates a new click listener.
            @Override
            public void onClick(View v) {//does what ever code is in here when the button is clicked
                Intent intent = new Intent();
                intent.setType("application/pdf");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Select a PDF "), SELECT_PDF);
            }
        }
    );
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    //PDF
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PDF) {
            Uri selectedUri_PDF = data.getData();
            SelectedPDF = getPDFPath(selectedUri_PDF);
        }
    }
}

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

6 个答案:

答案 0 :(得分:5)

在您的getPDFPath方法中添加以下代码段:

public String getPDFPath(Uri uri){

     final String id = DocumentsContract.getDocumentId(uri);
     final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

     String[] projection = { MediaStore.Images.Media.DATA };
     Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null);
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
     cursor.moveToFirst();
     return cursor.getString(column_index);
}

在您的情况下,此代码专门用于DownloadProvider的文档,以便进一步实施检查Paul Burke's answer。我个人使用他的aFileChooser library来避免这种问题。

答案 1 :(得分:1)

以下是两个解决方案

1)您可以使用以下代码。它可以处理任何类型的文件,也可以处理任何文件夹。

{
"cars" : {
   "chevrolet" : {
      "silverado" : {
         "id192874623" : true,
         "id786766663" : true
      }
   },
   "ford" : {
      "taurus" : {
         "id736273627" : true
      }
   },
   "honda" : {
      "accord" : {
         "id635263535" : true
      }
   }
}}

这是我浏览文件的最佳解决方案。

希望它会有所帮助。

另一种方式

2)我找到的另一个解决方案是

在Module {app

private String getPath(final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; if(isKitKat) { // MediaStore (and general) return getForApi19(uri); } else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } @TargetApi(19) private String getForApi19(Uri uri) { Log.e(tag, "+++ API 19 URI :: " + uri); if (DocumentsContract.isDocumentUri(this, uri)) { Log.e(tag, "+++ Document URI"); // ExternalStorageProvider if (isExternalStorageDocument(uri)) { Log.e(tag, "+++ External Document URI"); final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { Log.e(tag, "+++ Primary External Document URI"); return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { Log.e(tag, "+++ Downloads External Document URI"); final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { Log.e(tag, "+++ Media Document URI"); final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { Log.e(tag, "+++ Image Media Document URI"); contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { Log.e(tag, "+++ Video Media Document URI"); contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { Log.e(tag, "+++ Audio Media Document URI"); contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(contentUri, selection, selectionArgs); } } else if ("content".equalsIgnoreCase(uri.getScheme())) { Log.e(tag, "+++ No DOCUMENT URI :: CONTENT "); // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { Log.e(tag, "+++ No DOCUMENT URI :: FILE "); return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ public String getDataColumn(Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } 中添加依赖项
build.gradle

然后在您的代码中使用

compile 'in.gauriinfotech:commons:1.0.8'

确保您在String fullPath = Commons.getPath(uri, context);

中添加了以下权限
Manifest.xml

答案 2 :(得分:1)

  

我的问题是如何在Android中执行此操作?

你没有。 ACTION_GET_CONTENT与文件几乎没有关系。

如果您绝对需要文件use a file picker library,而不是ACTION_GET_CONTENT

如果您想使用ACTION_GET_CONTENT,请停止尝试获取内容的文件系统路径。如果ContentResolver具有openInputStream()Urifile方案,请使用contentandroid.resource来阅读内容的内容。如果Uri具有httphttps方案,请使用HTTP客户端API。

答案 3 :(得分:0)

Uri uri = intent.getData();

                String uriString = uri.toString();

                File myFile = new File(uriString);

                final String path = myFile.getAbsolutePath();

                String displayName = null;

                if (uriString.startsWith("content://")) {
                    Cursor cursor = null;
                    try {
                        cursor = getActivity().getContentResolver().query(uri, null, null, null, null);
                        if (cursor != null && cursor.moveToFirst()) {
                            displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                            tvFile.setVisibility ( View.VISIBLE );
                            tvFile.setText ( displayName );

                            final String finalDisplayName = displayName;
                            tvFile.setOnClickListener ( new View.OnClickListener () {
                                @Override
                                public void onClick(View v) {
                                    File dir = Environment.getExternalStorageDirectory();
                                    File yourFile = new File(dir, path+ finalDisplayName );

                                    Toast.makeText ( getActivity (),"hiiiii"+yourFile,Toast.LENGTH_SHORT ).show ();
                                }
                            } );
                            //Toast.makeText ( getActivity (),"hii"+displayName,Toast.LENGTH_LONG ).show ();
                        }
                    } finally {
                        cursor.close();
                    }
                } else if (uriString.startsWith("file://")) {
                    displayName = myFile.getName();
                   // Toast.makeText ( getActivity (),"hii"+displayName,Toast.LENGTH_LONG ).show ();
                }

答案 4 :(得分:-1)

这两条线对我有用

File dir = Environment.getExternalStorageDirectory();
File yourFile = new File(dir, path+ finalDisplayName );

答案 5 :(得分:-1)

请使用以下文件从URI获取路径

public class FileUtils {
    private static Uri filePathUri = null;


    public static String getPath(final Context context, final Uri uri) {
        filePathUri=uri;
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        final boolean isOreo=Build.VERSION.SDK_INT >= 26;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = getDocumentId(DocumentsContract.getDocumentId(uri));
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = getDocumentId(DocumentsContract.getDocumentId(uri));


                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));


                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = getDocumentId(DocumentsContract.getDocumentId(uri));
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;**strong text**
        final String column = "_data";
        final String[] projection = {
                column
        };
        FileInputStream input = null;
        FileOutputStream output = null;

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } catch (IllegalArgumentException e){
            e.printStackTrace();

            File file = new File(context.getCacheDir(), "tmp");
            String filePath = file.getAbsolutePath();

            try {
                ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(filePathUri, "r");
                if (pfd == null)
                    return null;

                FileDescriptor fd = pfd.getFileDescriptor();
                input = new FileInputStream(fd);
                output = new FileOutputStream(filePath);
                int read;
                byte[] bytes = new byte[4096];
                while ((read = input.read(bytes)) != -1) {
                    output.write(bytes, 0, read);
                }

                input.close();
                output.close();
                return new File(filePath).getAbsolutePath();
            } catch (IOException ignored) {
                ignored.printStackTrace();
            }
        } finally{
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }


    private static String getDocumentId(String id) {
        if (!TextUtils.isEmpty(id)) {
            if (id.startsWith("raw:")) {
                return id.replaceFirst("raw:", "");
            }

        }
        return id;
    }
}