android选择指定文件路径无效,解决android4.4以上机型选择文件返回路径无法正常读取文件的问题...

问题:

android4.4以上机型选择文件返回路径无法正常读取文件, 在选择系统文件的时候,返回的文件路径如下:/document/primary:Download/myfolder/test.txt

解决:

经转换后:/storage/emulated/0/Download/myfolder/test.txt

使用代码:

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

// super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK) {

if (requestCode == 2) {

Uri uri = data.getData();

Log.i("wakkk","开始文件路径:"+uri.getPath().toString()+"----转换后文件路径:"+UriUtils.getPath(context,uri));

}

}

解决代码:

package com.example.otasample;

import android.annotation.SuppressLint;

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;

@SuppressLint("NewApi")

public class UriUtils {

/**

* Get a file path from a Uri. This will get the the path for Storage Access

* Framework Documents, as well as the _data field for the MediaStore and

* other file-based ContentProviders.

*

* @param context The context.

* @param uri The Uri to query.

*/

public static String getPath(final Context context, final Uri uri) {

final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

// DocumentProvider

if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

// ExternalStorageProvider

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)) {

final String id = 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 = 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 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.

*/

public static String getDataColumn(Context context, Uri uri, String selection,

String[] selectionArgs) {

Cursor cursor = null;

final String column = "_data";

final String[] projection = {

column

};

try {

cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,

null);

if (cursor != null && cursor.moveToFirst()) {

final int 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.

*/

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());

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我之前回答的是 Java 语言的解决方法,而不是 JavaScript。由于 JavaScript 是一种脚本语言,通常用于 Web 前端开发,而不是 Android 开发,因此在 Android 应用程序中使用 JavaScript 解决 "exposed beyond app through Intent.getData()" 异常可能会比较困难。 不过,如果你的 Android 应用程序是基于 Web 技术开发的,比如使用 WebView 来加载网页,那么你可以通过 JavaScript 调用 Java 原生方法来解决这个问题。具体步骤如下: 1. 在 Java 中实现共享文件的逻辑,参考我之前的回答,使用 FileProvider 类来共享文件。 2. 在 AndroidManifest.xml 文件中为 FileProvider 添加一个 authorities: ``` <manifest> <application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="你的应用程序包名.fileprovider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ... </application> </manifest> ``` 3. 在 JavaScript 中创建一个 Java 对象,用于调用 Java 原生方法: ``` var fileProvider = window.AndroidFileProvider; ``` 这里的 AndroidFileProvider 是你在 Java 中实现共享文件逻辑的类名,需要在 Java 中声明为 public。 4. 在 JavaScript 中调用 Java 原生方法,将共享文件的 Uri 作为参数传递: ``` var uri = "共享文件的 Uri"; fileProvider.shareFile(uri); ``` 在 Java 中实现 shareFile 方法,参考我之前的回答,使用 Intent.FLAG_GRANT_READ_URI_PERMISSION 标记授予访问 Uri 的权限。 以上就是使用 JavaScript 调用 Java 原生方法解决 "exposed beyond app through Intent.getData()" 异常的步骤。需要注意的是,JavaScript 调用 Java 原生方法需要使用 Android 4.4 及以上版本才能支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值