java - 打开失败 : EACCES (Permission denied)

标签 java android android-asynctask filenotfoundexception android-external-storage

我正在开发一个应用程序,我想在其中仅从 SD 卡中的互联网下载 PDF 文件。

我正在使用 android kitkat (4.4.4)。下载文件时出现错误提示 java.io.FileNotFoundException:/storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied)。当我使用 android (4.2) 时,它工作正常。

当我在 android 4.4.4 中运行此代码 Environment.getExternalStorageDirectory(); 时,它会返回内部存储空间。在 android 4.2 中,它会返回 SD 卡位置。

这是我的代码。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ashishkudale.filedownload">

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

MainActivity.java

public class MainActivity extends AppCompatActivity {

private Button bt_Download;
private ProgressDialog progressDialog;
public static final int progress_bar_type = 0;
private static String file_url = "http://my_website_url/Data/953.pdf";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    bt_Download = (Button) findViewById(R.id.bt_Download);

    bt_Download.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new DownloadFile().execute(file_url);
        }
    });
}

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case progress_bar_type:
            progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("Downloading...");
            progressDialog.setMax(100);
            progressDialog.setCancelable(true);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setIndeterminate(false);
            progressDialog.show();
            return progressDialog;
        default:
            return null;
    }
}

class DownloadFile extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(progress_bar_type);
    }

    @Override
    protected String doInBackground(String... fileUrl) {
        int count;
        try {
            URL url = new URL(fileUrl[0]);
            URLConnection conection = url.openConnection();
            conection.connect();

            int lenghtOfFile = conection.getContentLength();

            InputStream input = new BufferedInputStream(url.openStream(), 8192);

            File file = new File("/storage/sdcard1/pdf","953.pdf");

            OutputStream output = new FileOutputStream(file);

            byte data[] = new byte[1024];

            long total = 0;

            while ((count = input.read(data)) != -1) {
                total += count;
                publishProgress(""+(int)((total*100)/lenghtOfFile));

                output.write(data, 0, count);
            }

            output.flush();

            output.close();
            input.close();

        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }

        return null;
    }

    protected void onProgressUpdate(String... progress) {
        progressDialog.setProgress(Integer.parseInt(progress[0]));
    }

    @Override
    protected void onPostExecute(String fileUrl) {
        dismissDialog(progress_bar_type);
    }

}
}

它被异常捕获了。这是我的异常(exception)信息。 java.io.FileNotFoundException:/storage/sdcard1/pdf/953.pdf:打开失败:EACCES(权限被拒绝)

我不知道为什么 android 4.4.4 和更高版本不允许我写入 SD 卡。

我也在网上搜索了很多,但没有得到任何具体的答案。 还有其他方法吗?请告诉我。

最佳答案

I am developing an app in which I wanted to download PDF files from internet in SD card only.

您没有对 removable storage 的任意文件系统访问权在 Android 4.4+ 上。

when I run this code Environment.getExternalStorageDirectory(); in android 4.4.4 it returns me internal storage.

它返回 external storage ,由 Android SDK 定义。

where as in android 4.2 it returns me SD card location

也许在您的一台测试设备上确实如此。在绝大多数现代 Android 设备上,外部存储不是可移动存储。

I don't know why android 4.4.4 and above is not allowing me to write in SD card.

您没有对 removable storage 的任意文件系统访问权在 Android 4.4+ 上。

Is there any other way to do this?

在 Android 4.4+ 上,使用 ACTION_CREATE_DOCUMENTthe Storage Access Framework 的一部分— 允许用户决定放置内容的位置。你会得到一个 Uri。您可以将其与 ContentResolveropenOutputStream() 一起使用,将您的内容写入由 Uri 标识的位置。这也让用户可以灵活地将文件放在用户想要的其他地方,例如 Google Drive、Dropbox 或应用存储提供商管理的任何其他地方。

关于java - 打开失败 : EACCES (Permission denied),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38040609/

相关文章:

java - 如何使用 Docx4j 打印

android - Bottomappbar看不正确

android - 在android中复制mp3文件

android - 当其他任务正在运行时,AsyncTask 永远不会完成

java - 在java中从列表转换为json

Java随机不重复

java - Android Studio : SearchView: error in searchView. setSearchableInfo(searchManager.getSearchableInfo(cn));

java - Android AsyncTask #2 调用 detach()

java - Android AsyncTask 与 onPostExecute 错误

java - 包装类对象作为返回类型