且构网

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

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

更新时间:2022-10-20 20:14:42

您唯一需要做的就是创建此路径:/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;使用系统;命名空间WritToSd{[Activity(Label ="WritToSd",MainLauncher = true)]公共类MainActivity:活动{字符串s;受保护的重写void OnCreate(Bundle savedInstanceState){base.OnCreate(savedInstanceState);//从主要"布局资源设置我们的视图SetContentView(Resource.Layout.Main);//重要的代码开始于:List< string>avaliableStorages = getAvaliableStorages(this);对于(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文件=新的Java.IO.File(方向);如果(!file.Exists()){file.Mkdirs();}//结尾Java.IO.File sdCardPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);//filePath:/storage/11E3-2116/Android/data/com.companyname.cropsample/files/Pictures字符串destPath = Path.Combine(direction,"test.png");字符串originPath = Path.Combine(sdCardPath.Abs​​olutePath,"test.png");Android.Util.Log.Error("lv",destPath);FileOutputStream fos = new FileOutputStream(destPath,false);FileInputStream fis =新的FileInputStream(originPath);int b;byte [] d =新的字节[1024 * 1024];而((b = fis.Read(d))!= -1){fos.Write(d,0,b);}fos.Flush();fos.Close();fis.Close();}公共列表< string>getAvaliableStorages(上下文上下文){List< string>list = null;尝试{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(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;
        }



    }

}
}