web-dev-qa-db-fra.com

Choisissez l'appareil photo dans le téléchargement de fichiers dans l'application Cordova sur Android sans utiliser l'appareil photo Cordova

J'ai donc créé une application Cordova, ajouté une plate-forme Android et créé un code HTML simple avec un champ d'entrée

<input type="file" capture="camera" accept="image/*" id="takePictureField">

J'ai ajouté 

<uses-permission Android:name="Android.permission.CAMERA" />
<uses-feature Android:name="Android.hardware.camera" Android:required="false" />
<uses-feature Android:name="Android.hardware.camera.autofocus" />
<feature name="http://api.phonegap.com/1.0/camera" />

au fichier manifeste.

mais lorsque j'appuie sur le bouton, je ne peux pas choisir de prendre une nouvelle photo avec l'appareil photo. y a-t-il une permission qui me manque ou autre chose ??

Je ne peux pas utiliser les fonctions de prise de photo de Cordova, cela doit être fait en HTML pur.

24
pjensen68321

Après un peu de recherche sur Google, voici ce que je pourrais conclure:

La capture de média dans les navigateurs mobiles semble toujours poser quelques problèmes. Découvrez ce link . L'extrait dit:

En fait, il semble que les implémentations actuelles ne reposent pas du tout sur l’attribut capture, mais seulement sur les attributs type et accept: le navigateur affiche une boîte de dialogue dans laquelle l’utilisateur peut choisir où le fichier doit être pris et la capture. Cet attribut n'est pas pris en compte. Par exemple, iOS Safari s'appuie sur l'attribut accept (non capturé) pour les images et les vidéos (non audio). Même si vous n'utilisez pas l'attribut accept, le navigateur vous laissera choisir entre «Prendre une photo ou une vidéo» et «Choisir existant». 

On dirait donc que l'attribut capture n'a aucun impact.

Aussi, suggérez que vous regardiez ceci SO post pour plus d’informations sur la façon de faire ce travail. J'espère que ça aide. À votre santé.

MISE À JOUR: Après le vote, je creuse plus profondément sur le problème. La plupart des recherches ont été infructueuses, car la solution optimale pour ce problème consiste à utiliser le plug-in de caméra Cordova. Enfin tombé sur ce SO post qui est exactement le double de cette question. L’utilisateur a pu résoudre le problème (à l’aide de la vue Web des passages pour piétons). La réponse dans cet article est déjà mentionnée ici par @Fabio. Mais au lieu d’ajouter le plug-in uniquement pour inclure les autorisations, vous pouvez utiliser cordova-custom-plugin pour ajouter les autorisations requises. 

Toujours selon le commentaire de @ jcesarmobile (qui est un expert de Cordova) dans le post sans plug-in de vue Web de passage pour piétons, le type de saisie ne fonctionne correctement que sur iOS et non sur Android. Donc, utiliser le plugin de caméra est la seule façon de le faire fonctionner sans utiliser de plug-in de passage pour piétons. Heureusement, cela aide.

MISE À JOUR 2: Après la question mise à jour, j'ai creusé un peu plus profond pour la résolution de ce problème. Mais maintenant, je peux assurer que ce problème n’est toujours pas résolu pour Android Webview. On dirait que ce n'est pas un problème Cordova mais un problème avec la vue Web Chromium. 

Pour des informations détaillées, veuillez vous reporter à ces problèmes dans Apache Cordova Issue Tracker:

Ces deux problèmes sont non résolus jusqu'à la date. Donc, je suis sûr que pour le moment, vous ne pouvez pas le faire fonctionner sur Android à moins d’utiliser le plug-in de l’appareil photo Cordova. J'espère que vous êtes d'accord avec moi et acceptez la résolution. À votre santé

10
Gandhi

Clause de non-responsabilité: les commentaires récents à propos de cette réponse indiquent que cela ne fonctionne plus. Cette question et les réponses concernent les anciennes versions des plugins Cordova et Et peuvent donc ne pas être applicables à votre situation actuelle de .

Une vieille question, mais je viens de faire face à ce problème. Il s’avère que le moyen le plus simple de réaliser ce que vous voulez est d’inclure ces plugins Cordova dans votre application, même si vous n’avez pas besoin de les utiliser

