简体   繁体   English

Crosswalk Cordova Android多文件选择

[英]Crosswalk Cordova Android multiple file select

I have a hybrid app built using cordova and angularjs, for Android I run the app using crosswalk. 我有一个使用cordova和angularjs构建的混合应用程序,对于Android我使用人行横道运行应用程序。

I've been scouring the internet to find the solution for the html5 file input to allow selection of multiple files. 我一直在网上搜索html5文件输入的解决方案,以允许选择多个文件。

I'm using the following element for file selecting: 我正在使用以下元素进行文件选择:

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

I am running Android Lollipop version 5.1.1 and Crosswalk version 20, I have tested with Crosswalk version 18 and 19 also. 我正在运行Android Lollipop版本5.1.1和Crosswalk版本20,我已经使用Crosswalk版本18和19进行了测试。 Chrome is installed on my device running the latest version although I don't think that makes a difference. Chrome已安装在运行最新版本的设备上,但我认为这不会产生任何影响。

When I click the input element above I get the expected dialog asking me to select from my Documents or Camera. 当我点击上面的输入元素时,我得到了预期的对话框,要求我从我的文档或相机中进行选择。 If I choose to select from my Documents then I am only able to select single files, in this case images. 如果我选择从我的文档中选择,那么我只能选择单个文件,在这种情况下是图像。 This is true for every App that I can select images from, so the default android 'Images', 'Videos', 'Audio', etc and external Apps such as Google Photos - All only allow me to select one single file at a time. 对于我可以从中选择图像的每个应用程序都是如此,因此默认的Android“图像”,“视频”,“音频”等以及Google照片等外部应用程序 - 所有这些只允许我一次选择一个文件。

In the image below you can see the files listed, a long press on each tile does not add the file to a multiple selection. 在下面的图像中,您可以看到列出的文件,长按每个图块不会将文件添加到多个选择中。

在此输入图像描述

This works on the IOS version of the App. 这适用于App的IOS版本。

After digging through all the material I can find online it seems that the multiple attribute is supported on Android 5+ running Chrome 49+. 在深入了解我可以在网上找到的所有材料后,似乎Android 5+运行Chrome 49+支持多重属性。

I'm unsure if this is a crosswalk browser implementation or Android Operating System issue, or something else? 我不确定这是一个人行横道浏览器实现还是Android操作系统问题,还是其他什么? Could anyone advise. 任何人都可以建议。

Edit 编辑

Just to confirm this does not work with or without using Crosswalk. 只是为了确认这与使用或不使用Crosswalk无效。

After weeks of trying to sort this out, I finally got it to work (Cordova without Crosswalk). 经过数周的努力解决这个问题,我终于开始工作了(没有Crosswalk的Cordova)。 This was done using Cordova Tools in Windows so please pardon the filespecs below. 这是在Windows中使用Cordova Tools完成的,所以请原谅下面的文件规范。

Step 1: Change the minSdkVersion in platforms\\Android\\CordovaLib\\AndroidManifest.xml to 21 Explanation: onShowFileChooser API was introduced in LOLLIPOP (API 21). 步骤1:将platforms \\ Android \\ CordovaLib \\ AndroidManifest.xml中的minSdkVersion更改为21 说明: onShowFileChooser API在LOLLIPOP(API 21)中引入。 It allows returning url[] instead of url returned by showFileChooser in earlier API versions. 它允许返回url[]而不是早期API版本中showFileChooser返回的url This gets called only when you change the API to 21 or greater. 仅在将API更改为21或更高时才会调用此方法。

Step 2: Update/Replace the onActivityResult method to retrieve multiple files. 第2步:更新/替换onActivityResult方法以检索多个文件。 Append the following after creating intent using fileChooserParams to allow choosing multiple files: 使用fileChooserParams创建intent后添加以下fileChooserParams以允许选择多个文件:

    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

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

Step 3: Update the corresponding onActivityResult method to return multiple urls using intent.getClipData() . 步骤3:使用intent.getClipData()更新相应的onActivityResult方法以返回多个URL。

Caveats: 注意事项:

  1. Enables Multi-upload for all calls. 为所有呼叫启用多重上传。 You could update the intent based on fileChooserParams mode. 您可以根据fileChooserParams模式更新intent。
  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<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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM