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(权限被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章