Android 6.0系統讀寫檔案出現FileNotFoundException:EACCES (permission denied)解決辦法
先檢查你的AndroidManifest.xml是否已經有讀寫許可權:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
然後在獲取檔案流的時候,報出異常資訊:
程式碼:
bis = new BufferedInputStream(new FileInputStream(inFile));
異常是: FileNotFoundException:EACCES (permission denied)
異常的意思是檔案不存在,並且許可權有問題,但是許可權你也確實加了,這就是今天要解決的問題了。
由於Android 6.0 的許可權是一套新的授權機制,所以在用法上也格外的不同。
參考材料:
What Are Runtime Permissions?
With Android 6.0 Marshmallow, Google introduced a new permission model that allows users to better understand why an application may be requesting specific permissions. Rather than the user blindly accepting all permissions at install time, the user is now prompted to accept permissions as they become necessary during application use. As you probably already know, such a change requires efforts on the part of the application developer, but what happens if you do not implement this new model? Will your application still run? What changes do you have to make to be sure your application will run smoothly on all the versions you support?
This blog will step you through a sample application that demonstrates implementing the new permissions model all while answering commonly asked questions about the new model and how it affects your application.
When to Implement the New Model
The Good
The big question for many is: will my existing applications still work on Marshmallow devices? The good news is the new model has backwards compatibility- i.e. it doesn’t require full support until you choose to target version 23 in your application. If you are targeting version 22 or below, your application will request all permissions at install time just as it would on any device running an OS below Marshmallow.
The Bad
Just because we can fall back on the old model, it does not mean that we can just avoid the new model by never targeting Marshmallow. A user with a Marshmallow device will now have the ability to revoke dangerous permissions via the application settings (we will get into what a dangerous permission is later). This means that even though the user accepted all your permissions at install time, they can later decide to take some of those permissions away from you.
The Ugly
If you have chosen not to implement the new permissions model, the revocation of permissions can cause unwanted user experiences and in some cases application crashes. The OS attempts to handle these scenarios as gracefully as possibly but developers should not rely on the OS to handle this scenario perfectly. In my experience, most permission revocations will not cause an application crash, but will absolutely degrade user experience. However, the side-effects of permission revocation are specific to an application’s implementation and I highly suggest at the very least running your application on a Marshmallow emulator and testing your application with permission revocation.
新的許可權是Runtime Permissions,就是所謂的執行時許可權,所以就需要在用的時候去重新請求系統許可權並得到使用者的允許授權。
我的解決方法是在讀取檔案之前加上以下程式碼:
int REQUEST_EXTERNAL_STORAGE = 1;
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
MainActivity.this,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
然後執行程式碼的效果是:
點選允許,FileNotFoundException:EACCES (permission denied)
問題就解決了。
有不明白的,可以直接參考下面的參考文件。