Crosswalk Cordova Android multiple file select

前端 未结 1 1701
小鲜肉
小鲜肉 2021-02-09 23:12

I have a hybrid app built using cordova and angularjs, for Android I run the app using crosswalk.

I\'ve been scouring the internet to find the solution for the html5 fi

1条回答
  •  爱一瞬间的悲伤
    2021-02-09 23:45

    After weeks of trying to sort this out, I finally got it to work (Cordova without Crosswalk). This was done using Cordova Tools in Windows so please pardon the filespecs below.

    Step 1: Change the minSdkVersion in platforms\Android\CordovaLib\AndroidManifest.xml to 21 Explanation: onShowFileChooser API was introduced in LOLLIPOP (API 21). It allows returning url[] instead of url returned by showFileChooser in earlier API versions. This gets called only when you change the API to 21 or greater.

    Step 2: Update/Replace the onActivityResult method to retrieve multiple files. Append the following after creating intent using fileChooserParams to allow choosing multiple files:

        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    

    Location: platforms\android\CordovaLib\src\org\apache\cordova\engine\SystemWebChromeClient.java

    Step 3: Update the corresponding onActivityResult method to return multiple urls using intent.getClipData().

    Caveats:

    1. Enables Multi-upload for all calls. You could update the intent based on fileChooserParams mode.
    2. Disables Camera as a source in chooser which is available with crosswalk by default.

    Final Code:

    Uri photoUri;
    
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean onShowFileChooser(WebView webView, final ValueCallback filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
        // Check and use MIME Type.
        String mimeType = "*/*";
        int ACTION_CODE = FILECHOOSER_RESULTCODE;
        try {
            if (fileChooserParams.getAcceptTypes().length > 0) {
                mimeType = fileChooserParams.getAcceptTypes()[0];
            } else {
                mimeType = "*/*";
            }
        } catch (Exception e) {
            mimeType = "*/*";
        };
    
        // Check if Mutiple is specified 
        Boolean selectMultiple = false;
        if (fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) {
            selectMultiple = true;
        };
    
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        if (selectMultiple) { intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); };
        intent.setType(mimeType);
        ACTION_CODE = FILECHOOSER_RESULTCODE;
        final Intent chooserIntent = Intent.createChooser(intent, "Select Source");
    
        // Add camera intent to the chooser if image and send URI to return full image 
        if (mimeType.equals("image/*")) {
            photoUri = null;
            try {
                File photoFile = createImageFile();
                photoUri = Uri.fromFile(photoFile);
            }
            catch (Exception ex) {
                photoUri = null;
            }
            if (photoUri != null) {
                Intent camIntent = new Intent();
                camIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
                camIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                camIntent.putExtra("return-data", true);
                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent [] {camIntent} );
            }
        }
    
        try {
            parentEngine.cordova.startActivityForResult(new CordovaPlugin() {
                @Override
                public void onActivityResult(int requestCode, int resultCode, Intent intent) {
                    if (resultCode ==  Activity.RESULT_OK && intent != null) {
                        if (intent.getData() != null)
                        {
                            Uri[] result = WebChromeClient.FileChooserParams.parseResult(resultCode, intent);
                            filePathsCallback.onReceiveValue(result);
                        }
                        else
                        {
                            if (intent.getClipData() != null) {
                                final int numSelectedFiles = intent.getClipData().getItemCount();
                                Uri[] result = new Uri[numSelectedFiles];
                                for (int i = 0; i < numSelectedFiles; i++) {
                                    result[i] = intent.getClipData().getItemAt(i).getUri();
                                }
                                filePathsCallback.onReceiveValue(result);
                            }
                            else {
                                filePathsCallback.onReceiveValue(null);
                            }
                        }
                    }
                    else if(resultCode ==  Activity.RESULT_OK && (intent == null || intent.getData() == null )) {
                        Uri[] result = new Uri[1];
                        result[0] = photoUri;
                        filePathsCallback.onReceiveValue(result);
                    } else {
                        filePathsCallback.onReceiveValue(null);
                    }
                }
            }, chooserIntent, ACTION_CODE);
        } catch (ActivityNotFoundException e) {
            Log.w("No activity found to handle file chooser intent.", e);
            filePathsCallback.onReceiveValue(null);
        }
        return true;
    }
    

    0 讨论(0)
提交回复
热议问题