Java 安卓无法';无法在sd卡上写入和删除操作
我现在正在使用ImageCompressor应用程序 我需要Java 安卓无法';无法在sd卡上写入和删除操作,java,android,permissions,file-permissions,storage-access-framework,Java,Android,Permissions,File Permissions,Storage Access Framework,我现在正在使用ImageCompressor应用程序 我需要删除和写入(更新)图像文件。在内部存储中工作正常,但**SD卡不能给我删除和写入文件的权限 我的应用程序如何能够在sd卡上执行写入和删除操作(可移动存储) 我已经完成了整个项目没有这个,所以我必须找到一个方法 更新: // ----------- Intent ------------- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCateg
删除
和写入
(更新)图像文件。在内部存储中工作正常,但**SD卡不能给我删除和写入文件的权限
我的应用程序如何能够在sd卡上执行写入
和删除
操作(可移动存储)
我已经完成了整个项目没有这个,所以我必须找到一个方法
更新:
// ----------- Intent -------------
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
// ------------ On Activity Result --------------
Uri uri = data.getData();
try {
ParcelFileDescriptor fileDescriptor = getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fos = new FileOutputStream(fileDescriptor.getFileDescriptor());
FileInputStream fis = new FileInputStream(getImageFilePath(uri));
FileChannel source = fis.getChannel();
FileChannel destination = fos.getChannel();
destination.transferFrom(source, 0, source.size());
fis.close();
fos.close();
fileDescriptor.close();
Toast.makeText(this, "File save successfully.", Toast.LENGTH_SHORT).show();
}
我已经在研究和讨论这个问题。我知道我必须使用存储访问框架
,但我是SAF新手
我使用一个库来压缩需要文件而不是Uri的照片。为此,我使用Uri->File
并使用Intent.ACTION\u打开文档
并从可移动存储中选择图像
但对于可移动存储,我无法从uri中找到图像的真实路径
我不知道这是不是正确的方法。如果在SAF中有任何方法可以使用uri压缩图像,请告诉我。或者如何从可移动存储照片的uri获取图像真实路径
更新代码SAF:
// ----------- Intent -------------
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
// ------------ On Activity Result --------------
Uri uri = data.getData();
try {
ParcelFileDescriptor fileDescriptor = getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fos = new FileOutputStream(fileDescriptor.getFileDescriptor());
FileInputStream fis = new FileInputStream(getImageFilePath(uri));
FileChannel source = fis.getChannel();
FileChannel destination = fos.getChannel();
destination.transferFrom(source, 0, source.size());
fis.close();
fos.close();
fileDescriptor.close();
Toast.makeText(this, "File save successfully.", Toast.LENGTH_SHORT).show();
}
Uri到文件路径,我从媒体应用程序(如Gallary、Photos)中选择图像,但从sd卡中选择什么将代替MediaStore.Images.media.DATA
我不知道。代码:
private File getImageFilePath(Uri uri) throws IOException {
String image_id = null, imagePath = null;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
image_id = cursor.getString(0);
image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
cursor.close();
}
cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
if (cursor!=null) {
cursor.moveToFirst();
imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
}
File file = new File(imagePath);
return new Compressor(this).setQuality(50).compressToFile(file);
}
如果使用File和FileOutputStream类,可移动SD卡只能在现代Android设备上写入 如果幸运的话,使用
getExternalFilesDirs()
的设备会将卡上的应用程序特定目录作为第二项返回,您仍然可以在其中写入
对于其余部分,请使用
首先让用户选择具有意图的sd卡。操作打开文档树
或具有意图的文件。操作打开文档
您已经尝试过了
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
//Filter common Linux partitions
if (line.contains("secure"))
continue;
if (line.contains("asec"))
continue;
if (line.contains("media"))
continue;
if (line.contains("system") || line.contains("cache")
|| line.contains("sys") || line.contains("data")
|| line.contains("tmpfs") || line.contains("shell")
|| line.contains("root") || line.contains("acct")
|| line.contains("proc") || line.contains("misc")
|| line.contains("obb")) {
continue;
}
if (line.contains("fat") || line.contains("fuse") || (line
.contains("ntfs"))) {
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
String path = columns[1];
if (path!=null&&!SdList.contains(path)&&path.contains("sd"))
SdList.add(columns[1]);
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我挖掘了我的一个旧安卓应用程序,并检索到以下内容: 此方法将SD卡uri的根转换为
文件
路径
public File getRootPath(Context context, Uri sdcardRootUri)
{
List<String> pathSegments = sdcardRootUri.getPathSegments();
String[] tokens = pathSegments.get(pathSegments.size()-1).split(":");
for (File f : ContextCompat.getExternalFilesDirs(context, null))
{
String path = f.getAbsolutePath().substring(0, f.getAbsolutePath().indexOf("/Android/"));
if (path.contains(tokens[0]))
{
return new File(path);
}
}
return null;
}
然后用户会选择SD卡的根,然后,我像这样处理结果:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK && requestCode == SDCARD_ROOT_CODE)
{
// Persist access permissions
Uri sdcdardRootUri = data.getData();
grantUriPermission(getPackageName(), sdcdardRootUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(sdcdardRootUri, takeFlags);
// Do whatever you want with sdcdardRootUri
}
}
我希望这就是你要找的。这样,您就可以读取/写入/删除SD卡上需要的任何文件。您尝试过搜索吗@米肯。是的,我说的是可移动存储。@反斜杠的问题和Answare是非常老的。在5.0版Lolipop之后,android更改了sd卡访问策略。@B001ᛦ 是的,我提供了正确的许可,这就是为什么手机内存中的每件事都能完美工作的原因。但是Sd卡有问题。请看一看对不起,我没有看Sd卡路径。我必须获得sd卡(可移动存储)上的删除权限。首先,我很抱歉延迟,我很忙。这就是我要找的答案。但现在我无法测试这段代码,很明显,我会在运行完这段代码后通知您。非常感谢。您好,您的
getRootPath(上下文,urisdcardrooturi)
不工作。这里path
veriable return/storage/3034-6134
这个字符串是SD卡路径而不是文件夹文件路径。是的SD卡根路径,只需在下一个附加文件的相对路径我不专业,你可以说初学者。我不明白这对我有什么帮助。对于ACTION\u OPEN\u DOCUMENT\u TREE
我需要specefic文件夹文件。我怎么能得到这个?你能为我添加一些代码吗?例如:fileyourfile=newfile(getRootPath(context,sdcdardRootUri),“path/to/File/in/sd/card”)代码>