filestack / filestack-android

Official Android SDK for Filestack - API and content management system that makes it easy to add powerful file uploading and transformation capabilities to any web or mobile application.
https://www.filestack.com
Apache License 2.0
154 stars 90 forks source link

Can't upload multiple files at once #120

Closed filippolightful closed 6 years ago

shawnmaten commented 7 years ago

Could you please provide some description about your issue?

filippolightful commented 7 years ago
E/AndroidRuntime: FATAL EXCEPTION: IntentService[ContentService]
                                                                                     Process: dev.com.lightful.mobile.android.b2b, PID: 24825
                                                                                     java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
                                                                                         at io.filepicker.utils.FilesUtils.readPathFromUri(FilesUtils.java:117)
                                                                                         at io.filepicker.utils.FilesUtils.getPath(FilesUtils.java:69)
                                                                                         at io.filepicker.services.ContentService.handleActionUploadFile(ContentService.java:513)
                                                                                         at io.filepicker.services.ContentService.onHandleIntent(ContentService.java:273)
                                                                                         at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:67)
                                                                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                                         at android.os.HandlerThread.run(HandlerThread.java:61)
filippolightful commented 7 years ago

It might be happening on lollipop and above devices, rather than getting the Uri from intent.getData() get it from clipdata as all items are stored in a list

Example:

 try {
            // When an Image is picked
            if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == RESULT_OK
                    && null != data) {
                // Get the Image from data

                String[] filePathColumn = { MediaStore.Images.Media.DATA };
                imagesEncodedList = new ArrayList<String>();
                if(data.getData()!=null){

                    Uri mImageUri=data.getData();

                    // Get the cursor
                    Cursor cursor = getContentResolver().query(mImageUri,
                            filePathColumn, null, null, null);
                    // Move to first row
                    cursor.moveToFirst();

                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    imageEncoded  = cursor.getString(columnIndex);
                    cursor.close();

                }else {
                    if (data.getClipData() != null) {
                        ClipData mClipData = data.getClipData();
                        ArrayList<Uri> mArrayUri = new ArrayList<Uri>();
                        for (int i = 0; i < mClipData.getItemCount(); i++) {

                            ClipData.Item item = mClipData.getItemAt(i);
                            Uri uri = item.getUri();
                            mArrayUri.add(uri);
                            // Get the cursor
                            Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
                            // Move to first row
                            cursor.moveToFirst();

                            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                            imageEncoded  = cursor.getString(columnIndex);
                            imagesEncodedList.add(imageEncoded);
                            cursor.close();

                        }
                        Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());
                    }
                }
            } else {
                Toast.makeText(this, "You haven't picked Image",
                        Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
                    .show();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }
shawnmaten commented 7 years ago

This should be fixed in version 4.0.2 available now. Let us know if you're still having issues. Thanks for reporting!

filippolightful commented 7 years ago

@shawnmaten, this fix the crash, but still it uploads one image as you are starting the service passing a single Uri at a time, you need to pass it as a List and when the service starts processing the file it can execute one by one. Now is like a race condition, yes it starts the service correctly, but the Uri extra will be replaced by the multiple image Uri and only the one who's lucky to be uploaded will be picked by this line Uri uri = intent.getParcelableExtra(EXTRA_FILE_URI);

There is another minor issue, which is when I try to upload a video there is a toast that says uploading image, I can give further examples if necessary, but for now let's fix this. I appreciate your help!

shawnmaten commented 7 years ago

The call we make to uploadLocalFile() in the Filepicker class eventually leads to a startService() call. The service that's started is an IntentService. An IntentService handles work on a separate worker thread and multiple calls to it get queued. This is documented here. So the URI isn't getting replaced, an intent is being created and queued for each.

That being said, I did find issues with how we're making networking calls within the ContentService class. The calls should be synchronous but they're actually asynchronous which is a problem because the service stops once onHandleIntent() is finished and our callback could come back to a finished thread. Although we seem be lucking out with that not causing a problem. I just uploaded 3, 20 MB local files with the updated code and I'm not having any issues. Did you actually run the updated version and if so did you have any issues with files not successfully uploading?

filippolightful commented 7 years ago

@shawnmaten, I am using the new library, but no luck uploading multiple files. Regarding the concept of IntentService, you are right but seems to be misguiding in this specific scenario. And also please remove the Toast that's shown while uploading a video.

Lukkub commented 7 years ago

@shawnmaten I had problem with crash issue when multiple files were uploded. I check new version and it fix crash but still not getting the whole list of uploaded files on acitivity result.

Lukkub commented 7 years ago

@shawnmaten Any update on this Issue ?

shawnmaten commented 6 years ago

@Lukkub Sorry this didn't get responded to for so long, but v2 should support this use case just fine. If you have an issue using v2, please open a new issue.