Как найти путь к файлу для выбранного изображения с помощью C # в Xamarin.Android? - PullRequest
0 голосов
/ 07 ноября 2019

Я занимаюсь разработкой приложения для Android на платформе Xamarin.Android. Я развернул это на моем устройстве. Я пытаюсь получить путь к файлу выбранного изображения из моей галереи Android, но я получаю System.IO.DirectoryNotFoundException: 'Could not find a part of the path "/document/image:2547".'.

Я искал решения для этого, но ни одно из решений не помогло в моей ситуации.

Я исключу некоторый код, который не нужно показывать.

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    Android.Net.Uri uri = data.Data;
    string path = uri.Path;
    ImageView imageView = new ImageView(this);
    imageView.SetImageURI(uri);
    Blob.UploadFileInBlob(path);
}
public static class Blob
{
    public static async void UploadFileInBlob(string path)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse("[string here]");
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("images");
        await container.CreateIfNotExistsAsync();
        CloudBlockBlob blockBlob = container.GetBlockBlobReference("imageblob.jpg");
        await blockBlob.UploadFromFileAsync(@path);
    }
}

Я ожидаю, что файл изображения будет загружен в BLOB-объект на основе пути к файлу изображения. Однако я получаю ошибку System.IO.DirectoryNotFoundException: 'Could not find a part of the path "/document/image:2547".'. Само изображение по-прежнему отображается в приложении, когда оно выбрано.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2019

У меня сработало следующее:

private void AddImage_Click(object sender, EventArgs args)
{
    Intent intent = new Intent();
    intent.SetType("image/*");
    intent.SetAction(Intent.ActionGetContent);
    StartActivityForResult(Intent.CreateChooser(intent, "Select Picture"), 1);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    if ((requestCode == 1) && (resultCode == Result.Ok) && (data != null)
    {
        Android.Net.Uri uri = data.Data;
        string path = GetPathToImage(uri);
        Blob.UploadFileInBlob(path);
    }
}
private string GetPathToImage(Android.Net.Uri uri)
{
    ICursor cursor = ContentResolver.Query(uri, null, null, null, null);
    cursor.MoveToFirst();
    string document_id = cursor.GetString(0);
    if (document_id.Contains(":"))
        document_id = document_id.Split(':')[1];
    cursor.Close();

    cursor = ContentResolver.Query(
    MediaStore.Images.Media.ExternalContentUri,
    null, MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new string[] { document_id }, null);
    cursor.MoveToFirst();
    string path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data));
    cursor.Close();

    return path;
}
public class Blob
{
    public static async void UploadFileInBlob(string path)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse("[string here]");
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("[Your container here]");
        await container.CreateIfNotExistsAsync();
        CloudBlockBlob blockBlob = container.GetBlockBlobReference("[Your Blob reference here]");
        await blockBlob.UploadFromFileAsync(path);
    }
}

Примечание: Обязательно предоставьте READ_EXTERNAL_STORAGE под Требуемые разрешения в Манифест Android через свойства проекта. Кроме того, включите разрешение Storage на вашем устройстве для приложения. Не забудьте добавить расширение файла (например, jpg) в path или в любую переменную, которую вы используете.

0 голосов
/ 07 ноября 2019

Вы можете сослаться на мою другую ветку здесь , это должно быть полезно для вас. Основной код выглядит следующим образом:

метод OnActivityResult

protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
        if (resultCode == Result.Canceled)
        {
            Finish();
        }
        else
        {
            try
            {
            var _uri = data.Data;
            var filePath = IOUtil.getPath(this, _uri);

            if (string.IsNullOrEmpty(filePath))
                filePath = _uri.Path;

            var file = IOUtil.readFile(filePath);// here we can get byte array
        }
            catch (Exception readEx)
            {
                System.Diagnostics.Debug.Write(readEx);
            }
            finally
            {
                Finish();
            }
    }
}

IOUtil.cs

public class IOUtil
{
  public static string getPath(Context context, Android.Net.Uri uri)
{
    bool isKitKat = Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat;

    // DocumentProvider
    if (isKitKat && DocumentsContract.IsDocumentUri(context, uri))
    {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri))
        {
            var docId = DocumentsContract.GetDocumentId(uri);
            string[] split = docId.Split(':');
            var 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 = DocumentsContract.GetDocumentId(uri);
            Android.Net.Uri contentUri = ContentUris.WithAppendedId(
                    Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri))
        {
            var docId = DocumentsContract.GetDocumentId(uri);
            string[] split = docId.Split(':');
            var 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;
            }

            var selection = "_id=?";
            var 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;
}

public static string getDataColumn(Context context, Android.Net.Uri uri, string selection,
string[] selectionArgs)
{

    ICursor cursor = null;
    var 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);
}

public static byte[] readFile(string file)
{
    try
    {
        return readFile(new File(file));
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Write(ex);
        return new byte[0];
    }
 }

 public static byte[] readFile(File file)
 {
    // Open file
    var f = new RandomAccessFile(file, "r");

    try
    {
        // Get and check length
        long longlength = f.Length();
        var length = (int)longlength;

        if (length != longlength)
            throw new IOException("Filesize exceeds allowed size");
        // Read file and return data
        byte[] data = new byte[length];
        f.ReadFully(data);
        return data;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Write(ex);
        return new byte[0];
    }
    finally
    {
        f.Close();
    }
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...