Crosswalk Cordova Android多文件选择

时间:2016-09-08 12:20:49

标签: javascript android html5 cordova crosswalk

我有一个使用cordova和angularjs构建的混合应用程序,对于Android我使用人行横道运行应用程序。

我一直在搜索互联网,找到html5文件输入的解决方案,以便选择多个文件。

我使用以下元素进行文件选择:

<input type="file" multiple="multiple" name="files[]" />

我正在运行Android Lollipop版本5.1.1和Crosswalk版本20,我已经使用Crosswalk版本18和19进行了测试。 Chrome已安装在运行最新版本的设备上,但我认为这不会有所作为。

当我点击上面的输入元素时,我得到了预期的对话框,要求我从我的文档或相机中进行选择。如果我选择从我的文档中选择,那么我只能选择单个文件,在这种情况下是图像。对于我可以从中选择图像的每个应用程序都是如此,因此默认的Android&#39;图像&#39;视频&#39;音频&#39;等等和外部应用程序如Google相册 - 所有这些只允许我一次选择一个文件。

在下图中,您可以看到列出的文件,长按每个图块不会将文件添加到多个选择中。

enter image description here

这适用于App的IOS版本。

在深入了解我在网上找到的所有资料后,似乎Android 5+运行Chrome 49+支持多重属性。

我不确定这是一个人行横道浏览器实施或Android操作系统问题,还是其他什么?任何人都可以提出建议。

修改

只是为了确认无论是否使用Crosswalk都无效。

1 个答案:

答案 0 :(得分:4)

经过几周的努力解决这个问题,我终于开始工作了(没有Crosswalk的Cordova)。这是在Windows中使用Cordova Tools完成的,所以请原谅下面的文件规范。

第1步:将平台\ Android \ CordovaLib \ AndroidManifest.xml中的minSdkVersion更改为21 说明: onShowFileChooser API是在LOLLIPOP(API 21)中引入的。它允许在早期的API版本中返回url[]而不是url返回的showFileChooser。仅在将API更改为21或更高时才会调用此方法。

第2步:更新/替换onActivityResult方法以检索多个文件。 使用fileChooserParams创建意图后添加以下内容以允许选择多个文件:

    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

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

第3步:使用onActivityResult更新相应的intent.getClipData()方法以返回多个网址。

<强>注意事项:

  1. 为所有通话启用多重上传。您可以根据fileChooserParams模式更新intent。
  2. 禁用相机作为选择器中的来源,默认情况下可用于人行横道。
  3. 最终守则:

    Uri photoUri;
    
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> 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;
    }