我有按钮来附加文件
private void ImgAttach_Click(object sender, EventArgs e)
{
var _Intent = new Intent();
_Intent.SetType("*/*");
_Intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(_Intent, "Select File"), 0);
}
选择文件后,如果是图像,我可以获得真实路径。如果它不是图像(PDF,DOCX),则不起作用!例如,以下是选择图像后返回的路径:
"/storage/0403-0201/Pictures/beach_huts.jpg"
但选择文件后,会出现此错误
Android.Database.CursorIndexOutOfBoundsException:请求索引0, 大小为0
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok)
{
Android.Net.Uri selectedUri = data.Data;
////////////////////////
string s = GetRealPathFromURI(selectedUri);
}
}
private string GetRealPathFromURI(Android.Net.Uri contentURI)
{
Android.Database.ICursor cursor = ContentResolver.Query(contentURI, null, null, null, null);
cursor.MoveToFirst();
string documentId = cursor.GetString(0);
documentId = documentId.Split(':')[1];
cursor.Close();
cursor = ContentResolver.Query(
Android.Provider.MediaStore.Images.Media.ExternalContentUri,
null, Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new[] { documentId }, null);
cursor.MoveToFirst();
string path = cursor.GetString(cursor.GetColumnIndex(Android.Provider.MediaStore.Images.ImageColumns.Data));
cursor.Close();
return path;
}
答案 0 :(得分:2)
这是答案
/**
* 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.
* @author paulburke
*/
public static string GetRealPathFromURI(Context context,Android.Net.Uri uri)
{
bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;
// DocumentProvider
if (isKitKat && Android.Provider.DocumentsContract.IsDocumentUri(context, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
string docId = Android.Provider.DocumentsContract.GetDocumentId(uri);
string[] split = docId.Split(':');
string type = split[0];
if ("primary".Equals(type,StringComparison.OrdinalIgnoreCase))
{
return Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
string id = Android.Provider.DocumentsContract.GetDocumentId(uri);
Android.Net.Uri contentUri = ContentUris.WithAppendedId(Android.Net.Uri.Parse("content://downloads/public_downloads"), Convert.ToInt64(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri))
{
string docId = Android.Provider.DocumentsContract.GetDocumentId(uri);
string[] split = docId.Split(':');
string type = split[0];
Android.Net.Uri contentUri = null;
if ("image".Equals(type))
{
contentUri = Android.Provider.MediaStore.Images.Media.ExternalContentUri;
}
else if ("video".Equals(type))
{
contentUri = Android.Provider.MediaStore.Video.Media.ExternalContentUri;
}
else if ("audio".Equals(type))
{
contentUri = Android.Provider.MediaStore.Audio.Media.ExternalContentUri;
}
string selection = "_id=?";
string[] selectionArgs = new string[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".Equals(uri.Scheme,StringComparison.OrdinalIgnoreCase))
{
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".Equals(uri.Scheme,StringComparison.OrdinalIgnoreCase))
{
return uri.Path;
}
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,Android.Net.Uri uri, String selection,
String[] selectionArgs)
{
Android.Database.ICursor cursor = null;
string column = "_data";
string[] projection = {
column
};
try
{
cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.MoveToFirst())
{
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 bool isExternalStorageDocument(Android.Net.Uri uri)
{
return "com.android.externalstorage.documents".Equals(uri.Authority);
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
return "com.android.providers.downloads.documents".Equals(uri.Authority);
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static bool isMediaDocument(Android.Net.Uri uri)
{
return "com.android.providers.media.documents".Equals(uri.Authority);
}
答案 1 :(得分:1)
通常你会想要检查所选项目的mime类型,但这是处理媒体商店中不的项目的快速黑客:
string GetRealPathFromURI(Android.Net.Uri contentURI)
{
try
{
Android.Database.ICursor cursor = ContentResolver.Query(contentURI, null, null, null, null);
if (cursor != null)
{
cursor.MoveToFirst();
string documentId = cursor.GetString(0);
documentId = documentId.Split(':')[1];
cursor.Close();
cursor = ContentResolver.Query(Android.Provider.MediaStore.Images.Media.ExternalContentUri,
null,
Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new[] { documentId },
null);
cursor.MoveToFirst();
string path = cursor.GetString(cursor.GetColumnIndex(Android.Provider.MediaStore.Images.ImageColumns.Data));
cursor.Close();
return path;
}
return contentURI.Path;
}
catch (Android.Database.CursorIndexOutOfBoundsException ex)
{
return contentURI.Path;
}
}