SD 卡写入是否被阻止?
Has SD card writing been blocked?
我正在尝试在我的应用程序中提供一项功能,即用户可以将我的应用程序中使用的媒体或存储文件移动到 SD 卡。
我正在尝试使用下面描述的代码 link
http://www.java-samples.com/showtutorial.php?tutorialid=1523
但是我得到了权限异常。当我搜索获得该权限时,我发现我必须对设备进行 root 操作。我不想对我的设备进行 root,因为这是非法的,不是吗?是否有任何 android 设备型号从一开始就从制造商那里获得了根基?
之前我也曾在应用程序设置中看到一个 "Move To SD Card" 选项,但我再也看不到该选项了。我还看到我设备中安装的大多数文件浏览器应用程序都无法在 SD 卡上创建文件夹,
请分享一些关于实现此功能的最佳推荐方法的信息。我们支持 android 4.4 到 8.0
如果您还没有这样做,您需要通过将以下行添加到您的清单来为您的应用授予写入 SD 卡的正确权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Getting runtime permissions
您应该使用以下方式检查用户是否已授予外部存储权限:
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
//File write logic here
return true;
}
If not, you need to ask the user to grant your app a permission:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
Of course these are for marshmallow devices only so you need to check if your app is running on Marshmallow:
if (Build.VERSION.SDK_INT >= 23) {
//do your check here
}
还要确保您的 activity 实现了 OnRequestPermissionResult
整个权限如下所示:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
权限结果回调:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
//resume tasks needing this permission
}
}
Also
SD 卡目录是 /sdcard 但您不应该对其进行硬编码。相反,调用 Environment.getExternalStorageDirectory()
获取目录:
File sdDir = Environment.getExternalStorageDirectory();
Code to write into external storage
Source
/** Method to check whether external media available and writable. This is adapted from
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal */
private void checkExternalMedia(){
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// Can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// Can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Can't read or write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
}
/** Method to write ascii text characters to file on SD card. Note that you must add a
WRITE_EXTERNAL_STORAGE permission to the manifest file or this method will throw
a FileNotFound Exception because you won't have write permission. */
private void writeToSDFile(){
// Find the root of the external storage.
// See http://developer.android.com/guide/topics/data/data- storage.html#filesExternal
File root = android.os.Environment.getExternalStorageDirectory();
// See
File dir = new File (root.getAbsolutePath() + "/download");
dir.mkdirs();
File file = new File(dir, "myData.txt");
try {
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println("Hi , How are you");
pw.println("Hello");
pw.flush();
pw.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i(TAG, "******* File not found. Did you" +
" add a WRITE_EXTERNAL_STORAGE permission to the manifest?");
} catch (IOException e) {
e.printStackTrace();
}
}
/** Method to read in a text file placed in the res/raw directory of the application. The
method reads in all lines of the file sequentially. */
private void readRaw(){
InputStream is = this.getResources().openRawResource(R.raw.textfile);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr, 8192); // 2nd arg is buffer size
// More efficient (less readable) implementation of above is the composite expression
/*BufferedReader br = new BufferedReader(new InputStreamReader(
this.getResources().openRawResource(R.raw.textfile)), 8192);*/
try {
String test;
while (true){
test = br.readLine();
// readLine() returns null if no more lines in the file
if(test == null) break;
}
isr.close();
is.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
除此之外
共享存储可能并不总是可用,因为可移动媒体可能会被用户弹出。
- 可以使用 getExternalStorageState(File) 检查媒体状态。
- 这些文件没有强制执行安全措施。
是的,写入 SD 卡在现代 Android 版本中被阻止。
大部分情况下你已经读取了整个sd卡的权限。
仅写入一个应用程序特定目录,如果幸运的话,在 getExternalFilesDirs()
返回的第二项中可用。
如果要写入整个 SD 卡,请使用存储访问框架。
例如Intent.ACTION_OPEN_DOCUMENT_TREE.
我正在尝试在我的应用程序中提供一项功能,即用户可以将我的应用程序中使用的媒体或存储文件移动到 SD 卡。
我正在尝试使用下面描述的代码 link
http://www.java-samples.com/showtutorial.php?tutorialid=1523
但是我得到了权限异常。当我搜索获得该权限时,我发现我必须对设备进行 root 操作。我不想对我的设备进行 root,因为这是非法的,不是吗?是否有任何 android 设备型号从一开始就从制造商那里获得了根基?
之前我也曾在应用程序设置中看到一个 "Move To SD Card" 选项,但我再也看不到该选项了。我还看到我设备中安装的大多数文件浏览器应用程序都无法在 SD 卡上创建文件夹,
请分享一些关于实现此功能的最佳推荐方法的信息。我们支持 android 4.4 到 8.0
如果您还没有这样做,您需要通过将以下行添加到您的清单来为您的应用授予写入 SD 卡的正确权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Getting runtime permissions
您应该使用以下方式检查用户是否已授予外部存储权限:
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
//File write logic here
return true;
}
If not, you need to ask the user to grant your app a permission:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
Of course these are for marshmallow devices only so you need to check if your app is running on Marshmallow:
if (Build.VERSION.SDK_INT >= 23) {
//do your check here
}
还要确保您的 activity 实现了 OnRequestPermissionResult
整个权限如下所示:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
权限结果回调:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
//resume tasks needing this permission
}
}
Also
SD 卡目录是 /sdcard 但您不应该对其进行硬编码。相反,调用 Environment.getExternalStorageDirectory()
获取目录:
File sdDir = Environment.getExternalStorageDirectory();
Code to write into external storage
Source
/** Method to check whether external media available and writable. This is adapted from
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal */
private void checkExternalMedia(){
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// Can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// Can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Can't read or write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
}
/** Method to write ascii text characters to file on SD card. Note that you must add a
WRITE_EXTERNAL_STORAGE permission to the manifest file or this method will throw
a FileNotFound Exception because you won't have write permission. */
private void writeToSDFile(){
// Find the root of the external storage.
// See http://developer.android.com/guide/topics/data/data- storage.html#filesExternal
File root = android.os.Environment.getExternalStorageDirectory();
// See
File dir = new File (root.getAbsolutePath() + "/download");
dir.mkdirs();
File file = new File(dir, "myData.txt");
try {
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println("Hi , How are you");
pw.println("Hello");
pw.flush();
pw.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i(TAG, "******* File not found. Did you" +
" add a WRITE_EXTERNAL_STORAGE permission to the manifest?");
} catch (IOException e) {
e.printStackTrace();
}
}
/** Method to read in a text file placed in the res/raw directory of the application. The
method reads in all lines of the file sequentially. */
private void readRaw(){
InputStream is = this.getResources().openRawResource(R.raw.textfile);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr, 8192); // 2nd arg is buffer size
// More efficient (less readable) implementation of above is the composite expression
/*BufferedReader br = new BufferedReader(new InputStreamReader(
this.getResources().openRawResource(R.raw.textfile)), 8192);*/
try {
String test;
while (true){
test = br.readLine();
// readLine() returns null if no more lines in the file
if(test == null) break;
}
isr.close();
is.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
除此之外
共享存储可能并不总是可用,因为可移动媒体可能会被用户弹出。
- 可以使用 getExternalStorageState(File) 检查媒体状态。
- 这些文件没有强制执行安全措施。
是的,写入 SD 卡在现代 Android 版本中被阻止。
大部分情况下你已经读取了整个sd卡的权限。
仅写入一个应用程序特定目录,如果幸运的话,在 getExternalFilesDirs()
返回的第二项中可用。
如果要写入整个 SD 卡,请使用存储访问框架。
例如Intent.ACTION_OPEN_DOCUMENT_TREE.