如何在 Android Pie 中获取 pdf 文件的实际文件路径? [复制]
Posted
技术标签:
【中文标题】如何在 Android Pie 中获取 pdf 文件的实际文件路径? [复制]【英文标题】:How to get Actual file path of a pdf file in Android Pie? [duplicate] 【发布时间】:2019-05-27 22:34:31 【问题描述】:目前我面临无法检索 pdf 的实际文件路径的问题。我尝试了所有我得到的解决方案,但无法在 android Pie 中获得实际的文件路径。任何帮助都将不胜感激。
代码:- 意图打开文件管理器并允许选择pdf文件。
Intent intent = new Intent();
intent.setType("application/pdf");
intent.setAction(Intent.ACTION_GET_CONTENT);
String[] mimetypes = "application/pdf";
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(Intent.createChooser(intent, "Choose Pdf"), REQUEST_CODE_SELECT_IMAGE);
点击/选择任何 pdf 文件后编译器移动到 onActivityResult:-
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode)
case REQUEST_CODE_SELECT_IMAGE:
String template_file_uri = null;
String extension = null;
switch (resultCode)
case Activity.RESULT_OK:
try
String path = null;
if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
Uri selectedFileUri = data.getData();
String mimeType = getContentResolver().getType(selectedFileUri);
Log.e(TAG, "onActivityResult() REQUEST_CODE_SELECT_IMAGE RESULT_OK uri : " + selectedFileUri + " mimetype " + mimeType);
Log.e(TAG, ":::>>selectedFileUri::: " + selectedFileUri);
int lastDot = selectedFileUri.toString().lastIndexOf('.');
if (lastDot == -1)
// No dots - what do you want to do?
ApplicationHelper.showToast(activity, "Please select only pdf file !!!");
else
extension = selectedFileUri.toString().substring(lastDot);
Log.e(TAG, "extension: " + extension);
if (extension.equals(".pdf") || mimeType.equals("application/pdf"))
template_file_uri = selectedFileUri.toString();
displayFromUri(selectedFileUri);
getRealPathFromURI = ApplicationHelper.getRealPathFromURI(activity, selectedFileUri);
else
Log.e(TAG, "else ext: " + extension);
ApplicationHelper.showToast(activity, "Please select only pdf file !!!");
template_file_uri = null;
Log.e(TAG, "::::>>>getRealPathFromURI::: " + getRealPathFromURI);
else
Uri selectedFileUri = data.getData();
String path1 = getPath(activity, selectedFileUri);
catch (Exception e)
e.printStackTrace();
break;
case Activity.RESULT_CANCELED:
template_file_uri = null;
break;
default:
break;
break;
default:
break;
getRealPathFromURI 方法:-
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getRealPathFromURI(Context context, Uri uri)
Log.i(TAG, "getRealPathFromURI() uri " + uri);
String pattern = "/^[ A-Za-z0-9_@./#&+-]*$/";
uri = Uri.parse(uri.toString().replaceAll(pattern, uri.toString()));
String path = FileUtils.getPath(context, uri);
Log.i(TAG, "getRealPathFromURI() get path " + path);
if (ApplicationHelper.isStringValid(path))
if (!path.contains("://"))
path = "file://" + path;
path = path.replaceAll(pattern, path);
//path = path.replace(" ", "%20");
else
path = uri.toString();
Log.i(TAG, "getRealPathFromURI() return path " + path);
return path;
FileUtils:-
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri)
Log.i(TAG, "getPath() uri " + uri);
if (DEBUG)
Log.d(TAG + " File -",
"Authority: " + uri.getAuthority() +
", Fragment: " + uri.getFragment() +
", Port: " + uri.getPort() +
", Query: " + uri.getQuery() +
", Scheme: " + uri.getScheme() +
", Host: " + uri.getHost() +
", Segments: " + uri.getPathSegments().toString()
);
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isInternalStorageDocument(uri))
return uri.toString();
// DocumentProvider
else if (isKitKat && DocumentsContract.isDocumentUri(context, uri))
if (isExternalStorageDocument(uri))
final String docId = 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))
try
final String id = DocumentsContract.getDocumentId(uri);
// final long id = Long.parseLong(DocumentsContract.getDocumentId(uri));
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
Log.e(TAG, "Uri....");
return getDataColumn(context, contentUri, null, null);
catch (NumberFormatException e)
e.printStackTrace();
// MediaProvider
else if (isMediaDocument(uri))
final String docId = 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 the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
// File
else if ("file".equalsIgnoreCase(uri.getScheme()))
return uri.getPath();
else if (!ApplicationHelper.haveAuthority(uri))
return Constants.AUTHORITY_FILE + uri.toString();
return null;
【问题讨论】:
您可以在这里发布您所做的代码吗? 你需要什么文件路径?你不能只使用它的InputStream
吗?
如果遇到任何崩溃,请将代码与堆栈跟踪一起发布。
请查看更新后的问题。 @theapache64。我也使用了 InputStream 但没有得到任何东西。
请查看更新后的问题。 @ChintakPatel
【参考方案1】:
使用下面的类文件,只需传递 Uri 即可提供文件路径。
然后申请为
val filePathFromUri = FilePath.getPath(this, uri)
val file = File(filePathFromUri)
val absolutePath = file.absolutePath
在您的代码中,您可以在 onActivityResult()
中获取 Uri。
import android.annotation.TargetApi
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import java.util.*
object FilePath
val imageExts: ArrayList<String>
get()
val imageTypes = arrayOf("png", "jpg", "jpeg", "bmp", "gif")
val imageExts = imageTypes.indices.mapTo(ArrayList()) imageTypes[it]
return imageExts
val videoExts: ArrayList<String>
get()
val videoTypes = arrayOf("mpeg", "mp4", "gif", "wmv", "mov", "mpg", "3gp", "flv")
val videoExts = videoTypes.indices.mapTo(ArrayList()) videoTypes[it]
return videoExts
val docExts: ArrayList<String>
get()
val docTypes = arrayOf("doc", "docx", "pdf", "txt")
val docExts = docTypes.indices.mapTo(ArrayList()) docTypes[it]
return docExts
@TargetApi(Build.VERSION_CODES.KITKAT)
fun getPath(context: Context, uri: Uri): String?
val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri))
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile it.isEmpty() .toTypedArray()
val type = split[0]
if ("primary".equals(type, ignoreCase = true))
return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
else if (isDownloadsDocument(uri))
val decodedURI = Uri.decode(uri.toString())
if (decodedURI.contains("raw:"))
return decodedURI.substring(decodedURI.indexOf("raw:") + 4)
val id = DocumentsContract.getDocumentId(Uri.parse(decodedURI))
val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)!!)
return getDataColumn(context, contentUri, null, null)
else if (isMediaDocument(uri))
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile it.isEmpty() .toTypedArray()
val type = split[0]
var contentUri: Uri? = null
if ("image" == type)
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
else if ("video" == type)
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
else if ("audio" == type)
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
val selection = "_id=?"
val selectionArgs = arrayOf(split[1])
return getDataColumn(context, contentUri, selection, selectionArgs)
// MediaProvider
// DownloadsProvider
else if ("content".equals(uri.scheme, ignoreCase = true))
return getDataColumn(context, uri, null, null)
else if ("file".equals(uri.scheme, ignoreCase = true))
return uri.path
// File
// MediaStore (and general)
return null
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @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.
*/
fun getDataColumn(context: Context, uri: Uri?, selection: String?,
selectionArgs: Array<String>?): String?
var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(column)
try
cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
if (cursor != null && cursor.moveToFirst())
val column_index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(column_index)
finally
if (cursor != null)
cursor.close()
return null
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
fun isExternalStorageDocument(uri: Uri): Boolean
return "com.android.externalstorage.documents" == uri.authority
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
fun isDownloadsDocument(uri: Uri): Boolean
return "com.android.providers.downloads.documents" == uri.authority
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
fun isMediaDocument(uri: Uri): Boolean
return "com.android.providers.media.documents" == uri.authority
【讨论】:
你能发布一个Java的答案吗?以上是关于如何在 Android Pie 中获取 pdf 文件的实际文件路径? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 GPS 在后台 android Pie 中自动关闭?
FusedLocationProviderClient 在 Android Pie 9.0 中返回错误的纬度经度