如何在Xamarin.android中的mashmallow中写入外部存储SD卡 [英] How to write on external storage sd card in mashmallow in xamarin.android
问题描述
我开始了一个意图
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.AbsolutePath,"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屋!