我正进入(状态
开放失败:
EACCES (Permission denied)
在线OutputStream myOutput = new FileOutputStream(outFileName);
我检查了根,我尝试了android.permission.WRITE_EXTERNAL_STORAGE
。
我该如何解决这个问题?
try {
InputStream myInput;
myInput = getAssets().open("XXX.db");
// Path to the just created empty db
String outFileName = "/data/data/XX/databases/"
+ "XXX.db";
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
buffer = null;
outFileName = null;
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
我有同样的问题...... <uses-permission
在错误的地方。这是正确的:
<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<application>
...
<activity>
...
</activity>
</application>
</manifest>
uses-permission
标签需要在application
标签之外。
我有同样的问题,没有任何建议有帮助。但我发现了一个有趣的原因,在物理设备上,Galaxy Tab。
启用USB存储时,外部存储读写权限不起作用。只需关闭USB存储,并使用正确的权限,您将解决问题。
我希望/data
以下的所有内容都属于“内部存储”。但是,你应该写信给/sdcard
。
更改/system/etc/permission/platform.xml
中的权限属性
和小组需要提到如下。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
<group android:gid="sdcard_rw" />
<group android:gid="media_rw" />
</uses-permission>
我尝试在Galaxy S5(Android 6.0.1)上的DCIM /相机文件夹中写入图像时遇到了同样的错误,我发现只有这个文件夹受到限制。我只能写入DCIM /任何文件夹,但不能写入相机。这应该是基于品牌的限制/定制。
奇怪的是,在我的newFile之前加上斜杠“/”我的问题就解决了。我改变了这个:
File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");
对此:
File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");
当您的应用程序属于系统应用程序时,它无法访问SD卡。
也许答案是这样的:
在API> = 23设备上,如果您安装了应用程序(该应用程序不是系统应用程序),您应该检查“设置 - 应用程序”中的存储权限,每个应用程序都有权限列表,您应该检查它!尝试
在我的情况下,我使用file picker library返回外部存储的路径,但它从/root/
开始。即使在运行时授予了WRITE_EXTERNAL_STORAGE权限,我仍然会收到错误EACCES(权限被拒绝)。
因此,使用Environment.getExternalStorageDirectory()
获取外部存储的正确路径。
例:
不能写:/root/storage/emulated/0/newfile.txt
可以写:/storage/emulated/0/newfile.txt
boolean externalStorageWritable = isExternalStorageWritable();
File file = new File(filePath);
boolean canWrite = file.canWrite();
boolean isFile = file.isFile();
long usableSpace = file.getUsableSpace();
Log.d(TAG, "externalStorageWritable: " + externalStorageWritable);
Log.d(TAG, "filePath: " + filePath);
Log.d(TAG, "canWrite: " + canWrite);
Log.d(TAG, "isFile: " + isFile);
Log.d(TAG, "usableSpace: " + usableSpace);
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
输出1:
externalStorageWritable: true
filePath: /root/storage/emulated/0/newfile.txt
isFile: false
usableSpace: 0
输出2:
externalStorageWritable: true
filePath: /storage/emulated/0/newfile.txt
isFile: true
usableSpace: 1331007488
请记住,即使您在清单中设置了所有正确的权限:允许第三方应用程序在您的外部卡上写入的唯一位置是“他们自己的目录”(即/ sdcard / Android / data /)试图写入在其他地方:你会得到例外:EACCES(权限被拒绝)
我正在我的init.rc中的/ data /下创建一个文件夹(与Nexus 7上的aosp混在一起)并且确实存在这个问题。
事实证明,给予文件夹rw(666)权限是不够的,它必须是rwx(777)然后一切正常!
对于API 23+,您需要请求读/写权限,即使它们已经在您的清单中。
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
AndroidManifest.xml中
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
有关请求API 23+权限的官方文档,请查看https://developer.android.com/training/permissions/requesting.html
如果您通过以下adb命令拥有root设备,则可以绕过6.0版后的存储权限实施:
root@msm8996:/ # getenforce
getenforce
Enforcing
root@msm8996:/ # setenforce 0
setenforce 0
root@msm8996:/ # getenforce
getenforce
Permissive
在清单中添加权限。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
添加权限后解决了我的问题
<uses-permission android:name="android.permission.INTERNET"/>
我遇到了同样的问题(API> = 23)。
解决方案https://stackoverflow.com/a/13569364/1729501为我工作,但断开app进行调试是不切实际的。
我的解决方案是在Windows上安装正确的adb设备驱动程序。谷歌USB驱动程序不适用于我的设备。
第1步:下载适用于您的设备品牌的adb驱动程序。
第2步:转到设备管理器 - >其他设备 - >查找带有“adb”字样的条目 - >选择更新驱动程序 - >在步骤1中输入位置
添加gradle依赖项
implementation 'com.karumi:dexter:4.2.0'
在主要活动中添加以下代码。
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
checkMermission();
}
}, 4000);
}
private void checkMermission(){
Dexter.withActivity(this)
.withPermissions(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.INTERNET
).withListener(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.isAnyPermissionPermanentlyDenied()){
checkMermission();
} else if (report.areAllPermissionsGranted()){
// copy some things
} else {
checkMermission();
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
建立在user462990的回答之上
要在用户响应权限请求对话框时收到通知,请使用:( kotlin中的代码)
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
MY_PERMISSIONS_REQUEST_READ_CONTACTS -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return
}
// Add other 'when' lines to check for other
// permissions this app might request.
else -> {
// Ignore all other requests.
}
}
}
在我的情况下,错误出现在行上
target.createNewFile();
因为我无法在SD卡上创建新文件,所以我不得不使用DocumentFile方法。
documentFile.createFile(mime, target.getName());
对于上述问题,可以通过这种方法解决问题,
fos=context.getContentResolver().openOutputStream(documentFile.getUri());
看到这个帖子,How to use the new SD card access API presented for Android 5.0 (Lollipop)?
我在模拟器中运行应用程序时观察过一次。在仿真器设置中,您需要正确指定外部存储器的大小(“SD卡”)。默认情况下,“外部存储”字段为空,这可能意味着即使在清单中授予了权限,也不会抛出此类设备和EACCES。
除了所有答案之外,请确保您没有将手机用作USB存储设备。
我在启用USB存储模式的HTC Sensation上遇到了同样的问题。我仍然可以调试/运行应用程序,但我无法保存到外部存储。
我的问题是“TargetApi(23)”,如果你的minSdkVersion低于23,则需要这个。
所以,我有以下代码段的请求权限
protected boolean shouldAskPermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@TargetApi(23)
protected void askPermissions() {
String[] permissions = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
};
int requestCode = 200;
requestPermissions(permissions, requestCode);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
if (shouldAskPermissions()) {
askPermissions();
}
}
我也遇到了同样的问题。我发现如果你去设置 - >应用程序管理器 - >你的应用程序 - >权限 - >启用存储,它解决了这个问题。
事实证明,这是一个愚蠢的错误,因为我的手机仍然连接到台式电脑,并没有意识到这一点。
所以我不得不关闭USB连接,一切正常。
我在三星Galaxy Note 3上遇到了同样的问题,运行CM 12.1。我的问题是我有
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
并且必须使用它来拍摄和存储用户照片。当我试图在ImageLoader中加载那些相同的照片时,我得到了(Permission denied)
错误。解决方案是明确添加
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
由于上述权限仅将写入权限限制为API版本18,并且具有读取权限。
除了所有答案,如果客户使用Android 6.0,Android为(Marshmallow)添加了新的permission model。
技巧:如果您的目标是22或更低版本,您的应用程序将在安装时请求所有权限,就像在Marshmallow下运行操作系统的任何设备上一样。如果您正在尝试使用模拟器,那么从Android 6.0开始,您需要明确地去设置 - > apps-> YOURAPP - >权限并更改权限(如果您已经提供)。