我使用startActivityForResult Intent致电ACTION_GET_CONTENT。有些应用会使用此Uri返回数据:
内容://媒体/外部/图像/媒体/ 18122
我不知道它是图片,视频还是某些自定义内容。如何使用ContentResolver从此Uri获取实际文件名或内容标题?
答案 0 :(得分:14)
您可以通过修改投影
从此代码或任何其他字段获取文件名String[] projection = {MediaStore.MediaColumns.DATA};
ContentResolver cr = getApplicationContext().getContentResolver();
Cursor metaCursor = cr.query(uri, projection, null, null, null);
if (metaCursor != null) {
try {
if (metaCursor.moveToFirst()) {
path = metaCursor.getString(0);
}
} finally {
metaCursor.close();
}
}
return path;
答案 1 :(得分:14)
@ Durairaj的答案特定于获取文件的路径。如果你要搜索的是文件的实际名称(因为你应该使用内容解析,那么你可能会得到很多内容:// URIs)你'我需要做以下事情:
(从Durairaj复制的代码'答案和修改)
String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
Cursor metaCursor = cr.query(uri, projection, null, null, null);
if (metaCursor != null) {
try {
if (metaCursor.moveToFirst()) {
fileName = metaCursor.getString(0);
}
} finally {
metaCursor.close();
}
}
这里要注意的主要部分是我们正在使用MediaStore.MediaColumns.DISPLAY_NAME
,它会返回内容的实际名称。您也可以尝试MediaStore.MediaColumns.TITLE
,因为我不确定区别是什么。
答案 2 :(得分:5)
要获取文件名,您可以使用新的DocumentFile格式。
import { Component, Directive, Renderer2, ElementRef } from '@angular/core';
@Directive({
selector: '[scroller-directive]',
})
export class ScrollerDirective {
constructor(elRef: ElementRef, renderer: Renderer2) {
renderer.listen(elRef.nativeElement, 'wheel', (event) => {
const el = elRef.nativeElement;
const conditions = ((el.scrollTop + el.offsetHeight >= el.scrollHeight)) && event.deltaY > 0 || el.scrollTop === 0 && event.deltaY < 0;
if (conditions === true) {
event.preventDefault();
event.returnValue = false;
}
});
}
}
答案 3 :(得分:0)
private static String getRealPathFromURI(Context context, Uri contentUri)
{
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(context, contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String result = cursor.getString(column_index);
cursor.close();
return result;
}
答案 4 :(得分:0)
对于使用Kotlin遇到相同问题的任何人,您都可以定义一个扩展方法来一次获得文件名和大小(以字节为单位)。如果无法检索字段,则返回null。
fun Uri.contentSchemeNameAndSize(): Pair<String, Int>? {
return contentResolver.query(this, null, null, null, null)?.use { cursor ->
if (!cursor.moveToFirst()) return@use null
val name = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
val size = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.getString(name) to cursor.getInt(size)
}
}
如此使用
val nameAndSize = yourUri.contentNameAndSize()
// once you've confirmed that is not null, you can then do
val (name, size) = nameAndSize
可能 抛出异常,但对我来说从来没有这样做(只要URI是有效的content://
URI)。
答案 5 :(得分:0)
在阅读完此处给出的所有答案以及一些Airgram在其SDK中所做的工作后,我得出的结论是-我在Github上开源了该实用程序:
https://github.com/mankum93/UriUtilsAndroid/tree/master/app/src/main/java/com/androiduriutils
就像调用UriUtils.getDisplayNameSize()
一样简单。它提供了内容的名称和大小。
注意:仅适用于内容:// Uri
这里是代码的一瞥:
/**
* References:
* - https://www.programcreek.com/java-api-examples/?code=MLNO/airgram/airgram-master/TMessagesProj/src/main/java/ir/hamzad/telegram/MediaController.java
* - https://stackoverflow.com/questions/5568874/how-to-extract-the-file-name-from-uri-returned-from-intent-action-get-content
*
* @author Manish@bit.ly/2HjxA0C
* Created on: 03-07-2020
*/
public final class UriUtils {
public static final int CONTENT_SIZE_INVALID = -1;
/**
* @param context context
* @param contentUri content Uri, i.e, of the scheme <code>content://</code>
* @return The Display name and size for content. In case of non-determination, display name
* would be null and content size would be {@link #CONTENT_SIZE_INVALID}
*/
@NonNull
public static DisplayNameAndSize getDisplayNameSize(@NonNull Context context, @NonNull Uri contentUri){
final String scheme = contentUri.getScheme();
if(scheme == null || !scheme.equals(ContentResolver.SCHEME_CONTENT)){
throw new RuntimeException("Only scheme content:// is accepted");
}
final DisplayNameAndSize displayNameAndSize = new DisplayNameAndSize();
displayNameAndSize.size = CONTENT_SIZE_INVALID;
String[] projection = new String[]{MediaStore.Images.Media.DATA, OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE};
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
// Try extracting content size
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
if (sizeIndex != -1) {
displayNameAndSize.size = cursor.getLong(sizeIndex);
}
// Try extracting display name
String name = null;
// Strategy: The column name is NOT guaranteed to be indexed by DISPLAY_NAME
// so, we try two methods
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (nameIndex != -1) {
name = cursor.getString(nameIndex);
}
if (nameIndex == -1 || name == null) {
nameIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
if (nameIndex != -1) {
name = cursor.getString(nameIndex);
}
}
displayNameAndSize.displayName = name;
}
}
finally {
if(cursor != null){
cursor.close();
}
}
// We tried querying the ContentResolver...didn't work out
// Try extracting the last path segment
if(displayNameAndSize.displayName == null){
displayNameAndSize.displayName = contentUri.getLastPathSegment();
}
return displayNameAndSize;
}
}
答案 6 :(得分:-2)
您可以使用Durairaj提出的解决方案,将以下内容作为投影数组:
String[] projection = { "_data" };