Mi aplicación está basada en la web y he de subir las imágenes de un campo de ENTRADA del campamento. He dos situaciones y como no conozco otra manera de hacerlo dependiendo de la página que estoy eligiendo uno u otro con «boolean boolFileChoser» en función de su dirección URL de la petición:

una. selector de archivos

b. la cámara de fotos.

He tratado con selector de archivos y cargar el archivo a la perfección, el problema es con la cámara. Una vez que trato de subir la Cámara Pic, se bloquea.
Hasta donde yo sé porque la URI.

a) selector de Archivos: contenido://media/external/images/1234

b) Cámara de disparar: file:///mnt/sdcard/Pic.jpg

He encontrado ninguna manera de cambiarlo.

Ver la actualización

ahora se bloquea debido a un nullpointerexception al intentar cargar el «content://media/external/images/1234». (sólo con la cámara, no del selector de archivos. ).
También si el selector/cámara está cerrada (botón atrás), yo soy incapaz de llamar de nuevo.

El caso a) y b) del 100% de trabajo, aquí está el código de trabajo, incluyendo cómo puedo saber si fileChooser o la cámara se llama:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode != RESULT_OK) {
/** fixed code **/
//To be able to use the filechooser again in case of error
mUploadMessage.onReceiveValue(null);
/** fixed code **/
return;
}
if (mUploadMessage==null) {
Log.d("androidruntime","no mUploadMessage");
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
Uri selectedImage= intent == null || resultCode != RESULT_OK ? null : intent.getData();
Log.d("androidruntime","url: "+selectedImage.toString());
}else if (requestCode == CAMERAREQUEST_RESULTCODE) { 
if(mCapturedImageURI==null){
Log.d("androidruntime","no mCapturedImageURI");
return;
}
/** fixed code **/
getContentResolver().notifyChange(mCapturedImageURI, null);
ContentResolver cr = getContentResolver();
Uri uriContent= Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null));
photo = null;
/** fixed code **/
}
mUploadMessage.onReceiveValue(selectedImage);
mUploadMessage = null;
}
private static final int FILECHOOSER_RESULTCODE   = 2888;
private static final int CAMERAREQUEST_RESULTCODE = 1888;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
protected class AwesomeWebChromeClient extends WebChromeClient{
//Per Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){  
/**updated, out of the IF **/
mUploadMessage = uploadMsg;
/**updated, out of the IF **/
if(boolFileChooser){ //Take picture from filechooser
Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
i.addCategory(Intent.CATEGORY_OPENABLE);  
i.setType("image/*");  
MainActivity.this.startActivityForResult( Intent.createChooser( i, "Escoger Archivo" ), MainActivity.FILECHOOSER_RESULTCODE );  
} else { //Take photo and upload picture
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo = new File(Environment.getExternalStorageDirectory(),  "Pic.jpg");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
mCapturedImageURI = Uri.fromFile(photo);
startActivityForResult(cameraIntent, MainActivity.CAMERA_REQUEST);
}
}
//Per Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg){
openFileChooser(uploadMsg, "");
}
//Altre
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, "");
}
/** Added code to clarify chooser. **/
//The webPage has 2 filechoosers and will send a console message informing what action to perform, taking a photo or updating the file
public boolean onConsoleMessage(ConsoleMessage cm) {        
onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId());
return true;
}
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
Log.d("androidruntime", "Per cònsola: " + cm.message());
if(message.endsWith("foto")){ boolFileChooser= true; }
else if(message.endsWith("pujada")){ boolFileChooser= false; }
}
/** Added code to clarify chooser. **/
}

ACTUALIZACIÓN de 1

Podía obtener el «content://media/external/images/xxx» formato de uri, pero la aplicación todavía se bloquea al intentar cargar la uri a través de «mUploadMessage.onReceiveValue(selectedImage);». Ahora me estoy poniendo un nullpointerexception.


ACTUALIZACIÓN 2

Fijo y de trabajo.

He tenido la ‘ValueCallback uploadMsg’ en la variable local sólo en archivo-selector de caso, por lo que siempre tirado de mí una excepción cuando traté de subir una foto de archivo porque era nulo.
Una vez me sacó de if-else, todo lo trabajado.
La anterior actualización fue el método más fácil de lidiar con la carga de archivos.

Ya he añadido un ‘mUploadMessage.onReceiveValue(null)’; si la Cámara/filechooser intención es cancelado (debe lidiar con ella en su página web), si no, usted no será capaz de abrir el campo de ENTRADA (la Intención) de nuevo.


ACTUALIZACIÓN 3

Añadido la parte del código dentro de AwesomeChromeClient para discriminar la opción de tomar una foto o seleccionar un archivo.. es MI forma de hacerlo y añadido por petición, estoy seguro de que hay un montón de otras formas válidas para hacerlo,

El código es 100% funcional ahora. Si usted indicar si desea que la imagen o archivo-selector de

