java.io.filenotfoundexception 在设备上打开失败的 eacces(权限被拒绝)

Posted

技术标签:

【中文标题】java.io.filenotfoundexception 在设备上打开失败的 eacces(权限被拒绝)【英文标题】:java.io.filenotfoundexception open failed eacces (permission denied) on device 【发布时间】:2013-07-06 14:49:27 【问题描述】:

以下代码包括从服务器下载文件并将其保存在存储中,当设备具有内部存储时,它可以正常工作。 但是,当我尝试使用没有内部存储的设备时,仅使用外部存储时出现以下异常。

java.io.filenotfoundexception open failed eacces (permission denied)

public void downloadFile(String dlUrl, String dlName) 
    int count;

    HttpURLConnection con = null;
    InputStream is = null;
    FileOutputStream fos = null;

    try 
        URL url = new URL( dlUrl );
        con = (HttpURLConnection) url.openConnection();
        con.setDoInput(true);
        con.connect();

        is = url.openStream();
        String dir = Environment.getExternalStorageDirectory() + Util.DL_DIRECTORY;
        File file = new File( dir );
        if( !file.exists() )
            file.mkdir();
        

        Util.LOG_W(TAG, "Downloading: " + dlName + " ...");

        fos = new FileOutputStream(file + "/" +  dlName);
        byte data[] = new byte[1024];

        while( (count = is.read(data)) != -1 )
            fos.write(data, 0, count);
        

        Util.LOG_D(TAG, dlName + " Download Complete!");


     catch (Exception e) 
        Util.LOG_E(TAG, "DOWNLOAD ERROR = " + e.toString() );
        bServiceDownloading = false;
    
    finally
        try 
            if( is != null)
                is.close();
            if( fos != null)
                fos.close();
            if( con != null)
                con.disconnect();
         catch (Exception e) 
            Util.LOG_E(TAG, "CLOSE ERROR = " + e.toString() );
        
    

在清单文件中,我有以下内容:

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

任何建议可能是什么原因? 顺便说一句,Environment.getExternalStorageDirectory() 返回 /mnt/sdcard/ 并且 file.mkdir() 返回 false。

【问题讨论】:

试试File file = new File( dir + "/" + dlName ); 不幸的是,结果是一样的。顺便说一句,file.mkdir() 返回 false,这就是我认为的问题。 @PankajKumar 如果您在模拟器上调试,请确保您创建的 sd 卡支持.. 或者如果真实设备确保 sd 卡存在(设备未连接 USB) 实机调试。存在 SD 卡。如何检查设备是否未连接 USB?这包括 USB 鼠标吗? @hB0 我没有以理想的方式解决它。但我已经发布了关于我如何处理这个问题的答案。希望对您有所帮助。 【参考方案1】:

默认情况下,该属性在应用定位上为“false” Android 10 或更高版本。

<application android:requestLegacyExternalStorage="true" ... >
    ...
</application>

【讨论】:

【参考方案2】:

这个问题似乎是由几个因素造成的。

检查#1 首先在您的清单文件中添加此权限并检查它是否有效:

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

</application>

  .....

检查#2:

如果您在模拟器上运行,请检查属性以查看它是否有 SD 卡。

检查#3:

禁用从设备到计算机的文件传输。如果启用,应用程序将无法访问 SD 卡。

检查#4: 如果仍然无法正常工作,请尝试以下操作:

 String dir = Environment.getExternalStorageDirectory().getAbsolutePath()

对我来说,以下工作: 问题是 getExternalStorageDirectory 返回 /mnt/sdcard 而我需要外部存储的实际路径,即 /mnt/sdcard-ext 并且 android 中没有 API 可以让我获得可移动 sdcard 的绝对路径。 我的解决方案是对目录进行硬编码,如下所示:

String dir = "/mnt/sdcard-ext" ;

由于该应用程序旨在仅在一台设备上运行,因此上述工作完成了。 如果您遇到同样的问题,请使用file explorer application 找出外部目录的名称并对其进行硬编码。

【讨论】:

这是一个特定于设备的路径(如您所述)。例如:我在这里看到 String dir = "/mnt/sdcard"。 如果您想为所有安卓手机访问(或不)外部存储中的文件,您会建议什么解决方案? 你的回答中 Check#2 应该怎么做?【参考方案3】:

