开放失败:EACCES(权限被拒绝)

我在某些设备上访问存储时出现了一个非常奇怪的问题。 该应用程序适用于我的testing设备(Nexus 4和7,三星GS5)。 我的所有设备运行Android 4.4.2。 但是我收到很多来自用户的电子邮件,说应用程序不能写入存储器(既不是内部存储器也不是SD卡)。 从用户反馈收到的日志文件中,我可以看到问题是以下代码:

try { if (fStream == null) { fStream = new FileOutputStream(filename, true); } fStream.write(data, 0, bytes); return; } catch (IOException ex) { ex.printStackTrace(); } 

它会引发exceptionfStream = new FileOutputStream(filename,true); 创buildFileOutputStream时。

堆栈日志是:

 W/System.err( 8147): Caused by: java.io.FileNotFoundException: /storage/emulated/0/my_folder/test_file_name.png: open failed: EACCES (Permission denied) w/System.err( 8147): at libcore.io.IoBridge.open(IoBridge.java:409) W/System.err( 8147): at java.io.FileOutputStream.<init>(FileOutputStream.java:88) W/System.err( 8147): at java.io.FileOutputStream.<init>(FileOutputStream.java:128) W/System.err( 8147): at myapp.save(SourceFile:515) W/System.err( 8147): ... 8 more W/System.err( 8147): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied) W/System.err( 8147): at libcore.io.Posix.open(Native Method) W/System.err( 8147): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) W/System.err( 8147): at libcore.io.IoBridge.open(IoBridge.java:393) W/System.err( 8147): ... 11 more 

在AndroidManifest.xml中,我声明了以下权限:

  <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

我已经确认用户在SD卡上使用了正确的应用程序。 更奇怪的是,它也没有写入内部存储器。 如果我拥有读写权限,怎么会这样呢? 用户说当时他们没有把他们的设备连接到PC上。

更新

事实certificate,我打开和closuresFileOutputStream太频繁,这引发FileNotFoundException在某个时刻。 听起来更像是一个线程问题。

我碰到类似的问题。

你的问题可能在两个不同的领域。 这或者是如何创build要写入的文件,或者您的写作方法可能存在缺陷,因为它依赖于电话。

如果要将文件写入SD卡上的特定位置,请尝试使用环境variables。 他们应该始终指向一个有效的位置。 下面是一个写入下载文件夹的例子:

 java.io.File xmlFile = new java.io.File(Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/Filename.xml"); 

如果您正在将文件写入应用程序的内部存储器。 试试这个例子:

 java.io.File xmlFile = new java.io.File((getActivity() .getApplicationContext().getFileStreamPath("FileName.xml") .getPath())); 

我个人依靠外部库来处理stream文件。 这个还没有让我失望。

 org.apache.commons.io.FileUtils.copyInputStreamToFile(is, file); 

我在失败的写命令上丢失了太多次的数据,所以我依靠已知和经过testing的库来处理IO繁重的工作。

还有一点需要注意的是,如果文件很大,你可能也想看看在后台运行IO,还是使用callback。

对于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" /> 

在我的情况下,我遇到了错误的情况

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

android.permission必须是小写的,不知怎的,整个string在我们的来源大写。

我也面临同样的问题。 经过艰苦的工作,我发现我的情况出了什么问题。 我的设备通过USB电缆连接到电脑。 有大量存储,媒体设备(MTP),相机(PTP)等USB连接types。我的连接types是 – “大容量存储”,这是造成问题。 当我改变连接types时,问题就解决了。

记得在Android设备上访问文件系统时:

请勿将其作为大容量存储器连接至电脑/个人电脑。

在我的情况下,这是权限问题。 在Android 4.0.4的设备上,我得到了访问文件没有任何错误或exception。 在Android 5.1设备上,ACCESSexception失败(打开失败:EACCES(Permission denied))。 通过添加清单文件的后续权限处理它:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 

所以我想这是操作系统版本的权限pipe理之间的区别导致失败。

首先给予或检查权限

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 

如果这两个权限都可以,那么请检查您的输出stream格式是否正确。

例:

 FileOutputStream fos=new FileOutputStream(Environment.getExternalStorageDirectory()+"/rahul1.jpg"); 

在我的情况下,我使用AndroidManifest.xmlservice选项android:isolatedProcess="true"

只要我删除它,错误消失…

我遇到了同样的问题,发现我必须在运行时请求权限,即使我已经在清单中声明了它。 就像Justin Fiedler的回答一样。

有关这方面的官方文档在这里: https : //developer.android.com/training/permissions/requesting.html

我的实现与Justin Fiedler的答案略有不同,它也实现了v4片段的onRequestPermissionsResult方法来处理权限请求响应。

 public static final int REQUEST_EXTERNAL_PERMISSION_CODE = 666; @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) public static final String[] PERMISSIONS_EXTERNAL_STORAGE = { READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE }; public boolean checkExternalStoragePermission(Activity activity) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { return true; } int readStoragePermissionState = ContextCompat.checkSelfPermission(activity, READ_EXTERNAL_STORAGE); int writeStoragePermissionState = ContextCompat.checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE); boolean externalStoragePermissionGranted = readStoragePermissionState == PackageManager.PERMISSION_GRANTED && writeStoragePermissionState == PackageManager.PERMISSION_GRANTED; if (!externalStoragePermissionGranted) { requestPermissions(PERMISSIONS_EXTERNAL_STORAGE, REQUEST_EXTERNAL_PERMISSION_CODE); } return externalStoragePermissionGranted; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestCode == REQUEST_EXTERNAL_PERMISSION_CODE) { if (checkExternalStoragePermission(getActivity())) { // Continue with your action after permission request succeed } } } } 

我得到了同样的问题,但有时候,最困难的问题得到简单的答案。

我重新检查清单permisions和WAS_NOT写我permision耻辱!

我也find了解决办法。

在启动应用程序之前,我将root权限授予文件资源pipe理器,并且在退出应用程序时不禁止写入/读取权限。

我的应用程序不能使用外部存储器,而我没有restrat设备重置所有权限。

如果客户使用的是Android 6.0,Android为(棉花糖)添加了新的权限模型 。

诀窍:如果您的目标版本是22或以下,那么您的应用程序将在安装时请求所有权限,就像在任何运行低于棉花糖的操作系统的设备上一样

在我的情况下,问题是静态的WIFIconfiguration与另一个使用相同IP地址的设备发生冲突。

在我的情况下,我忘了添加/后面的文件名后我join我摆脱了它

 bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(Environment.getExternalStorageDirectory()+"/arjunreddy.png"));