0

In my Android Studio project I want to implement a function, where 3 files should get exported. So I want the user to choose a directory and enter the name for a new directory, in which the files are going to be stored.

Right now, I already have an intent which lets the user choose, where to place the new folder and how to name the new folder:

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType(DocumentsContract.Document.MIME_TYPE_DIR);
                intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.folder_backup));
                startActivityForResult(intent, REQUEST_CODE_SAVE_BACKUP);

In the onActivityResult method, I tried to save the 3 files. Here is the code:

@Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_SAVE_BACKUP
                && resultCode == Activity.RESULT_OK) {
            Uri uri = null;
            if (data != null) {
                uri = data.getData();

                String dbFileName = ExampleDatabase.DB_NAME;
                List<String> dbComponentsNames = new ArrayList<>();
                dbComponentsNames.add(dbFileName);
                dbComponentsNames.add(dbFileName + "-shm");
                dbComponentsNames.add(dbFileName + "-wal");

                try {

                    for (int i = 0; i < dbComponentsNames.size(); i++) {
                        uri = Uri.parse(uri.toString() + "%2F" + dbComponentsNames.get(i));
                        File dbComponent = getActivity().getDatabasePath(dbComponentsNames.get(i));

                        byte[] byteArray = new byte[(int) dbComponent.length()];
                        FileInputStream fileInputStream = new FileInputStream(dbComponent);
                        fileInputStream.read(byteArray);

                        ParcelFileDescriptor pfd = getActivity().getContentResolver().openFileDescriptor(uri, "w");
                        FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
                        fileOutputStream.write(byteArray);
                        pfd.close();
                    }
                } catch (Exception e) {

                }
            }
        }
    }

My idea was to get the URI from the created folder and just append the file names to that URI, so these files get stored in the newly created folder. I also found out, that a \ in the URI is replaced by %2F but this doesn't matter. Does anyone know, how to achieve saving multiple files without using MediaStore?

Leon
  • 195
  • 2
  • 10
  • Further you cannot use the File class using SAF. And it does not make sense to use an (file)inputstresm to create a file. – blackapps Dec 05 '19 at 20:34
  • How to create a directory or file in the newly created directory you can find here: https://stackoverflow.com/questions/59189631 – blackapps Dec 05 '19 at 21:00
  • `My idea was to get the URI from the created folder and just append the file names to that URI` Well that is not possible under SAF. – blackapps Dec 05 '19 at 21:01
  • That was too early said. Indeed you can let the user create a directory (ab)using ACTION_CREATE_DOCUMENT with dir type and you get an uri. But the uri is useless. Its not a tree uri. Change your approach. Use ACTION_OPEN_DOCUMENT_TREE to let the user pick a folder. Doing so the user can create new folders first and then pick the finall one. – blackapps Dec 05 '19 at 21:49
  • @blackapps Thanks for you answer. Can you please clarify, why I cannot use file class and why it doesn't make sense to use inputstream? Here: https://stackoverflow.com/questions/14376807/how-to-read-write-string-from-a-file-in-android and here: https://stackoverflow.com/questions/13352972/convert-file-to-byte-array-and-vice-versa this is done the same way. The file is first converted into a byte array through the inputstream and then it is saved through the output stream. – Leon Dec 06 '19 at 06:27
  • I wrote `And it does not make sense to use an (file)inputstresm to create a file.`. But you did not do that. And you could have corrected me. – blackapps Dec 06 '19 at 09:15
  • But the approch with loading the complete file completely in a byte array is a bad one. When it is 3GB? Better make a loop where you read a chunk and immediately write to the output. – blackapps Dec 06 '19 at 09:18

0 Answers0