【问题标题】:java.io.filenotfoundexception open failed eacces (permission denied) on devicejava.io.filenotfoundexception 在设备上打开失败的 eacces(权限被拒绝)
【发布时间】: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 我没有以理想的方式解决它。但我已经发布了关于我如何处理这个问题的答案。希望对您有所帮助。

标签: android android-permissions android-file


【解决方案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 权限从设备读取数据。

    【讨论】:

    【解决方案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);
          

          【讨论】:

          【解决方案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();
            
                                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-05-16
              • 1970-01-01
              • 2023-03-03
              • 2015-08-06
              • 1970-01-01
              • 2016-10-15
              • 2021-05-15
              相关资源
              最近更新 更多