Android: 文件获取 URI 来自内容 URI?

在我的应用程序中,用户必须选择音频文件,然后由应用程序处理。 问题是,为了使应用程序执行我希望它与音频文件进行的操作,我需要 URI 它处于文件格式。 当我使用本土音乐播放器时 Android 要搜索应用程序中的音频文件, URI - 这是内容 URI, 这看起来像这样:


content://media/external/audio/media/710


但是,使用流行的文件应用程序 Astro, 我得到以下内容:


file:///sdcard/media/audio/ringtones/GetupGetOut.mp3


后者对我来说更易于访问,但是,当然,我希望应用程序具有与选择用户的音频文件的功能,而不管它用于查看其集合的程序。 所以,我的问题是是否有一种转换样式的方法
content://

URI 在
file://

URI? 否则,你建议我如何解决这个问题? 以下是调用选择工具供参考的代码:


Intent ringIntent = new Intent//;
ringIntent.setType/"audio/mp3"/;
ringIntent.setAction/Intent.ACTION_GET_CONTENT/;
ringIntent.addCategory/Intent.CATEGORY_OPENABLE/;
startActivityForResult/Intent.createChooser/ringIntent, "Select Ringtone"/, SELECT_RINGTONE/;


我用内容做了以下操作 URI:


m_ringerPath = m_ringtoneUri.getPath//;
File file = new File/m_ringerPath/;


然后做点什么 FileInputStream 使用此文件。
已邀请:

涵秋

赞同来自:

刚使用
getContentResolver//.openInputStream/uri/

, 获得
InputStream

的 URI.

http://developer.android.com/r ... %2529
/

郭文康

赞同来自:

这是一个旧的答案,具有过时的和黑客方式来克服内容内容的一些特定疼痛点。 用几个巨大的盐谷物服用并使用右侧 openInputStream API, 如果这通常是可能的。

您可以使用内容识别器来实现方式
file://


content://

URI:


String filePath = null;
Uri _uri = data.getData//;
Log.d/"","URI = "+ _uri/;
if /_uri != null && "content".equals/_uri.getScheme//// {
Cursor cursor = this.getContentResolver//.query/_uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null/;
cursor.moveToFirst//;
filePath = cursor.getString/0/;
cursor.close//;
} else {
filePath = _uri.getPath//;
}
Log.d/"","Chosen path = "+ filePath/;

江南孤鹜

赞同来自:

如果你有内容 Uri 从
content://com.externalstorage...

, 您可以使用此方法获取文件夹或文件的绝对路径。

在 Android 19 或更高

.


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// {
System.out.println/"getPath// uri: " + uri.toString///;
System.out.println/"getPath// uri authority: " + uri.getAuthority///;
System.out.println/"getPath// uri path: " + uri.getPath///;

// ExternalStorageProvider
if /"com.android.externalstorage.documents".equals/uri.getAuthority//// {
final String docId = DocumentsContract.getDocumentId/uri/;
final String[] split = docId.split/":"/;
final String type = split[0];
System.out.println/"getPath// docId: " + docId + ", split: " + split.length + ", type: " + type/;

// This is for checking Main Memory
if /"primary".equalsIgnoreCase/type// {
if /split.length > 1/ {
return Environment.getExternalStorageDirectory// + "/" + split[1] + "/";
} else {
return Environment.getExternalStorageDirectory// + "/";
}
// This is for checking SD Card
} else {
return "storage" + "/" + docId.replace/":", "/"/;
}

}
}
return null;
}


你可以检查每个部分 Uri 用途 println. 返回我的卡的值 SD 下面列出了设备的主存储器。 如果在内存中,您可以访问和删除文件,但我不能

从卡中删除文件

SD 通过这种方法,只读或打开
使用此绝对路径的D图像。 如果您找到了使用此方法删除的解决方案,请分享它。
SD卡


