C# Xamarin android将图像上载到azure blob的最佳方法?

C# Xamarin android将图像上载到azure blob的最佳方法?,c#,azure,xamarin,xamarin.android,azure-storage,C#,Azure,Xamarin,Xamarin.android,Azure Storage,我尝试了几件事都没有成功。最新版本的ive尝试使用一些在我的桌面上运行并提供图像真实路径的代码,但是当路径传递到Xamarin和我的android设备中的相同方法时,所选图像不会上传,也不会出现错误 谁知道问题可能是什么(错误的文件路径或其他完全错误的东西),或者有其他方法执行此任务 下面是相关的代码,上面的部分只在我的Xamarin项目中使用,我知道下面的部分在我的桌面上使用手动传入的路径运行时可以工作 //这部分处理从手机获取图像及其数据,但是图像的路径似乎与手动浏览文件时不同 pr

我尝试了几件事都没有成功。最新版本的ive尝试使用一些在我的桌面上运行并提供图像真实路径的代码,但是当路径传递到Xamarin和我的android设备中的相同方法时,所选图像不会上传,也不会出现错误

谁知道问题可能是什么(错误的文件路径或其他完全错误的东西),或者有其他方法执行此任务

下面是相关的代码,上面的部分只在我的Xamarin项目中使用,我知道下面的部分在我的桌面上使用手动传入的路径运行时可以工作

//这部分处理从手机获取图像及其数据,但是图像的路径似乎与手动浏览文件时不同

    private void BtnClickFindImage(object sender, EventArgs e)
    {
        Intent = new Intent();
        Intent.SetType("image/*");
        Intent.SetAction(Intent.ActionGetContent);
        StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), PickImageId);
    }
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        if ((requestCode == PickImageId) && (resultCode == Result.Ok) && (data != null))
        {
            Android.Net.Uri uri = data.Data;
            recipeImagePreview.SetImageURI(uri);

            var path = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            var fullPath = Path.Combine(path.ToString(), "IMG_20180701_105406608.jpg");
            Manager_AzureServer_RecipeImages.PushFilTilWebsite(fullPath);
        }
    }
//这一部分将文件推送到我的Azure存储单元,从我的桌面运行时,它就像一个魔咒,但是在我的android设备上运行时,没有文件被上传。要么路径不工作,要么由于某种原因代码在android上不工作,要么甚至可能存在某种android规则,默认情况下不允许从设备上传图像

        public static void PushFilTilWebsite(string _imagePath)
    {       
        ProcessAsync(_imagePath);
    }

    private static async Task ProcessAsync(string _imagePath)
    {
        CloudStorageAccount storageAccount = null;
        CloudBlobContainer cloudBlobContainer = null;

        // Retrieve the connection string for use with the application. The storage connection string is stored
        // in an environment variable on the machine running the application called storageconnectionstring.
        // If the environment variable is created after the application is launched in a console or with Visual
        // Studio, the shell needs to be closed and reloaded to take the environment variable into account.
        // Encrypt den her før release.
        string storageConnectionString = "XXX";

        // Check whether the connection string can be parsed.
        if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
        {
            try
            {
                // Create the CloudBlobClient that represents the Blob storage endpoint for the storage account.
                CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();

                // Create a container called 'quickstartblobs' and append a GUID value to it to make the name unique. 
                //cloudBlobContainer = cloudBlobClient.GetContainerReference("quickstartblobs" + Guid.NewGuid().ToString());
                cloudBlobContainer = cloudBlobClient.GetContainerReference("lghrecipeimages");

                // Set the permissions so the blobs are public. 
                BlobContainerPermissions permissions = new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Blob
                };
                await cloudBlobContainer.SetPermissionsAsync(permissions);

                // Get a reference to the blob address, then upload the file to the blob.
                // Use the value of localFileName for the blob name.
                CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference("test image upload2");
                await cloudBlockBlob.UploadFromFileAsync(_imagePath);

                finishedPushingToServer = true;                
            }
            catch (StorageException ex)
            {
                Console.WriteLine("Error returned from the service: {0}", ex.Message);
            }
            finally
            {
            }
        }
        else
        {
        }
        string test = "";
    }

问题是您没有使用正确的图像路径

您可以从文件选择器意图中获取Uri,但是除了预览之外,您不使用该Uri。此Uri需要转换为外部存储器中的实际路径

