Search code examples
androidandroid-permissionsfile-permissionsandroid-12l

Android compileSdk 32, java.io.FileNotFoundException: /storage/emulated/0/Download/number sample.csv: open failed: EACCES (Permission denied)


I have compiled Android Project to 32(compileSdk 32) I'm trying to read the CSV files, so as per the Android Documentation, I'm getting the permission like below, I have added android:requestLegacyExternalStorage and asking the runtime permission as well, even though I'm getting the below exception after I picked and read the file, what went wrong this

readCSV: e /storage/emulated/0/Download/number sample.csv: open failed: EACCES (Permission denied)

manifest

<application
    android:allowBackup="true"
    android:dataExtractionRules="@xml/data_extraction_rules"
    android:fullBackupContent="@xml/backup_rules"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.app"
    android:requestLegacyExternalStorage="true"
    tools:targetApi="31">

AddContacts Activity

public class AddContacts extends AppCompatActivity {

    private static final String TAG = "AddContacts";

    private FloatingActionButton floatingActionButton;

    private boolean isReadPermissionGranded=false;
    ActivityResultLauncher<String[]> permissionResultLauncher;
    ActivityResultLauncher<String> getCSV;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contacts);

        floatingActionButton=findViewById(R.id.fab2);
        
        permissionResultLauncher=registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
            @Override
            public void onActivityResult(Map<String, Boolean> result) {
                if(result.get(Manifest.permission.READ_EXTERNAL_STORAGE)!=null){
                    isReadPermissionGranded= result.get(Manifest.permission.READ_EXTERNAL_STORAGE);
                }
            }
        });

        getCSV=registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri result) {
                Log.d(TAG, "onActivityResult: uri here - "+result);
                readCSV(result);
            }
        });


        floatingActionButton.setOnClickListener(view -> {
            requestPermission();
            if(ContextCompat.checkSelfPermission(AddContacts.this,Manifest.permission.READ_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED){
                getCSV.launch("*/*");
            }else{
                Log.d(TAG, "onCreate: no permission granted");
            }

        });

    }

    private String getRealPathFromURI(Uri contentURI) {
        String result;
        Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
        if (cursor == null) { // Source is Dropbox or other similar local file path
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
            result = cursor.getString(idx);
            cursor.close();
        }
        return result;
    }


    private void requestPermission(){
        
        isReadPermissionGranded= ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED;
        
        List<String> permissionRequest=new ArrayList<>();
        
        if(!isReadPermissionGranded){
            permissionRequest.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }
        
        if(!permissionRequest.isEmpty()){
            permissionResultLauncher.launch(permissionRequest.toArray(new String[0]));
        }

    }

    private void readCSV(Uri result) {
        Log.d(TAG, "readCSV: reading..");

        Uri selectedURI = Uri.parse(result.getPath());
        File file = new File(getRealPathFromURI(selectedURI));


        try {
            CSVReader reader = new CSVReader(new FileReader(file));
            String[] nextLine;
            while ((nextLine = reader.readNext()) != null) {
                // nextLine[] is an array of values from the line
                //   System.out.println(nextLine[0] + nextLine[1] + "etc...");
                Log.d(TAG, "readCSV: data is "+nextLine[0]);
            }
        } catch (IOException e) {
            Log.d(TAG, "readCSV: e "+e.getMessage());
        } catch (CsvValidationException e) {
            e.printStackTrace();
            Log.d(TAG, "readCSV: "+e.getMessage());
        }
    }
}

Solution

  • After getting the URI, create an Inputstream object and convert like thisinputStream = getContentResolver().openInputStream(uri);

    private void readCSV(Uri uri) {
    
            InputStream  inputStream = null;
            try {
                inputStream = getContentResolver().openInputStream(uri);
    
                List<String[]> list = new ArrayList<>();
                CSVReader csvReader = new CSVReader(new
                        InputStreamReader(inputStream));
                String[] line;
                while ((line = csvReader.readNext()) != null) {
                    System.out.println(line[0]+" --- "+line[1]);
                    list.add(line);
                }
                inputStream.close();
                csvReader.close();
    
            } catch (IOException | CsvValidationException e) {
                e.printStackTrace();
            }
            
        }