当前,我面临着无法检索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;
}
答案 0 :(得分: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
}
}