user1584253
user1584253

Reputation: 1005

Android Studio - java.io.FileNotFoundException: /abc.csv open failed: EACCES (Permission denied)

I am trying to read a CSV file, load its content to a spinner. I have given relevant permissions MANAGE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE to read a file from external storage. I have placed the CSV file in a directory requested permission on runtime. Also the file.exists() function return true but still unable to read csv file. Where am I going wrong?

Here is the error log:

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

Below is my code:

            @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();
        }   
                }
    

Here is 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>

UPDATE

I am now using Dexter Library to grant permissions. I have added additional permission MANAGE_EXTERNAL_STORAGE and place the input.csv file in Public Directory i.e. Downloads folder. However now it's giving following error:

open failed: ENOENT (No such file or directory)

Upvotes: 2

Views: 3961

Answers (1)

blackapps
blackapps

Reputation: 9282

After File.exists() use File.canRead() before you act on the file.

This csv file is not created by your app.

Hence on Android 11 you are not the owner and although your app can check if the file exists it discovers with File.canRead() that the file is not accessable.

With MANAGE_EXTERNAL_STORAGE and the right runtime code your app can obtain access.

The right code would start an intent for Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION.

Upvotes: 0

Related Questions