Todos los errores corregidos y post actualizado con el código de trabajo.
El código se ve bien, y va a ser muy útil para mí, no he probado todavía, no estoy tratando de averiguar donde la variable «boolFileChooser»‘s valor se establece? También divisó a un error tipográfico: creo que «MainActivity.CAMERA_REQUEST» debe ser «MainActivity.CAMERAREQUEST_RESULTCODE»
He logrado conseguir mi código de trabajo ahora, muchas gracias por la ayuda. Intentado muchas otras soluciones en la web, pero este era el mejor. Saludos!
¿es posible cargar el código completo? gracias.
user280109 me recuerda que yo también lo he probado (de diferentes fuentes y código tryings) y no puedo recordar por qué puse eso, pero que «funciona» 😀 no puedo publicar el código completo (código específico para la aplicación y el estándar de webview en oncreate), pero puedo añadir el «boolFileChooser» parte.. es la pieza que falta para que funcione, así que debería ser suficiente.. Cuando escribí esto, no era aún implementado. (yo estaba fuera, hasta ahora, lo siento por no contestar antes).

OriginalEl autor Jordi | 2012-11-08

3 Comentarios

  1. 7

    Esta es la forma en que he implementado la cámara de carga y filechooser de WebView campo de entrada:

    Siguiente es el código para este importante tema. La no relevante se ha quitado el código.

    public class MainActivity extends Activity {
    private WebView webView;
    private String urlStart = "http://www.example.com/mobile/";
    //File choser parameters
    private static final int FILECHOOSER_RESULTCODE   = 2888;
    private ValueCallback<Uri> mUploadMessage;
    //Camera parameters
    private Uri mCapturedImageURI = null;
    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    webView = (WebView) findViewById(R.id.webView);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setLoadWithOverviewMode(true);
    webView.getSettings().setAllowFileAccess(true);
    webView.loadUrl(urlStart);
    webView.setWebChromeClient(new WebChromeClient() {
    //openFileChooser for Android 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { 
    mUploadMessage = uploadMsg;
    try{
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File externalDataDir = Environment.getExternalStoragePublicDirectory(
    Environment.DIRECTORY_DCIM);
    File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
    File.separator + "browser-photos");
    cameraDataDir.mkdirs();
    String mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
    System.currentTimeMillis() + ".jpg";
    mCapturedImageURI = Uri.fromFile(new File(mCameraFilePath));
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
    Intent i = new Intent(Intent.ACTION_GET_CONTENT); 
    i.addCategory(Intent.CATEGORY_OPENABLE);
    i.setType("image/*");
    Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[] { cameraIntent });
    startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
    }
    catch(Exception e){
    Toast.makeText(getBaseContext(), "Camera Exception:"+e, Toast.LENGTH_LONG).show();
    }
    }
    //For Android < 3.0
    @SuppressWarnings("unused")
    public void openFileChooser(ValueCallback<Uri> uploadMsg ) {
    openFileChooser(uploadMsg, "");
    }
    //For Android  > 4.1.1
    @SuppressWarnings("unused")
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
    openFileChooser(uploadMsg, acceptType);
    }
    public boolean onConsoleMessage(ConsoleMessage cm) {        
    onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId());
    return true;
    }
    public void onConsoleMessage(String message, int lineNumber, String sourceID) {
    Log.d("androidruntime", "www.example.com: " + message);
    }
    });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    //TODO Auto-generated method stub
    if(requestCode==FILECHOOSER_RESULTCODE)  
    {  
    if (null == this.mUploadMessage) {
    return;
    }
    Uri result=null;
    try{
    if (resultCode != RESULT_OK) {
    result = null;
    } else {
    //retrieve from the private variable if the intent is null
    result = intent == null ? mCapturedImageURI : intent.getData(); 
    } 
    }
    catch(Exception e)
    {
    Toast.makeText(getApplicationContext(), "activity :"+e, Toast.LENGTH_LONG).show();
    }
    mUploadMessage.onReceiveValue(result);
    mUploadMessage = null;
    }
    }

    Espero que sea útil para alguien 🙂

    OriginalEl autor user3459287

  2. 2

    Resuelto. Dentro de mi pregunta, existe el código funcional en caso de que alguien lo necesita.

    Aquí está la solución de los problemas:

    1. No podía abrir la cámara/filechooser si me ha abierto anteriormente y cancelado:

      //inside onActivityResult
      if (resultCode != RESULT_OK) {
      mUploadMessage.onReceiveValue(null);
      return;
      }
    2. Obtener el «content://media/external/images/xxx» formato de uri, para cargar la uri a través de «mUploadMessage.onReceiveValue(selectedImage);», evitando un nullpointerexception

      //inside OnActivityResult
      getContentResolver().notifyChange(mCapturedImageURI, null);
      ContentResolver cr = getContentResolver();
      Uri uriContent = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null));
    Jordi he utilizado ur código y mi ap dejar de estrellarse, pero, por desgracia, la imagen no se puede cargar al servidor.
    porque me sale «uriContent» null.

    OriginalEl autor Jordi

  3. 1

    Resuelto y su trabajo bien.

    Sólo mirar el código de WebChromeClient clase.
    Usted encontrará que se cambian los parámetros de la anterior.

    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
    throw new RuntimeException("Stub!");
    }

    Solución:

    Usted sólo tiene que seguir las últimas ChromeBrowser código en este enlace de github
    Android Chrome, el navegador de código en Github

    Utilizar el mismo código de github para su proyecto.

    Nota: todavía Hay problema con android 4.4 KitKat versión. Excepto android 4.4 su trabajo bien para otras versiones de Android.

    Porque se trata de defecto abierto de Google. Por favor, compruebe en el enlace de abajo.

    openFileChooser no se llama cuando se hace clic en android 4.4 webview

    OriginalEl autor porwalankit

Dejar respuesta

Please enter your comment!
Please enter your name here