ammarahm-ed / react-native-scoped-storage

MIT License
58 stars 10 forks source link

openDocumentTree and go back on UI #15

Closed projectnetworld closed 2 years ago

projectnetworld commented 2 years ago

there is currently this issue that when you want to choose a directory for ( downloading ) its works fine if you proceed and choose one folder but when the user decides to cancel the download ( android go back button ) the at some point it will be back on the app but the download process is still on going ?

how should we cancel the process safely?

        if (Platform.OS === 'android') {
            // Android saves downloaded file buffer to user selected folder
            openDocumentTree(false).then(response => {
                writeFile(response.uri, filename, '*/*', buff, 'base64', false).then(() => {
                    HelperSendLocalNotification(
                        'Download Completed',
                        'File:' + filename,
                        moment().valueOf().toString(),
                        EnumLocalNotificationId.Download_Complete,
                        response.uri,
                    );
                    resolve();
                });
            });
        } 
ammarahm-ed commented 2 years ago

Use createDocument for one time download to a folder.

You can return if the download is cancelled? I don't see the download related code here? Another way would be to delete the file if it was written possibly. Otherwise do nothing.

projectnetworld commented 2 years ago

Use createDocument for one time download to a folder.

You can return if the download is cancelled? I don't see the download related code here? Another way would be to delete the file if it was written possibly. Otherwise do nothing.

Hi Thx for the reply also thx for suggestion the createDocument but the problem exists also with this function here is what is missing in such function please have a look you the problem is that you just assume the ideal scenario and not thinking if something go wrong to reject the promise such as user just navigate back to the app with back button https://github.com/ammarahm-ed/react-native-scoped-storage/blob/d5c1d75312f84915a096d5b665490aa762a3e905/android/src/main/java/com/ammarahmed/scopedstorage/RNScopedStorageModule.java

    public void createDocument(final String fileName, final String mimeType, final String data, final String encoding, final Promise promise) {
        try {

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_CREATE_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.putExtra(Intent.EXTRA_TITLE, fileName);
        intent.setType(mimeType);

        if (activityEventListener != null) {
            reactContext.removeActivityEventListener(activityEventListener);
            activityEventListener = null;
        }
        activityEventListener = new ActivityEventListener() {
            @Override
            public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
                if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
                    if (intent != null) {
                        Uri uri = intent.getData();

                        DocumentFile dir = DocumentFile.fromSingleUri(reactContext,uri);
                        try {
                            byte[] bytes = stringToBytes(data, encoding);
                            OutputStream os = reactContext.getContentResolver().openOutputStream(uri);
                            try {
                                os.write(bytes);
                            } finally {
                                os.close();
                            }
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        WritableMap params = Arguments.createMap();
                        params.putString("uri", dir.getUri().toString());
                        params.putString("name", dir.getName());
                        params.putString("type", dir.isDirectory() ? "directory" : "file");
                        if (dir.isFile()) {
                            params.putString("mime", dir.getType());
                        }
                        params.putDouble("lastModified", dir.lastModified());
                        promise.resolve(params);
                    }
                /*MISSING*/

                else{
                  promise.reject();
                }

                /*END*/
                }

                /*MISSING*/

                else{
                  promise.reject();
                }

                /*END*/

                reactContext.removeActivityEventListener(activityEventListener);
                activityEventListener = null;
            }
ammarahm-ed commented 2 years ago

Nothing will happen if the user navigates back in the app after selecting the folder. The code will execute and complete. I don't see any problem. It's working great in a production app for me.

projectnetworld commented 2 years ago

Nothing will happen if the user navigates back in the app after selecting the folder. The code will execute and complete. I don't see any problem. It's working great in a production app for me.

yes exactly not after selecting a folder I mean before selection

this problem can be resolved by adding the else I mentioned

ammarahm-ed commented 2 years ago

Nothing will happen if the user navigates back in the app after selecting the folder. The code will execute and complete. I don't see any problem. It's working great in a production app for me.

yes exactly not after selecting a folder I mean before selection

  • user starts to download
  • after download the file tree opens (createDocument )
  • the user now must select a folder to put the file in ( createDocument )
  • here the user would not select any folder but only press the nav back button until the root folder and then form the document tree to app and the app is still waiting for the user to select a folder to put the file

this problem can be resolved by adding the else i mentioned

It is already handled. It will return null if there is no folder selected.

projectnetworld commented 2 years ago

Nothing will happen if the user navigates back in the app after selecting the folder. The code will execute and complete. I don't see any problem. It's working great in a production app for me.

yes exactly not after selecting a folder I mean before selection

  • user starts to download
  • after download the file tree opens (createDocument )
  • the user now must select a folder to put the file in ( createDocument )
  • here the user would not select any folder but only press the nav back button until the root folder and then form the document tree to app and the app is still waiting for the user to select a folder to put the file

this problem can be resolved by adding the else i mentioned

It is already handled. It will return null if there is no folder selected.

here is the control line

        const CreatedFile = await createDocument(filename, '*/*', buff, 'base64');
        console.log(CreatedFile);

the line console.log(CreatedFile); would never be invoked/executed

projectnetworld commented 2 years ago

Nothing will happen if the user navigates back in the app after selecting the folder. The code will execute and complete. I don't see any problem. It's working great in a production app for me.

yes exactly not after selecting a folder I mean before selection

  • user starts to download
  • after download the file tree opens (createDocument )
  • the user now must select a folder to put the file in ( createDocument )
  • here the user would not select any folder but only press the nav back button until the root folder and then form the document tree to app and the app is still waiting for the user to select a folder to put the file

this problem can be resolved by adding the else i mentioned

It is already handled. It will return null if there is no folder selected.

Hi Did you try the code i sent ?

ammarahm-ed commented 2 years ago

@projectnetworld Can you try the master branch and see if it is working as expected now?

yarn add https://github.com/ammarahm-ed/react-native-scoped-storage.git
projectnetworld commented 2 years ago

@projectnetworld Can you try the master branch and see if it is working as expected now?

yarn add https://github.com/ammarahm-ed/react-native-scoped-storage.git

Hi yes it works as expected now ,the null is now returned thx for the fix

gkasireddy202 commented 2 years ago

How to create directory without using openDocumentTree() method and also how to get path for create directory.

ammarahm-ed commented 2 years ago

@gkasireddy202 You can't. that's how scoped storage works. You can't just access stuff without acquiring permissions first. To get path for a directory, use openDocumentTree

gkasireddy202 commented 2 years ago

I am using below code for acquiring permissions but below error is occurred. Can you please share example code for acquiring permissions and create directory.

'/storage/emulated/0'does not have permission to create directories - This error is occurred by using below code for creating the directory in external storage.

createDirectory=async()=>{

const path = ${RNFS.ExternalStorageDirectoryPath}; try { const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE ); if (granted == PermissionsAndroid.RESULTS.GRANTED) { ScopedStorage.createDirectory(path, "TEST").then((obj) => { alert(obj) }) .catch(error => { console.log("ERROR" + error) })

    } else {
        console.log('permission denied');
    }
} catch (err) {
    console.warn(err);
}

}