0

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());
        }
    }
}
FGH
  • 2,900
  • 6
  • 26
  • 59
  • You picked a file (for which you do not need any permission). After that you could read from the uri opening an inputstream for which you do not need any permission. – blackapps Oct 16 '22 at 07:33
  • 1
    But instead of doing so you did a nasty thing like trying to get a real parh from uri. Which you managed to do so. But only to discover that you have no permission for that file on Android 11+ devices even if you have the normal read permissions for external storage – blackapps Oct 16 '22 at 07:35
  • How can i read it A11 onwards , any APIs? – FGH Oct 16 '22 at 07:36
  • 1
    The normal read and write permissions are only for files created by your app on Android 11+ devices. – blackapps Oct 16 '22 at 07:37
  • 1
    I already told you: open an InputStream and give the stream to your readers. – blackapps Oct 16 '22 at 07:39
  • i done it, check the answer below, thanks ❤️ – FGH Oct 16 '22 at 08:45

1 Answers1

0

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();
        }
        
    }
FGH
  • 2,900
  • 6
  • 26
  • 59