Google去年11月正式发布了Android 4.4,代号为KitKat(奇巧,雀巢的一款巧克力品牌),该系统带来了诸多新的特性。
但需要注意的是,该系统可能会让你之前一直正常使用的SD卡变为无用的“摆设”,因为根据新版本的API改进,应用程序将不能再往SD卡中写入文件。
来看Android开发者网站的“外部存储技术信息”文档中的描述:
引用
WRITE_EXTERNAL_STORAGE只为设备上的主要外部存储授予写权限,应用程序无法将数据写入二级外部存储设备,除非指定了应用程序允许访问的特定的目录。
这目前只影响双存储设备,如果你的设备有内部存储空间,即通常所说的机身存储(这就是指主要外部存储),那么你的SD卡就是一个二级外部存储设备。
在Android 4.4中,如果你同时使用了机身存储和SD卡,那么应用程序将无法在SD卡中创建、修改、删除数据。比如,你无法使用文件管理器通过无线网络从电脑往SD卡中复制文件了。但是应用程序仍然可以往主存储的任意目录中写入数据,不受任何限制。
Google表示,这样做的目的是,通过这种方式进行限制,系统可以在应用程序被卸载后清除遗留文件。
目前三星已经通过OTA向部分手机发送了Android 4.4的更新,已经有Note3用户抱怨FX文件管理器现在不能往SD卡中复制内容了。
解决办法
获得系统的ROOT权限是一个解决方法。
很显然,这是针对用户的解决办法,但是并不是所有的用户都愿意进行ROOT,那么需要SD卡写入权限的开发者该如何做呢?
XDA论坛已经有大神给出了解决方案——在应用中嵌入一段代码,这段代码作用是在Android
4.4+设备上,如果其他方式写入失败,则将数据写入二级存储设备。
详细方案:http://forum.xda-developers.com/showthread.php?p=50008987
-
-
-
-
-
-
-
-
-
-
-
-
-
-
package nextapp.mediafile;
-
-
import java.io.File;
-
import java.io.IOException;
-
import java.io.OutputStream;
-
-
import android.content.ContentResolver;
-
import android.content.ContentValues;
-
import android.net.Uri;
-
import android.provider.MediaStore;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
public class MediaFile {
-
-
private final File file;
-
private final ContentResolver contentResolver;
-
private final Uri filesUri;
-
private final Uri imagesUri;
-
-
public MediaFile(ContentResolver contentResolver, File file) {
-
this.file = file;
-
this.contentResolver = contentResolver;
-
filesUri = MediaStore.Files.getContentUri("external");
-
imagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-
}
-
-
-
-
-
-
public boolean delete()
-
throws IOException {
-
if (!file.exists()) {
-
return true;
-
}
-
-
boolean directory = file.isDirectory();
-
if (directory) {
-
-
String[] files = file.list();
-
if (files != null && files.length > 0) {
-
return false;
-
}
-
}
-
-
String where = MediaStore.MediaColumns.DATA + "=?";
-
String[] selectionArgs = new String[] { file.getAbsolutePath() };
-
-
-
contentResolver.delete(filesUri, where, selectionArgs);
-
-
if (file.exists()) {
-
-
-
ContentValues values = new ContentValues();
-
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
-
contentResolver.insert(imagesUri, values);
-
-
-
contentResolver.delete(filesUri, where, selectionArgs);
-
}
-
-
return !file.exists();
-
}
-
-
public File getFile() {
-
return file;
-
}
-
-
-
-
-
public boolean mkdir()
-
throws IOException {
-
if (file.exists()) {
-
return file.isDirectory();
-
}
-
-
ContentValues values;
-
Uri uri;
-
-
-
values = new ContentValues();
-
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
-
contentResolver.insert(filesUri, values);
-
-
-
-
values = new ContentValues();
-
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath() + "/temp.jpg");
-
uri = contentResolver.insert(imagesUri, values);
-
-
-
contentResolver.delete(uri, null, null);
-
-
return file.exists();
-
}
-
-
-
-
-
public OutputStream write()
-
throws IOException {
-
if (file.exists() && file.isDirectory()) {
-
throw new IOException("File exists and is a directory.");
-
}
-
-
-
-
String where = MediaStore.MediaColumns.DATA + "=?";
-
String[] selectionArgs = new String[] { file.getAbsolutePath() };
-
contentResolver.delete(filesUri, where, selectionArgs);
-
-
ContentValues values = new ContentValues();
-
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
-
Uri uri = contentResolver.insert(filesUri, values);
-
-
if (uri == null) {
-
-
throw new IOException("Internal error.");
-
}
-
-
return contentResolver.openOutputStream(uri);
-
}
-
}
安卓4.4中应用无法读取修改sd卡的问题——程序员解决方案
原文:http://blog.csdn.net/shao941122/article/details/43734325