Android Studio - java.io.FileNotFoundException: /abc.csv 打开失败:EACCES(权限被拒绝)
Android Studio - java.io.FileNotFoundException: /abc.csv open failed: EACCES (Permission denied)
我正在尝试读取 CSV 文件,将其内容加载到微调器中。我给了相关权限 MANAGE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE 从外部存储读取文件。我已将 CSV 文件放在运行时请求权限的目录中。另外 file.exists() 函数 return true 但仍然无法读取 csv 文件。我哪里错了?
这是错误日志:
022-02-27 18:03:32.457 13080-13080/com.example.locationfetcher_v2 W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Khidmah/input.csv: open failed: EACCES (Permission denied)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.IoBridge.open(IoBridge.java:492)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.io.FileInputStream.<init>(FileInputStream.java:160)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.io.FileInputStream.<init>(FileInputStream.java:115)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.io.FileReader.<init>(FileReader.java:58)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at com.example.locationfetcher_v2.MainActivity.onCreate(MainActivity.java:157)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.Activity.performCreate(Activity.java:8157)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.Activity.performCreate(Activity.java:8129)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3494)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3693)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2135)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.os.Looper.loop(Looper.java:236)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread.main(ActivityThread.java:8059)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.Linux.open(Native Method)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7932)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.IoBridge.open(IoBridge.java:478)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: ... 19 more
下面是我的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Using Dexter Library
Dexter.withContext(this)
.withPermissions(
Manifest.permission.MANAGE_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CAMERA
).withListener(new MultiplePermissionsListener() {
@Override public void onPermissionsChecked(MultiplePermissionsReport report) {/* ... */}
@Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {/* ... */}
}).check();
MultiplePermissionsListener dialogMultiplePermissionsListener =
DialogOnAnyDeniedMultiplePermissionsListener.Builder
.withContext(this)
.withTitle("Camera, Storage and Location permission")
.withMessage("All Camera, Storage and Location permission are required for this application")
.withButtonText(android.R.string.ok)
.build();
//// Read data from CSV file
List<String> addresses = new ArrayList<String>();
Spinner address_spinner = findViewById(R.id.spinnerAddress);
// File file = new File(Environment.getExternalStorageDirectory() + "/Khidmah/", "input.csv");
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "input.csv");
show_notification(file.getPath());
show_notification(new Boolean(file.exists()).toString());
FileInputStream fis = null;
try {
if (file.exists()){
show_notification("can read - " + new Boolean(file.canRead()).toString());
CSVReader reader = new CSVReader(new FileReader(file.toURI().toString()));
show_notification("successfully read file...");
String[] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
// System.out.println(nextLine[0] + nextLine[1] + nextLine[2]);
addresses.add(nextLine[0] + nextLine[1] + nextLine[2]);
show_notification(nextLine[0] + nextLine[1] + nextLine[2]);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item,addresses);
address_spinner.setAdapter(adapter);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (CsvValidationException e) {
e.printStackTrace();
}
}
这里是AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.locationfetcher_v2">
<!-- Always include this permission -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Include only if your app benefits from precise location access. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LocationFetcher_v2"
android:foregroundServiceType="location">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>
更新
我现在正在使用 Dexter Library 授予权限。我添加了额外的权限 MANAGE_EXTERNAL_STORAGE 并将 input.csv 文件放在 Public 目录中,即下载文件夹。但是现在它给出了以下错误:
open failed: ENOENT (No such file or directory)
在 File.exists() 之后,在对文件执行操作之前使用 File.canRead()。
此 csv 文件不是由您的应用创建的。
因此,在 Android 11,您不是所有者,尽管您的应用可以检查文件是否存在,但它发现 File.canRead() 文件不可访问。
使用 MANAGE_EXTERNAL_STORAGE 和正确的运行时代码,您的应用可以获得访问权限。
正确的代码将启动 Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
的意图。
我正在尝试读取 CSV 文件,将其内容加载到微调器中。我给了相关权限 MANAGE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE 从外部存储读取文件。我已将 CSV 文件放在运行时请求权限的目录中。另外 file.exists() 函数 return true 但仍然无法读取 csv 文件。我哪里错了?
这是错误日志:
022-02-27 18:03:32.457 13080-13080/com.example.locationfetcher_v2 W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Khidmah/input.csv: open failed: EACCES (Permission denied)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.IoBridge.open(IoBridge.java:492)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.io.FileInputStream.<init>(FileInputStream.java:160)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.io.FileInputStream.<init>(FileInputStream.java:115)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.io.FileReader.<init>(FileReader.java:58)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at com.example.locationfetcher_v2.MainActivity.onCreate(MainActivity.java:157)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.Activity.performCreate(Activity.java:8157)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.Activity.performCreate(Activity.java:8129)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3494)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3693)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2135)
2022-02-27 18:03:32.461 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.os.Looper.loop(Looper.java:236)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread.main(ActivityThread.java:8059)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.Linux.open(Native Method)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7932)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: at libcore.io.IoBridge.open(IoBridge.java:478)
2022-02-27 18:03:32.462 13080-13080/com.example.locationfetcher_v2 W/System.err: ... 19 more
下面是我的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Using Dexter Library
Dexter.withContext(this)
.withPermissions(
Manifest.permission.MANAGE_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CAMERA
).withListener(new MultiplePermissionsListener() {
@Override public void onPermissionsChecked(MultiplePermissionsReport report) {/* ... */}
@Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {/* ... */}
}).check();
MultiplePermissionsListener dialogMultiplePermissionsListener =
DialogOnAnyDeniedMultiplePermissionsListener.Builder
.withContext(this)
.withTitle("Camera, Storage and Location permission")
.withMessage("All Camera, Storage and Location permission are required for this application")
.withButtonText(android.R.string.ok)
.build();
//// Read data from CSV file
List<String> addresses = new ArrayList<String>();
Spinner address_spinner = findViewById(R.id.spinnerAddress);
// File file = new File(Environment.getExternalStorageDirectory() + "/Khidmah/", "input.csv");
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "input.csv");
show_notification(file.getPath());
show_notification(new Boolean(file.exists()).toString());
FileInputStream fis = null;
try {
if (file.exists()){
show_notification("can read - " + new Boolean(file.canRead()).toString());
CSVReader reader = new CSVReader(new FileReader(file.toURI().toString()));
show_notification("successfully read file...");
String[] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
// System.out.println(nextLine[0] + nextLine[1] + nextLine[2]);
addresses.add(nextLine[0] + nextLine[1] + nextLine[2]);
show_notification(nextLine[0] + nextLine[1] + nextLine[2]);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item,addresses);
address_spinner.setAdapter(adapter);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (CsvValidationException e) {
e.printStackTrace();
}
}
这里是AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.locationfetcher_v2">
<!-- Always include this permission -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Include only if your app benefits from precise location access. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LocationFetcher_v2"
android:foregroundServiceType="location">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>
更新
我现在正在使用 Dexter Library 授予权限。我添加了额外的权限 MANAGE_EXTERNAL_STORAGE 并将 input.csv 文件放在 Public 目录中,即下载文件夹。但是现在它给出了以下错误:
open failed: ENOENT (No such file or directory)
在 File.exists() 之后,在对文件执行操作之前使用 File.canRead()。
此 csv 文件不是由您的应用创建的。
因此,在 Android 11,您不是所有者,尽管您的应用可以检查文件是否存在,但它发现 File.canRead() 文件不可访问。
使用 MANAGE_EXTERNAL_STORAGE 和正确的运行时代码,您的应用可以获得访问权限。
正确的代码将启动 Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
的意图。