且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-10-20 20:18:25

你唯一需要做的就是创建这个路径:/storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures 首先,一旦它创建,然后你可以写.我希望它会有所帮助.

更新:

我找到了解决办法:

使用Android.App;使用 Android.Widget;使用Android.OS;使用 System.IO;使用Java.IO;使用 System.Collections.Generic;使用 Android.Content;使用 Android.OS.Storage;使用 Java.Lang.Reflect;使用系统;命名空间写到Sd{[活动(标签 =WritToSd",MainLauncher = true)]公共类 MainActivity : 活动{字符串 s;protected override void OnCreate(Bundle savedInstanceState){base.OnCreate(savedInstanceState);//从主"布局资源设置我们的视图SetContentView(Resource.Layout.Main);//重要代码开始:列表avaliableStorages = getAvaliableStorages(this);for (int i=0;i<avaliableStorages.Count;i++) {//因为只有一张外置sd卡,所以s就是我们需要的路径.s = avaliableStorages[i];}var str=this.GetExternalFilesDir(null).AbsolutePath;字符串方向 = s + "/Android/data/" + this.PackageName + "/files/Pictures";Java.IO.File file = new Java.IO.File(direction);如果 (!file.Exists()){文件.Mkdirs();}//结尾Java.IO.File sdCardPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);//文件路径:/storage/11E3-2116/Android/data/com.companyname.cropsample/files/Picturesstring destPath = Path.Combine(direction, "test.png");string originPath = Path.Combine(sdCardPath.Abs​​olutePath, "test.png");Android.Util.Log.Error("lv", destPath);FileOutputStream fos = new FileOutputStream(destPath, false);FileInputStream fis = new FileInputStream(originPath);国际b;字节[] d = 新字节[1024 * 1024];而 ((b = fis.Read(d)) != -1){fos.Write(d, 0, b);}fos.flush();fos.关闭();fis.Close();}公共列表getAvaliableStorages(上下文上下文){列表列表 = 空;尝试{var storageManager = (Android.OS.Storage.StorageManager)context.GetSystemService(Context.StorageService);var volumeList = (Java.Lang.Object[])storageManager.Class.GetDeclaredMethod("getVolumeList").Invoke(storageManager);list = new List();foreach(volumeList 中的 var 存储){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);}}}捕获(例外 e){}退货清单;}}}}

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. 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).

When I tried to create a new file in the storage/D660-18BD/newfile.jpg, it says Access to the path is denied.

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.

Here is a demo in the thread, download it, it is a Xamarin.Forms project,

1) Run it on your phone, then it will create this path:/storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures

2) Add this in the MainActivity, under 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. 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. 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;
        }



    }

}
}