Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android access to folder is only granted until app is closed

Tags:

java

android

When my app is launched for the first time and the Intent.ACTION_OPEN_DOCUMENT_TREE is called then I choose my desired folder in file explorer, my code works fine until I do "Force close app". After that I get an en exception (dfFinalDir is null):

java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.documentfile.provider.DocumentFile androidx.documentfile.provider.DocumentFile.findFile(java.lang.String)' on a null object reference

I guess it happens maybe because after closing the app I lose my access to folder, but shouldn't it be permanently? I hope so and this is what I want to achieve.

private void writeDataToFile(Intent intent) {

    String uriString = sp.getString("auto_backup_uri", "");

    if (uriString.equals("")) {
        Util.initConfirmDialog(this, getString(R.string.choose_folder_for_auto_backup) + getString(R.string.app_name_no_space) + "/", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Log.i("TAG", "Trying to get access the desired folder");
                Intent intent2 = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                startActivityForResult(intent2, AppConstants.GRANT_ACCESS_TO_AUTO_BACKUP_FILE);
            }
        });
    }

    if (!uriString.equals("")) {
        Log.i("TAG", "Trying to write data to file " + uriString);
        Uri uri = Uri.parse(uriString);
        DocumentFile dfBeforeFinalDir = DocumentFile.fromTreeUri(this, uri);
        DocumentFile dfFinalDir = dfBeforeFinalDir.findFile(getString(R.string.app_name_no_space));

        // HERE IS AN EXCEPTION
        DocumentFile dfFinalAutoBackupFile = dfFinalDir.findFile("notatki_a");


        if (dfFinalAutoBackupFile == null) {
            Log.i("TAG", "Auto backup file does not exist, creating new one");
            dfFinalAutoBackupFile = dfFinalDir.createFile("application/*", "notatki_a");
        }

        OutputStream fileOutputStream = null;
        try {
            fileOutputStream = getContentResolver().openOutputStream(dfFinalAutoBackupFile.getUri());
        } catch (FileNotFoundException e) {
            doWhenException(e, "The provided URI could not be opened", intent);
        }
        try {
            fileOutputStream.write(jsonNotes.getBytes(StandardCharsets.UTF_8));
            fileOutputStream.close();
            intent.putExtra("auto_save_status", AppConstants.SUCCESS);
        } catch (IOException e) {
            doWhenException(e, "An IOException during writing data to newly created file", intent);
        } finally {
            if (extNoteOrder > 0)
                intent.putExtra("ext_note_order", extNoteOrder);
            startActivity(intent);
        }
    }
}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    super.onActivityResult(requestCode, resultCode, resultData);
    if (requestCode == AppConstants.GRANT_ACCESS_TO_AUTO_BACKUP_FILE && resultCode == Activity.RESULT_OK) {
        if (resultData != null) {
            Uri uri = resultData.getData();
            spEditor.putString("auto_backup_uri", uri.toString()).apply();

            DocumentFile documentFile = DocumentFile.fromTreeUri(this, uri);

            try {
                DocumentFile dfFinalDir = documentFile.findFile(getString(R.string.app_name_no_space));
                if (dfFinalDir == null) {
                    dfFinalDir = documentFile.createDirectory(getString(R.string.app_name_no_space));
                }
                if (dfFinalDir != null) {
                    Util.initConfirmDialogNoNegButton(this, getString(R.string.you_can_do_with_auto_backup));
                }


            } catch (Exception e) {
                Util.doWhenException(this, e, "The problem with /" + getString(R.string.app_name_no_space) + "/ folder: " + e.getMessage());
            }
        }
    }
}

private void doWhenException(Exception e, String exCause, Intent intent) {
    Log.e("TAG", exCause);
    Toast.makeText(ActivityNewEditNote.this, e.getMessage(), Toast.LENGTH_SHORT).show();
    e.printStackTrace();
    intent.putExtra("auto_save_status", AppConstants.FAILURE);
}

1 Answers

You need to takePersistableUriPermission() to keep access across runs without re-asking the user to choose the directory.

See Persist permissions for details on how to do this.

like image 111
Scott Stanchfield Avatar answered Oct 22 '25 14:10

Scott Stanchfield



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!