问题描述
Android 用户应用程序在尝试将文件从 /storage/emulated/0/test.txt
拷贝到 /cache/SH_DIR/
时出现 open failed: EACCES (Permission denied)
错误。当应用被作为系统应用安装并通过 AOSP 创建时,没有权限问题。因此推测可能是由于普通用户应用缺失必要的文件写入权限导致的。
解决方案
方案1:增加用户应用程序所需的文件访问权限
在 AndroidManifest.xml 文件中添加以下声明以授予文件读取和写入权限:
<manifest>
<application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 只需添加 WRITE_EXTERNAL_STORAGE 权限,用于访问 /storage/emulated/0/ 下的文件 -->
</application>
</manifest>
注意:从 Android 6.0(API 级别为 23)开始,需要使用 Runtime_permissions
API 动态请求以下权限:
– WRITE_EXTERNAL_STORAGE
– READ_EXTERNAL_STORAGE
因此,请确保在代码中请求相应的运行时权限。具体可参考官方文档 动态请求权限指南。
实现示例
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// 提供权限请求解释或指南,然后再次请求该权限。
}
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_CODE);
}
private static final int MY_PERMISSION_REQUEST_CODE = 1;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 拷贝文件逻辑
}
}
}
方案2:检查 /cache/SH_DIR
目录的访问权限
由于某些应用无法在 /cache
下产生直接子目录,因此建议检查是否需要增加额外的 SEPolicy 规则。首先确保你的设备支持写入 /cache
路径。这可以通过 adb shell 检查:
adb shell ls /cache
如果返回正常结果,则可以继续:
1. 确认目录 SH_DIR
是否存在以及权限设置。
2. 可能需要修改设备的安全策略(SEPolicy)来允许应用使用该路径。具体操作如下:
– 打开设备安全策略配置 ($ANDROID-sdk-platform-tools-directory/repo/adb shell
后运行 sepolicy
– 编辑 SELinux 策略以授予访问权限,参考文档 SELinux 政策设置指南.
方案3:确认 SH_DIR 的位置是否可用
对于 /cache/SH_DIR
作为目标路径的合理性进行验证。若 SH_DIR
文件夹确实不适合你的应用场景,请考虑使用其他路径。
综上所述,根据实际情况选择相应的方案来解决问题。如果应用仍然报告权限问题,则可能需要进一步深入探究设备的安全保护配置及权限要求。