如何在 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, "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.AbsolutePath, "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屋!