简体   繁体   English

如何在Xamarin.android中的mashmallow中写入外部存储SD卡

[英]How to write on external storage sd card in mashmallow in xamarin.android

I started an Intent 我开始了一个意图

Intent = new Intent();
Intent.SetType("image/*");
Intent.PutExtra(Intent.ExtraAllowMultiple,true);
Intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), code);`

I am working with bitmap.Compress(...) function and took the uri from above intent. 我正在使用bitmap.Compress(...)函数,从上面的意图中获取了uri。 I want to delete that bitmap file and recreate the file with the same name (in short: Replacing the existing file). 我想删除该位图文件并重新创建具有相同名称的文件(简而言之:替换现有文件)。

My physical devices is Samsung J5 having Internal storage and external sd card storage like /storage/emulated/0/ and /storage/D660-18BD/ (D668-18BD is not fixed, it changes according to devices). 我的物理设备是Samsung J5,具有内部存储和外部sd卡存储,例如/storage/emulated/0//storage/D660-18BD/ (D668-18BD不固定,根据设备而异)。

When I tried to create a new file in the storage/D660-18BD/newfile.jpg , it says Access to the path is denied. 当我尝试在storage/D660-18BD/newfile.jpg创建一个新文件时,它说拒绝访问该路径。

I googled a lot but no success 我用谷歌搜索了很多但没有成功

What I had tried 1. Added Read/Write External Storage (but android take it as Internal storage) in the manifest file 2. Added the above permission at Runtime also alongwith Read/Write URI permission. 我尝试过的操作1.在清单文件中添加了读取/写入外部存储(但android将其作为内部存储)2.在运行时还添加了以上权限以及读取/写入URI权限。

Here is a demo in the thread , download it, it is a Xamarin.Forms project, 这是该线程中的演示 ,请下载它,它是一个Xamarin.Forms项目,

1) Run it on your phone, then it will create this path: /storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures 1)在手机上运行它,然后它将创建此路径: /storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures

2) Add this in the MainActivity , under LoadApplication(new App()); 2)将其添加到MainActivity LoadApplication(new App()); :

    Java.IO.File sdCardPath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
    //  filePath: /storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures
    string destPath = Path.Combine("/storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures/", "test.png");
    string originPath = Path.Combine(sdCardPath.AbsolutePath, "nULSa.png");
    Android.Util.Log.Error("lv", destPath);
    FileOutputStream fos = new FileOutputStream(destPath, false);
    FileInputStream fis = new FileInputStream(originPath);
    int b;
    byte[] d = new byte[1024 * 1024];
    while ((b = fis.Read(d)) != -1)
    {
        fos.Write(d, 0, b);
    }
    fos.Flush();
    fos.Close();
    fis.Close();

storage/D660-18BD/ is wrong path, you can't get the permission, you have the permission only in your package folder. storage/D660-18BD/路径错误,无法获取权限,仅在package文件夹中具有权限。 So you need create the path. 因此,您需要创建路径。 Sorry I can't find where the path created, maybe you can find it. 抱歉,我找不到路径的创建位置,也许您可​​以找到它。

This is the result: 结果如下:

在此处输入图片说明

The only thing you need to is to create this path: /storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures firstly, once it created, then you can write. 您唯一需要做的就是创建此路径: /storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures首先,一旦创建,就可以编写了。 I hope it will help. 希望对您有所帮助。


Update: 更新:

I find the solution: 我找到了解决方案:

using Android.App;
using Android.Widget;
using Android.OS;
using System.IO;
using Java.IO;
using System.Collections.Generic;
using Android.Content;
using Android.OS.Storage;
using Java.Lang.Reflect;
using System;

namespace WritToSd
{
    [Activity(Label = "WritToSd", MainLauncher = true)]
    public class MainActivity : Activity
    {
        string s;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);
            // important codes start:
            List<string> avaliableStorages = getAvaliableStorages(this);

            for (int i=0;i<avaliableStorages.Count;i++) {
                // because there is only one external sd card, so s is the path we need.
                s = avaliableStorages[i];
            }

            var str=this.GetExternalFilesDir(null).AbsolutePath;
            string direction = s + "/Android/data/" + this.PackageName + "/files/Pictures";
            Java.IO.File file = new Java.IO.File(direction);
            if (!file.Exists())
            {
                file.Mkdirs();
            }
            // end
            Java.IO.File sdCardPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
            //  filePath: /storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures
            string destPath = Path.Combine(direction, "test.png");
            string originPath = Path.Combine(sdCardPath.AbsolutePath, "test.png");
            Android.Util.Log.Error("lv", destPath);
            FileOutputStream fos = new FileOutputStream(destPath, false);
            FileInputStream fis = new FileInputStream(originPath);
            int b;
            byte[] d = new byte[1024 * 1024];
            while ((b = fis.Read(d)) != -1)
            {
                fos.Write(d, 0, b);
            }
            fos.Flush();
            fos.Close();
            fis.Close();

        }
        public List<string> getAvaliableStorages(Context context)
        {
            List<string> list = null;
            try
            {

                var storageManager = (Android.OS.Storage.StorageManager)context.GetSystemService(Context.StorageService);

                var volumeList = (Java.Lang.Object[])storageManager.Class.GetDeclaredMethod("getVolumeList").Invoke(storageManager);

                list = new List<string>();

                foreach (var storage in volumeList)
                {
                    Java.IO.File info = (Java.IO.File)storage.Class.GetDeclaredMethod("getPathFile").Invoke(storage);

                    if ((bool)storage.Class.GetDeclaredMethod("isEmulated").Invoke(storage) == false && info.TotalSpace > 0)
                    {
                        list.Add(info.Path);
                    }
                }
            }
            catch (Exception e)
            {

            }
            return list;
        }



    }

}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM