打开失败:EACCES(权限被拒绝)
open failed: EACCES (Permission denied)
我正在开发一个应用程序,我想在其中仅从 SD 卡中的互联网下载 PDF 文件。
我正在使用 android kitkat (4.4.4)
。下载文件时出现 java.io.FileNotFoundException: /storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied)
错误。当我使用 android (4.2)
时它工作正常。
当我 运行 这个代码 Environment.getExternalStorageDirectory();
在 android 4.4.4
它 returns 我的内部存储。在 android 4.2
中,它 returns 我的 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);
}
}
}
异常捕获。这是我的例外信息。 java.io.FileNotFoundException: /storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied)
我不知道为什么android 4.4.4
及更高版本不允许我写入SD卡
我也在网上查了很多,也没有得到具体的答案。
还有其他方法吗?请告诉我。
I am developing an app in which I wanted to download PDF files from internet in SD card only.
在 Android 4.4+ 上,您没有对 removable storage 的任意文件系统访问权限。
when I run this code Environment.getExternalStorageDirectory(); in android 4.4.4 it returns me internal storage.
它 returns 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.
在 Android 4.4+ 上,您没有对 removable storage 的任意文件系统访问权。
Is there any other way to do this?
在 Android 4.4+ 上,使用 ACTION_CREATE_DOCUMENT
— the Storage Access Framework 的一部分 — 允许用户决定放置内容的位置。你会得到一个Uri
。您可以将其与 ContentResolver
和 openOutputStream()
一起使用,将您的内容写入 Uri
标识的位置。这也使用户可以灵活地将文件放在用户想要的其他地方,例如 Google Drive、Dropbox 或应用存储提供商管理的任何其他地方。
我正在开发一个应用程序,我想在其中仅从 SD 卡中的互联网下载 PDF 文件。
我正在使用 android kitkat (4.4.4)
。下载文件时出现 java.io.FileNotFoundException: /storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied)
错误。当我使用 android (4.2)
时它工作正常。
当我 运行 这个代码 Environment.getExternalStorageDirectory();
在 android 4.4.4
它 returns 我的内部存储。在 android 4.2
中,它 returns 我的 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);
}
}
}
异常捕获。这是我的例外信息。 java.io.FileNotFoundException: /storage/sdcard1/pdf/953.pdf: open failed: EACCES (Permission denied)
我不知道为什么android 4.4.4
及更高版本不允许我写入SD卡
我也在网上查了很多,也没有得到具体的答案。 还有其他方法吗?请告诉我。
I am developing an app in which I wanted to download PDF files from internet in SD card only.
在 Android 4.4+ 上,您没有对 removable storage 的任意文件系统访问权限。
when I run this code Environment.getExternalStorageDirectory(); in android 4.4.4 it returns me internal storage.
它 returns 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.
在 Android 4.4+ 上,您没有对 removable storage 的任意文件系统访问权。
Is there any other way to do this?
在 Android 4.4+ 上,使用 ACTION_CREATE_DOCUMENT
— the Storage Access Framework 的一部分 — 允许用户决定放置内容的位置。你会得到一个Uri
。您可以将其与 ContentResolver
和 openOutputStream()
一起使用,将您的内容写入 Uri
标识的位置。这也使用户可以灵活地将文件放在用户想要的其他地方,例如 Google Drive、Dropbox 或应用存储提供商管理的任何其他地方。