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

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

问题描述

我开始了一个意图

  Intent = new Intent();Intent.SetType("image/*");Intent.PutExtra(Intent.ExtraAllowMultiple,true);Intent.SetAction(Intent.ActionGetContent);StartActivityForResult(Intent.CreateChooser(Intent,选择图片"),代码); 

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

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

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

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

我尝试过的1.在清单文件中添加了读取/写入外部存储(但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;使用系统;命名空间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;
        }



    }

}
}

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

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