在 Android 7 设备的 SD 卡中写入文件
Write a file in the SD card of an Android 7 device
我必须开发一个小功能,除了其他功能外,还要在 SD 卡中写入一个文件。我必须将它用于供应商提供的两个特定 Android 平板电脑。一台平板电脑使用Android 5,另一台平板电脑使用Android 7。我正在修改的应用程序是系统应用程序,它没有UI。我正在从 Service
调用代码,我想从 FirebaseMessagingService
调用它。我只在 Android 7 平板电脑中写入文件时遇到问题。
我对 Android 5 平板电脑没有任何问题,我确定了外部存储文件夹,我可以在其中创建文件。但是我在 Android 7 中确实遇到了问题,我确定了外部存储文件夹并且遇到了问题:权限被拒绝。
我在清单中有这个权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这是给我带来问题的代码:
public void myFunction()
{
String sdPath;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
sdPath = "/storage/extsd";
else
sdPath = "/storage/0665-3426";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (my_context.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
Log.d(TAG, "Permission is granted");
else
Log.d(TAG, "Permission is denied");
}
File folder = new File(sdPath);
if (folder.exists()) {
Log.d(TAG, sdPath + " exists, can write: " + folder.canWrite());
File file = new File(sdPath + "/new_file");
boolean fileExists = file.exists();
Log.d(TAG, file.getAbsolutePath() + " file exists: " + fileExists + ", can write: " + file.canWrite());
if (!fileExists) {
try {
file.createNewFile();
Log.d(TAG, "Can write in " + sdPath);
}
catch (Exception exception) {
Log.e(TAG, "Cannot write in " + sdPath + ": " + exception.getMessage());
}
}
}
else
Log.e(TAG, sdPath + " does not exist.");
...
}
这里是 Android 5 平板电脑中的日志:
10-22 14:44:51.271 10450-10450/com.my.app D/MY_TAG: /storage/extsd exists, can write: true
10-22 14:44:51.368 10450-10450/com.my.app D/MY_TAG: /storage/extsd/new_file file exists: false, can write: false
10-22 14:44:51.479 10450-10450/com.my.app D/MY_TAG: Can write in /storage/extsd
这里是 Android 7 平板电脑中的日志:
2020-10-22 15:11:56.383 19689-19689/com.my.app D/MY_TAG: Permission is granted
2020-10-22 15:11:59.037 19689-19689/com.my.app D/MY_TAG: /storage/0665-3426 exists, can write: false
2020-10-22 15:12:07.956 19689-19689/com.my.app D/MY_TAG: /storage/0665-3426/new_file file exists: false, can write: false
2020-10-22 15:12:07.957 19689-19689/com.my.app E/MY_TAG: Cannot write in /storage/0665-3426: Permission denied
如你所见,即使授予权限,canWrite()
方法returnsfalse
在Android 7.你知道原因吗?我该如何解决这个问题?
我已经阅读了一些来自堆栈溢出的其他问题,但我没有找到解决方案。
我指的是 中的一个答案。
我不知道你的目标 SDK 版本,但如果你正在构建版本 29,请尝试将它添加到你的 AndroidManifest.xml
文件中:
<manifest>
<application
<!-- other stuff -->
android:requestLegacyExternalStorage="true">
<!-- other stuff -->
</application>
</manifest>
此外,您是否在运行时正确请求权限?
自 Android Kitkat/Lollipop.
以来,可移动微型 SD 卡是只读的
因此您不能写入像 "/storage/0665-3426"
.
这样的路径
一张可移动的微型 SD 卡上只能写入一个特定于应用程序的目录。
要确定该文件夹的路径,请查看
返回的第二项
getExternalFilesDirs()
我决定不使用AndroidAPI。由于应用程序具有提升的权限,我通过执行 shell 命令创建了该文件。这是创建文件的代码(适用于可移动 SD 卡文件夹):
public static String createFile(String filePath)
{
String returnValue = "";
try
{
Runtime runtime = Runtime.getRuntime();
String[] command = new String[]{ "su", "0", "touch", filePath};
Process p = runtime.exec(command);
p.waitFor();
java.io.BufferedReader errorIn = new java.io.BufferedReader(
new java.io.InputStreamReader(p.getErrorStream()));
String line = "";
while ((line = errorIn.readLine()) != null)
returnValue += line + "\n";
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
return returnValue;
}
我必须开发一个小功能,除了其他功能外,还要在 SD 卡中写入一个文件。我必须将它用于供应商提供的两个特定 Android 平板电脑。一台平板电脑使用Android 5,另一台平板电脑使用Android 7。我正在修改的应用程序是系统应用程序,它没有UI。我正在从 Service
调用代码,我想从 FirebaseMessagingService
调用它。我只在 Android 7 平板电脑中写入文件时遇到问题。
我对 Android 5 平板电脑没有任何问题,我确定了外部存储文件夹,我可以在其中创建文件。但是我在 Android 7 中确实遇到了问题,我确定了外部存储文件夹并且遇到了问题:权限被拒绝。
我在清单中有这个权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这是给我带来问题的代码:
public void myFunction()
{
String sdPath;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
sdPath = "/storage/extsd";
else
sdPath = "/storage/0665-3426";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (my_context.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
Log.d(TAG, "Permission is granted");
else
Log.d(TAG, "Permission is denied");
}
File folder = new File(sdPath);
if (folder.exists()) {
Log.d(TAG, sdPath + " exists, can write: " + folder.canWrite());
File file = new File(sdPath + "/new_file");
boolean fileExists = file.exists();
Log.d(TAG, file.getAbsolutePath() + " file exists: " + fileExists + ", can write: " + file.canWrite());
if (!fileExists) {
try {
file.createNewFile();
Log.d(TAG, "Can write in " + sdPath);
}
catch (Exception exception) {
Log.e(TAG, "Cannot write in " + sdPath + ": " + exception.getMessage());
}
}
}
else
Log.e(TAG, sdPath + " does not exist.");
...
}
这里是 Android 5 平板电脑中的日志:
10-22 14:44:51.271 10450-10450/com.my.app D/MY_TAG: /storage/extsd exists, can write: true
10-22 14:44:51.368 10450-10450/com.my.app D/MY_TAG: /storage/extsd/new_file file exists: false, can write: false
10-22 14:44:51.479 10450-10450/com.my.app D/MY_TAG: Can write in /storage/extsd
这里是 Android 7 平板电脑中的日志:
2020-10-22 15:11:56.383 19689-19689/com.my.app D/MY_TAG: Permission is granted
2020-10-22 15:11:59.037 19689-19689/com.my.app D/MY_TAG: /storage/0665-3426 exists, can write: false
2020-10-22 15:12:07.956 19689-19689/com.my.app D/MY_TAG: /storage/0665-3426/new_file file exists: false, can write: false
2020-10-22 15:12:07.957 19689-19689/com.my.app E/MY_TAG: Cannot write in /storage/0665-3426: Permission denied
如你所见,即使授予权限,canWrite()
方法returnsfalse
在Android 7.你知道原因吗?我该如何解决这个问题?
我已经阅读了一些来自堆栈溢出的其他问题,但我没有找到解决方案。
我指的是
我不知道你的目标 SDK 版本,但如果你正在构建版本 29,请尝试将它添加到你的 AndroidManifest.xml
文件中:
<manifest>
<application
<!-- other stuff -->
android:requestLegacyExternalStorage="true">
<!-- other stuff -->
</application>
</manifest>
此外,您是否在运行时正确请求权限?
自 Android Kitkat/Lollipop.
以来,可移动微型 SD 卡是只读的因此您不能写入像 "/storage/0665-3426"
.
一张可移动的微型 SD 卡上只能写入一个特定于应用程序的目录。
要确定该文件夹的路径,请查看
返回的第二项getExternalFilesDirs()
我决定不使用AndroidAPI。由于应用程序具有提升的权限,我通过执行 shell 命令创建了该文件。这是创建文件的代码(适用于可移动 SD 卡文件夹):
public static String createFile(String filePath)
{
String returnValue = "";
try
{
Runtime runtime = Runtime.getRuntime();
String[] command = new String[]{ "su", "0", "touch", filePath};
Process p = runtime.exec(command);
p.waitFor();
java.io.BufferedReader errorIn = new java.io.BufferedReader(
new java.io.InputStreamReader(p.getErrorStream()));
String line = "";
while ((line = errorIn.readLine()) != null)
returnValue += line + "\n";
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
return returnValue;
}