使用READ_EXTERNAL_STORAGE 权限从设备读取数据。

【讨论】:

感谢您的建议,但不幸的是它并没有解决问题。 “任何声明 WRITE_EXTERNAL_STORAGE 权限的应用程序都被隐式授予此权限。” developer.android.com/reference/android/…【参考方案4】:

你在模拟器上试过了吗?检查属性是否有 SD 卡。我有同样的问题,这是因为模拟器没有SD卡。检查你的有没有。

【讨论】:

是的,我正在模拟器上尝试。在哪里查看您所指的属性?【参考方案5】:

我遇到了同样的问题,我通过禁用从设备到计算机的文件传输来解决它。 因为如果您启用文件传输,则无法访问 sd 卡来调试应用程序。

【讨论】:

谢谢,我就是这样。 OMG 它解决了我的问题,但调试了 3 小时【参考方案6】:
try
Environment.getExternalStorageDirectory().getAbsolutePath()

别忘了添加

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

【讨论】:

【参考方案7】:

我怀疑您运行的是 Android 6.0 Marshmallow (API 23) 或更高版本。如果是这种情况,您必须在尝试读/写外部存储之前实现运行时权限。 https://developer.android.com/training/permissions/requesting.html

【讨论】:

【参考方案8】:

尝试使用 mkdirs 而不是 mkdir。如果您正在创建目录路径并且父目录不存在,那么您应该使用 mkdirs。

【讨论】:

【参考方案9】:

我犯了一个非常愚蠢的错误。 我已经放入了AndroidManifest.xml

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

并在java文件中添加权限,以务实的方式获得权限。 但是 Manifest.permission.READ_EXTERNAL_STORAGE 有错误。 请使用 Manifest.permission.WRITE_EXTERNAL_STORAGE

ActivityCompat.requestPermissions(this, new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE, requestCode);

【讨论】:

它的整数值。请参考此链接***.com/questions/44309857/…【参考方案10】:

我遇到了同样的问题。我正确使用了清单中的写入和读取权限,但它不起作用!解决方案非常愚蠢:在运行应用程序之前从 PC 上拔下手机。当您的手机作为“大容量存储”连接到 PC 时,应用程序似乎无法访问外部存储。

【讨论】:

【参考方案11】:

首先在你的清单文件中声明权限:

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

现在在清单文件的应用程序标记的标题中:

android:requestLegacyExternalStorage="true"

现在在清单文件的标记之间为您的应用定义提供程序。如:

 <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="$applicationId.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_path" />
    </provider>

现在在 res 文件夹中创建一个文件夹 xml,如下所示:

现在创建一个 xml 文件 provider_path.xml 并在其中复制以下代码:

<?xml version="1.0" encoding="utf-8"?>
<path>
<external-path
    name="external_files"
    path="." />

现在在你的活动中:

String filename = null ;
URL url = null;
try 
                        url = new URL("http://websitename.com/sample.pdf");
                        filename = url.getPath();
                        filename = filename.substring(filename.lastIndexOf('/')+1);

                     catch (MalformedURLException e) 
                        e.printStackTrace();
                    
  File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/"+filename);
                    if(file.exists())
                        Uri uri = FileProvider.getUriForFile(context, "com.example.www"+".provider",file);
                        Intent i = new Intent(Intent.ACTION_VIEW);
                        i.setDataAndType(uri, "application/pdf");
                        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        context.startActivity(i);
                    
                    else 
                        //download file here
                        new AlertDialog.Builder(context)
                                .setTitle("Information")
                                .setMessage("Do you want to download this file ?")
                                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() 
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) 
                                        dialog.dismiss();
                                    
                                )
                                .setPositiveButton("Continue", new DialogInterface.OnClickListener() 
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) 
                                        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url+""));
                                        request.setTitle(filename);
                                        request.setMimeType("application/pdf");
                                        request.allowScanningByMediaScanner();
                                        request.setAllowedOverMetered(true);
                                        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                                        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
                                        DownloadManager downloadManager = (DownloadManager)context.getSystemService(DOWNLOAD_SERVICE);
                                        downloadManager.enqueue(request);
                                    
                                ).show();

                    

【讨论】:

以上是关于java.io.filenotfoundexception 在设备上打开失败的 eacces(权限被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中解码 jpeg