Crosswalk Cordova Android múltiples archivos select

Tengo una aplicación híbrida construida usando cordova y angularjs, para Android ejecuto la aplicación usando cruce de peatones.

He estado recorriendo el Internet para encontrar la solución para la entrada de archivo html5 para permitir la selección de varios archivos.

Estoy utilizando el siguiente elemento para la selección de archivos:

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

Estoy ejecutando Android Lollipop versión 5.1.1 y Crosswalk versión 20, he probado con Crosswalk versión 18 y 19 también. Chrome está instalado en mi dispositivo que ejecuta la última versión, aunque no creo que haga una diferencia.

Cuando hago clic en el elemento de entrada anterior obtengo el diálogo esperado que me pide que seleccione de mis documentos o cámara. Si elijo seleccionar entre mis documentos, sólo puedo seleccionar archivos individuales, en este caso imágenes. Esto es cierto para todas las aplicaciones en las que puedo seleccionar imágenes, por lo que el androide predeterminado "Imágenes", "Videos", "Audio", etc y aplicaciones externas como Google Fotos – Todo sólo me permite seleccionar un solo archivo a la vez .

En la imagen de abajo puede ver los archivos listados, una pulsación larga en cada mosaico no agrega el archivo a una selección múltiple.

Introduzca aquí la descripción de la imagen

Esto funciona en la versión IOS de la aplicación.

Después de excavar a través de todo el material que puedo encontrar en línea, parece que el atributo múltiple es compatible con Android 5 + con Chrome 49+.

No estoy seguro de si se trata de una implementación de navegador de pasarela o problema del sistema operativo Android, o algo más? ¿Podría alguien aconsejar.

Editar

Sólo para confirmar esto no funciona con o sin usar Crosswalk.

Después de semanas de tratar de solucionar esto, finalmente conseguí que funcione (Cordova sin Crosswalk). Esto se hizo con Cordova Tools en Windows así que por favor perdone los filespecs abajo.

Paso 1: Cambiar la minSdkVersion en las plataformas \ Android \ CordovaLib \ AndroidManifest.xml a 21 Explicación: onShowFileChooser API se introdujo en LOLLIPOP (API 21). Permite devolver url[] lugar de url devuelta por showFileChooser en versiones anteriores de API. Esto se llama sólo cuando cambia la API a 21 o mayor.

Paso 2: Actualizar / Sustituir el método onActivityResult para recuperar varios archivos. Añada lo siguiente después de crear el intento usando fileChooserParams para permitir la elección de varios archivos:

  intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); 

Ubicación: platform \ android \ CordovaLib \ src \ org \ apache \ cordova \ motor \ SystemWebChromeClient.java

Paso 3: Actualizar el método onActivityResult correspondiente para devolver varias urls utilizando el intent.getClipData() .

Advertencias:

  1. Permite la carga múltiple para todas las llamadas. Puede actualizar la intención en función del modo fileChooserParams.
  2. Desactiva la cámara como fuente en el selector que está disponible con el paso de peatones de forma predeterminada.

Código final:

 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; } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.