如何在 xamarin.android 中的 mashmallow 中写入外部存储 SD 卡 [英] How to write on external storage sd card in mashmallow in xamarin.android

查看:30
本文介绍了如何在 xamarin.android 中的 mashmallow 中写入外部存储 SD 卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始了一个意图

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

我正在使用 bitmap.Compress(...) 函数并从上面的意图中获取 uri.我想删除那个位图文件并重新创建同名文件(简而言之:替换现有文件).

我的物理设备是三星 J5,具有内部存储和外部 SD 卡存储,如 /storage/emulated/0//storage/D660-18BD/ (D668-18BD 不是固定的,它会根据设备而变化).

当我尝试在 storage/D660-18BD/newfile.jpg 中创建一个新文件时,它说访问路径被拒绝.

我用谷歌搜索了很多但没有成功

我尝试过的1.在manifest文件中增加了读/写外部存储(但android将其作为内部存储)2. 运行时增加了上述权限以及读/写URI权限.

解决方案

你唯一需要做的就是创建这个路径:/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;
        }



    }

}
}

这篇关于如何在 xamarin.android 中的 mashmallow 中写入外部存储 SD 卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