cordova-plugin-camera
cordova-plugin-media-capture
cordova-plugin-device
cordova-plugin-file
cordova-plugin-media

Avec ces chargé j'ai trouvé ce comportement

En cliquant sur 

<input type="file" />

Vous demander de choisir entre caméra, caméscope, microphone ou documents

En cliquant sur 

<input type="file" accept="image/*" />

Vous demander de choisir entre appareil photo ou documents

En cliquant sur

<input type="file" accept="image/*" capture="capture" />

Démarrez immédiatement la caméra.

0
Fabio C.

Mon projet utilisait cordova-plugin-inappbrowser. 

Je résous la solution de fusion dans webview caméra ouverte depuis le champ de saisie sans filechooser avec les méthodes onActivityResult et onShowFileChooser de la classe InAppBrowser dans le source du plugin.

Voir les modifications apportées à la classe InAppBrowser à partir du plugin version 3.0.0

1 - inclure les importations:

import Android.app.Activity;
import Android.os.Environment;
import Android.provider.MediaStore;
import Android.util.Log;
import Java.io.File;
import Java.io.IOException;
import Java.text.SimpleDateFormat;
import Java.util.Date;

2 - déclarer variavel;

    private String mCM;

3 - Remplacer le code onShowFileChooser


                    // For Android 5.0+
                    public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
                    {
                        LOG.d(LOG_TAG, "File Chooser 5.0+");

                        // If callback exists, finish it.
                        if(mUploadCallbackLollipop != null) {
                            mUploadCallbackLollipop.onReceiveValue(null);
                        }
                        mUploadCallbackLollipop = filePathCallback;

                        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                        if(takePictureIntent.resolveActivity(cordova.getActivity().getPackageManager()) != null) {

                            File photoFile = null;
                            try{
                                photoFile = createImageFile();
                                takePictureIntent.putExtra("PhotoPath", mCM);
                            }catch(IOException ex){
                                Log.e(LOG_TAG, "Image file creation failed", ex);
                            }
                            if(photoFile != null){
                                mCM = "file:" + photoFile.getAbsolutePath();
                                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                            }else{
                                takePictureIntent = null;
                            }
                        }
                        // Create File Chooser Intent
                        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                        contentSelectionIntent.setType("*/*");
                        Intent[] intentArray;
                        if(takePictureIntent != null){
                            intentArray = new Intent[]{takePictureIntent};
                        }else{
                            intentArray = new Intent[0];
                        }

                        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Selecione a imagem");
                        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

                        // Run cordova startActivityForResult
                        cordova.startActivityForResult(InAppBrowser.this, chooserIntent, FILECHOOSER_REQUESTCODE);

                        return true;
                    }

4 - Méthode create


    private File createImageFile() throws IOException{
        @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "img_"+timeStamp+"_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        return File.createTempFile(imageFileName,".jpg",storageDir);
    }

5 - Remplacez onActivityResult


    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        // For Android >= 5.0
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {

            LOG.d(LOG_TAG, "onActivityResult (For Android >= 5.0)");

            Uri[] results = null;
            //Check if response is positive
            if(resultCode== Activity.RESULT_OK){
                if(requestCode == FILECHOOSER_REQUESTCODE){
                    if(null == mUploadCallbackLollipop){
                        return;
                    }
                    if(intent == null || intent.getData() == null){
                        //Capture Photo if no image available
                        if(mCM != null){
                            results = new Uri[]{Uri.parse(mCM)};
                        }
                    }else{
                        String dataString = intent.getDataString();
                        if(dataString != null){
                            results = new Uri[]{Uri.parse(dataString)};
                        }
                    }
                }
            }
            mUploadCallbackLollipop .onReceiveValue(results);
            mUploadCallbackLollipop = null;
        }
        // For Android < 5.0
        else {
            LOG.d(LOG_TAG, "onActivityResult (For Android < 5.0)");
            // If RequestCode or Callback is Invalid
            if(requestCode != FILECHOOSER_REQUESTCODE || mUploadCallback == null) {
                super.onActivityResult(requestCode, resultCode, intent);
                return;
            }

            if (null == mUploadCallback) return;
            Uri result = intent == null || resultCode != cordova.getActivity().RESULT_OK ? null : intent.getData();

            mUploadCallback.onReceiveValue(result);
            mUploadCallback = null;
        }
    }

0
Gilberto Alexandre