Xamarin-Android:如何翻译类似于我刚刚保存文件的文件选择器路径,以便StreamReader工作
我刚刚使用以下创建的路径保存了一个文件:Xamarin-Android:如何翻译类似于我刚刚保存文件的文件选择器路径,以便StreamReader工作,android,xamarin,filepicker.io,Android,Xamarin,Filepicker.io,我刚刚使用以下创建的路径保存了一个文件: string documentsPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDocuments); fileName = System.IO.Path.Combine(documentsPath, fileData.FileName); 文件路径最终被保存并成功保存:/s
string documentsPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDocuments);
fileName = System.IO.Path.Combine(documentsPath, fileData.FileName);
文件路径最终被保存并成功保存:/storage/simulated/0/Documents/test.csv
我现在使用文件选择器选择文件,如下所示:
FileData fileData = await CrossFilePicker.Current.PickFile();
但返回的fileData.FilePath是:content://com.android.externalstorage.documents/document/home%3Atest.csv
如果将其卡在以下位置,则此路径不起作用:
StreamReader sr = new StreamReader (fileData.FilePath);
但是,如果我将上面.DirectoryDocuments中的路径与文件名一起使用,StreamReader将很好地打开它
所以,@livitos,如何将文件选择器路径转换为StreamReader可以使用的真实路径?您应该使用基于
流的Xamarin.Android
重载,它可以打开基于内容的uri://
,因为现代Android API级别会阻止您直接获取基于文件的uri://
安全问题:
System.IO.Stream.OpenInputStream (Android.Net.Uri uri);
此重载是从Android.Content.Contentresolver.Openinputstream转换而来的
关于:
如何将文件选择器路径转换为StreamReader可以使用的实际路径
我使用您的代码进行测试,但是我没有从fileData.FilePath获取content://uri,但是如果
要将文件选择器路径转换为实际路径,我建议您可以使用以下代码进行尝试
private string GetActualPathFromFile(Android.Net.Uri uri)
{
bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;
if (isKitKat && DocumentsContract.IsDocumentUri(this, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
string docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
string[] split = docId.Split(chars);
string type = split[0];
if ("primary".Equals(type, StringComparison.OrdinalIgnoreCase))
{
return Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
string id = DocumentsContract.GetDocumentId(uri);
Android.Net.Uri contentUri = ContentUris.WithAppendedId(
Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));
//System.Diagnostics.Debug.WriteLine(contentUri.ToString());
return getDataColumn(this, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri))
{
String docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
String[] split = docId.Split(chars);
String type = split[0];
Android.Net.Uri contentUri = null;
if ("image".Equals(type))
{
contentUri = MediaStore.Images.Media.ExternalContentUri;
}
else if ("video".Equals(type))
{
contentUri = MediaStore.Video.Media.ExternalContentUri;
}
else if ("audio".Equals(type))
{
contentUri = MediaStore.Audio.Media.ExternalContentUri;
}
String selection = "_id=?";
String[] selectionArgs = new String[]
{
split[1]
};
return getDataColumn(this, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.LastPathSegment;
return getDataColumn(this, uri, null, null);
}
// File
else if ("file".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
return uri.Path;
}
return null;
}
public static String getDataColumn(Context context, Android.Net.Uri uri, String selection, String[] selectionArgs)
{
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 index = cursor.GetColumnIndexOrThrow(column);
return cursor.GetString(index);
}
}
finally
{
if (cursor != null)
cursor.Close();
}
return null;
}
//Whether the Uri authority is ExternalStorageProvider.
public static bool isExternalStorageDocument(Android.Net.Uri uri)
{
return "com.android.externalstorage.documents".Equals(uri.Authority);
}
//Whether the Uri authority is DownloadsProvider.
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
return "com.android.providers.downloads.documents".Equals(uri.Authority);
}
//Whether the Uri authority is MediaProvider.
public static bool isMediaDocument(Android.Net.Uri uri)
{
return "com.android.providers.media.documents".Equals(uri.Authority);
}
//Whether the Uri authority is Google Photos.
public static bool isGooglePhotosUri(Android.Net.Uri uri)
{
return "com.google.android.apps.photos.content".Equals(uri.Authority);
}
更多详细信息,您可以查看:
@Livitos你知道吗?我明白了:流不包含“OpenInputStream”的定义@Sushihukoti,我有什么特别需要做的吗?Cherry,你得到了什么样的路径?@karhukoti,我尝试了你的代码,但我没有从fileData.FilePath获得content://uri,我只是得到了实际的路径,所以我没有要尝试的更改,你可以添加这个方法来尝试,看看它是否会返回你想要的路径。