OneDrive/onedrive-explorer-android

Upload operation in onedrive-explorer-android example

Closed this issue · 4 comments

What does it mean "Upload" item in your ActionBar overflow menu? Upload from where and to which destination? I have tried to upload file from phone memory (/storage/emulated/0) and was forced to make some changes in your sources to make this operation successful:
First of all add read/write permissions to Manifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />         
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

And then when I pick up file on phone memory data.getData() has scheme "file", not a "content" and I have to change your code to:

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        final BaseApplication application = (BaseApplication) getActivity().getApplication();
        final IOneDriveClient oneDriveClient = application.getOneDriveClient();
        if (requestCode == REQUEST_CODE_SIMPLE_UPLOAD
                && data != null
                && data.getData() != null
                && data.getData().getScheme().equalsIgnoreCase(SCHEME_FILE)) {
            final ProgressDialog dialog = new ProgressDialog(getActivity());
            dialog.setTitle(R.string.upload_in_progress_title);
            dialog.setMessage(getString(R.string.upload_in_progress_message));
            dialog.setIndeterminate(false);
            dialog.setCancelable(false);
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
           dialog.setProgressNumberFormat(getString(R.string.upload_in_progress_number_format));
            dialog.show();
            final AsyncTask<Void, Void, Void> uploadFile = new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(final Void... params) {
                    try {
                        RandomAccessFile f = new RandomAccessFile(data.getData().getPath(), "r");
                        byte[] fileInMemory = new byte[(int)f.length()];
                        f.read(fileInMemory); //Memory consuption - for small files only!
                        final String filename = data.getData().getLastPathSegment();
                        final Option option = new QueryOption("@name.conflictBehavior", "fail");
                        oneDriveClient
                                .getDrive()
                                .getItems(mItemId)
                                .getChildren()
                                .byId(filename)
                                .getContent()
                                .buildRequest(Collections.singletonList(option))
                                .put(fileInMemory,
                                        new IProgressCallback<Item>() {
                                            @Override
                                            public void success(final Item item) {
                                                dialog.dismiss();
                                                Toast.makeText(getActivity(),
                                                        application
                                                                .getString(R.string.upload_complete,
                                                                        item.name),
                                                        Toast.LENGTH_LONG).show();
                                                refresh();
                                            }

                                            @Override
                                            public void failure(final ClientException error) {
                                                dialog.dismiss();
                                                if (error.isError(OneDriveErrorCodes.NameAlreadyExists)) {
                                                    Toast.makeText(getActivity(),
                                                            R.string.upload_failed_name_conflict,
                                                            Toast.LENGTH_LONG).show();
                                                } else {
                                                    Toast.makeText(getActivity(),
                                                            application
                                                                    .getString(R.string.upload_failed,
                                                                            filename),
                                                            Toast.LENGTH_LONG).show();
                                                }
                                            }

                                            @Override
                                            public void progress(final long current, final long max) {
                                                dialog.setProgress((int) current);
                                                dialog.setMax((int) max);
                                            }
                                        });
                    } catch (final Exception e) {
                        Log.e(getClass().getSimpleName(), e.getMessage());
                        Log.e(getClass().getSimpleName(), e.toString());
                    }
                    return null;
                }
            };
            uploadFile.execute();
        }
    }

After it I become able to upload file from phone to cloud. Maybe there is something in your code I don't understand?

The selected file will be uploaded to the current folder on OneDrive, so if you are at viewing the root of your OneDrive, the file you pick from off your device will be uploaded into that location.

If you would like to add support to this application to also select file:// items, I'd be happy to review a pull request.

I just try to understand how did you intend to use "upload" menu item in your code? Namely, how to get file as a "content" scheme in your explorer? Would you be so kind to give me a use case of it?

When using the file picker there are several possible schemes that could be returned, when I implemented the picker I opted for the content:// scheme which is designed by Android to be the most 'universal' interface to content on the device via content resolvers.