私有字符串GetFilePathFromUri(Android.Net.Uri)
{
字符串[]列={MediaStore.Images.ImageColumns.Data};
var cursorLoader=new cursorLoader(this,uri,column,null,null,null);
ICursor cursor=cursorLoader.LoadInBackground()作为ICursor;
字符串filePath=null;
如果(光标!=null)
{
var columnIndex=cursor.GetColumnIndexOrThrow(MediaStore.Images.ImageColumns.Data);
cursor.MoveToFirst();
filePath=cursor.GetString(columnIndex);
}
返回文件路径;
}
这将转换您的Uri,它看起来像
content://media/images/external/1234
指向如下文件路径:
/storage/emulated/0/DCIM/Camera/IMG\u 20180718\u 071002.jpg


您可以将此文件路径交给Azure Storage SDK进行上传。

感谢Cheesebaron为我指明了正确的方向,我现在可以使用它了! 问题是我缺少在设备上使用外部存储所需的权限。下面我发布了为我修复它的代码,简短的解释:如果应用程序没有使用外部存储的权限,提示请求此权限,一旦用户接受,外部存储就可以使用

请随意使用下面的工作代码,干杯

       private void BtnClickFindImage(object sender, EventArgs e)
    {
        if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted)
        {
            Toast.MakeText(this, "We already have this permission!", ToastLength.Short).Show();
        }
        else
        {  
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.SetTitle("Permission needed!");
            alert.SetMessage("The pplication need special permission to continue");
            alert.SetPositiveButton("Request permission", (senderAlert, args) =>
            {
                RequestPermissions(PermissionsGroupLocation, RequestReadExternalStorageId);
            });

            alert.SetNegativeButton("Cancel", (senderAlert, args) =>
            {
                Toast.MakeText(this, "Cancelled!", ToastLength.Short).Show();
            });

            Dialog dialog = alert.Create();
            dialog.Show();

            return;
        }

        Intent = new Intent();
        Intent.SetType("image/*");
        Intent.SetAction(Intent.ActionGetContent);
        StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), PickImageId);
    }

    #region RuntimePermissions

    async Task TryToGetPermissions()
    {
        if ((int)Build.VERSION.SdkInt >= 23) // Android 7.0 - API 24 er min mobil
        {
            await GetPermissionsAsync();
            return;
        }
    }
    const int RequestReadExternalStorageId = 0;

    readonly string[] PermissionsGroupLocation =
        {
                        //TODO add more permissions
                        Manifest.Permission.ReadExternalStorage,
         };
    async Task GetPermissionsAsync()
    {
        const string permission = Manifest.Permission.ReadExternalStorage;

        if (CheckSelfPermission(permission) == (int)Android.Content.PM.Permission.Granted)
        {
            //TODO change the message to show the permissions name
            Toast.MakeText(this, "Special permissions granted", ToastLength.Short).Show();
            return;
        }

        if (ShouldShowRequestPermissionRationale(permission))
        {
            //set alert for executing the task
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.SetTitle("Permissions Needed");
            alert.SetMessage("The application need special permissions to continue");
            alert.SetPositiveButton("Request Permissions", (senderAlert, args) =>
            {
                RequestPermissions(PermissionsGroupLocation, RequestReadExternalStorageId);
            });

            alert.SetNegativeButton("Cancel", (senderAlert, args) =>
            {
                Toast.MakeText(this, "Cancelled!", ToastLength.Short).Show();
            });

            Dialog dialog = alert.Create();
            dialog.Show();


            return;
        }

        RequestPermissions(PermissionsGroupLocation, RequestReadExternalStorageId);

    }
    public override async void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        switch (requestCode)
        {
            case RequestReadExternalStorageId:
                {
                    if (grantResults[0] == (int)Android.Content.PM.Permission.Granted)
                    {
                        Toast.MakeText(this, "Special permissions granted", ToastLength.Short).Show();

                    }
                    else
                    {
                        //Permission Denied :(
                        Toast.MakeText(this, "Special permissions denied", ToastLength.Short).Show();

                    }
                }
                break;
        }
        //base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }

请不要将代码作为图像发布!我用图像显示它的原因是为了可以画线来澄清问题。@user10094935使用代码中的注释来澄清问题请删除图像。在这两种情况下是否都附加了调试器?看到了路径的不同吗?另外,Android应用程序中是否有允许上传的权限?请使用调试器或fiddler检索详细消息,如imagepath。我尝试了此操作,filePath返回null。但是,我尝试直接传入正确的文件路径,并检查了路径上是否存在文件,确实存在,因此路径应该是好的,而不是看起来的问题。但是,该文件仍然没有上传。。我开始觉得在我的手机上有一些安全规则或类似的东西阻止上传。。。。fullPath=“/storage/simulated/0/DCIM/Camera/IMG_20180701_105406608.jpg”;bool exists2=File.Exists(完整路径);Manager\u AzureServer\u RecipeImages.PushFilTilWebsite(完整路径);你请求外部存储许可了吗?没有,我现在就去试试,我想我在这里不知所措