getPath// uri: content://com.android.externalstorage.documents/tree/612E-B7BF%3A/document/612E-B7BF%3A
getPath// uri authority: com.android.externalstorage.documents
getPath// uri path: /tree/612E-B7BF:/document/612E-B7BF:
getPath// docId: 612E-B7BF:, split: 1, type: 612E-B7BF


主记忆


getPath// uri: content://com.android.externalstorage.documents/tree/primary%3A/document/primary%3A
getPath// uri authority: com.android.externalstorage.documents
getPath// uri path: /tree/primary:/document/primary:
getPath// docId: primary:, split: 1, type: primary


如果你想得到 Uri 从
file:///

收到路径后,使用


DocumentFile documentFile = DocumentFile.fromFile/new File/path//;
documentFile.getUri// // will return a Uri with file Uri

知食

赞同来自:

尝试处理 URI 通过 content:// scheme, 打电话
ContentResolver.query//

, 不是一个好的解决方案。 在 HTC Desire 被...统治 4.2.2 你可以得到 NULL 作为查询结果。

为什么不使用 ContentResolver?

郭文康

赞同来自:

灵感答案

&

. 已经回答的方法的尝试导致我决定,主要涵盖光标的转换 null cases & 的

content:/ /

to

file

://

要转换文件, read&write 收到的文件 uri


public static Uri getFilePathFromUri/Uri uri/ throws IOException {
String fileName = getFileName/uri/;
File file = new File/myContext.getExternalCacheDir//, fileName/;
file.createNewFile//;
try /OutputStream outputStream = new FileOutputStream/file/;
InputStream inputStream = myContext.getContentResolver//.openInputStream/uri// {
FileUtil.copyStream/inputStream, outputStream/; //Simply reads input to output stream
outputStream.flush//;
}
return Uri.fromFile/file/;
}


要获取文件名,它将覆盖光标案例 null


public static String getFileName/Uri uri/ {
String fileName = getFileNameFromCursor/uri/;
if /fileName == null/ {
String fileExtension = getFileExtension/uri/;
fileName = "temp_file" + /fileExtension != null ? "." + fileExtension : ""/;
} else if /!fileName.contains/"."// {
String fileExtension = getFileExtension/uri/;
fileName = fileName + "." + fileExtension;
}
return fileName;
}


类型有一个很好的转换选项。 mime 在文件扩展名中


public static String getFileExtension/Uri uri/ {
String fileType = myContext.getContentResolver//.getType/uri/;
return MimeTypeMap.getSingleton//.getExtensionFromMimeType/fileType/;
}


游标接收文件名


public static String getFileNameFromCursor/Uri uri/ {
Cursor fileCursor = myContext.getContentResolver//.query/uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null/;
String fileName = null;
if /fileCursor != null && fileCursor.moveToFirst/// {
int cIndex = fileCursor.getColumnIndex/OpenableColumns.DISPLAY_NAME/;
if /cIndex != -1/ {
fileName = fileCursor.getString/cIndex/;
}
}
return fileName;
}

君笑尘

赞同来自:

好吧,我有点迟到了答案,但我的代码已被验证

计划检查 uri:


byte[] videoBytes;

if /uri.getScheme//.equals/"content"//{
InputStream iStream = context.getContentResolver//.openInputStream/uri/;
videoBytes = getBytes/iStream/;
}else{
File file = new File/uri.getPath///;
FileInputStream fileInputStream = new FileInputStream/file/;
videoBytes = getBytes/fileInputStream/;
}


在上面的答案中,我转换了视频 uri 在一系列字节中 , 但这与问题无关,
我刚刚复制了我的完整代码来显示使用
FileInputStream


InputStream

, 因为他们两个同样在我的代码中工作。

我使用了一个变量的上下文,我的片段是平等的 getActivity//, 和行动,只是 ActivityName.this


context=getActivity//;

//in 分段


context=ActivityName.this;

// 在行动中

要回复问题请先登录注册