java.io.FileNotFoundException:/storage/emulated/0/New file.txt:打开失败:EACCES(权限被拒绝)

Posted

技术标签:

【中文标题】java.io.FileNotFoundException:/storage/emulated/0/New file.txt:打开失败:EACCES(权限被拒绝)【英文标题】:java.io.FileNotFoundException: /storage/emulated/0/New file.txt: open failed: EACCES (Permission denied) 【发布时间】:2016-10-15 15:08:33 【问题描述】:

我一直在尝试加密文件并将这些文件写回到同一个地方。但我收到错误消息说"java.io.FileNotFoundException: /storage/emulated/0/New file.txt: open failed: EACCES (Permission denied)".

我的Manifest文件是这个

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tdk.mytestapplication2">

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


<application
    android:allowBackup="true"

我想我在那里提供了正确的许可。我用来加密文件的代码就是这个。

public static void encrypt(SecretKey secretKey, String filePath)
    try 
        // Here you read the cleartext.
        FileInputStream fis = new FileInputStream(filePath);
        // This stream write the encrypted text. This stream will be wrapped by another stream.
        FileOutputStream fos = new FileOutputStream(filePath);

        // Create cipher
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // Wrap the output stream
        CipherOutputStream cos = new CipherOutputStream(fos, cipher);

        // Write bytes
        int b;
        byte[] d = new byte[8];
        while ((b = fis.read(d)) != -1) 
            cos.write(d, 0, b);
        

        // Flush and close streams.
        cos.flush();
        cos.close();
        fis.close();

    catch(IOException e)
        e.printStackTrace();
    catch (NoSuchAlgorithmException e)
        e.printStackTrace();
    catch(NoSuchPaddingException e)
        e.printStackTrace();
    catch(InvalidKeyException e)
        e.printStackTrace();
    

我在按钮中使用了这个方法

Button btnEncrypt = (Button) findViewById(R.id.btnEnc);
    btnEncrypt.setOnClickListener(new OnClickListener() 
        @Override
        public void onClick(View v) 
            aesKey = EncAndDec.generateKey();
            String filePath = editText.getText().toString();
            //Generating the file hash
            String md5Hash = MD5Hash.getMD5(filePath);

            System.out.println(aesKey.toString());
            System.out.println(filePath);
            System.out.println(md5Hash);

            //Encrypting the file
            for(int i=1; i<100; i++) 
                EncAndDec.encrypt(aesKey, filePath);
            
        
    );

我仍然无法配置此错误。请有人帮忙!

【问题讨论】:

***.com/questions/32635704/… 请同时确认:/storage/emulated/0/New file.txt: 文件是否存在?当您浏览您的设备时,您会看到它吗? @ishmaelMakitla hmmm 因为消息是“权限被拒绝”,那么文件确实存在(如果不存在,消息将是“找不到文件”) 问题是您的错误包括java.io.FileNotFoundException: /storage/emulated/0/New file.txt...,因此我问您是否已确认该文件确实存在 - 在这种情况下,错误可能会产生误导。但是在你的情况下事情看起来很奇怪,因为你声明了权限但你仍然得到Permission Denied - 所以请交叉检查文件本身是否存在。 @Tharindu 你运行的是什么版本的Android? 【参考方案1】:

如果您在 Android 29 中运行,那么您必须使用范围存储,或者现在,您可以使用以下方法绕过此问题:

android:requestLegacyExternalStorage="true"

在应用标签的清单中。

【讨论】:

你真的救了我,但我在 android 5 上仍然遇到问题 我认为你需要检查你的权限@IslamAssem 不敢相信他们默认设置了 false ......我花了 2 个小时在上面开什么玩笑 你成就了我的一天,感谢您的回答 :-) 此解决方案是临时的,不适用于 Android 11。您必须使用 MediaStore 类。检查此链接以获取永久解决方案。 sujeetkumargpt06.medium.com/…【参考方案2】:

我怀疑您运行的是 Android 6.0 Marshmallow (API 23) 或更高版本。如果是这种情况,您必须在尝试读/写外部存储之前实现runtime permissions。

【讨论】:

...仅当目标 SDK 为 23 或更高版本时 我的目标 SDK 是 19,但模拟器是 23 @Tharindu Hm,正如@devnull69 提到的,如果您的targetSdkVersion 为22 或更低,那么它仍应使用旧的权限模型。这可能不是问题。 @Bryan 安装后仍在安装一些组件,我将尝试在此处运行和更新 @Bryan 你有任何用于构建运行时权限的示例我是 android 开发新手【参考方案3】:

实现运行时权限,以便在 Android 6.0 Marshmallow (API 23) 或更高版本上运行您的应用。

或者您可以手动启用存储权限-

转到设置>应用程序>“your_app_name”>单击它>然后单击权限>然后启用存储。就是这样。

但我建议第一个是,在您的代码中实现运行时权限。

【讨论】:

其实第二个建议更好,如果你只需要保存一些东西进行调试。 是的,它可以用于调试目的@ŁukaszSromek 对于 android11.0 或更高版本有什么想法吗?【参考方案4】:

在 Android 11 上,应用无法再访问外部存储中任何其他应用的专用应用特定目录中的文件。 为了保护用户隐私,在运行 Android 11 或更高版本的设备上,系统会进一步限制您的应用访问其他应用的私有目录。

请求 MANAGE_EXTERNAL_STORAGE 权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" 
tools:ignore="ScopedStorage"/>

请求外部存储权限

ActivityCompat.requestPermissions( this,
new String[]
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.MANAGE_EXTERNAL_STORAGE
, 1
);

检查MANAGE_EXTERNAL_STORAGE的权限

// If you have access to the external storage, do whatever you need
if (Environment.isExternalStorageManager())

// If you don't have access, launch a new activity to show the user the system's dialog
// to allow access to the external storage
else
  Intent intent = new Intent();
  intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
  Uri uri = Uri.fromParts("package", this.getPackageName(), null);
  intent.setData(uri);
  startActivity(intent);

【讨论】:

【参考方案5】:

对于 SDK 29:

String str1 = "";
folder1 = new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)));
if (folder1.exists()) str1 = folder1.toString() + File.separator;

public static void createTextFile(String sBody, String FileName, String Where) 
    try 
        File gpxfile = new File(Where, FileName);
        FileWriter writer = new FileWriter(gpxfile);
        writer.append(sBody);
        writer.flush();
        writer.close();
     catch (IOException e) 
        e.printStackTrace();
    

然后您可以像这样保存文件:

createTextFile("This is Content","file.txt",str1);

【讨论】:

以上是关于java.io.FileNotFoundException:/storage/emulated/0/New file.txt:打开失败:EACCES(权限被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中解码 jpeg