Android WebView (H5) appelle l'appareil photo natif et l'album photo

Avant de commencer à décrire le texte, l'auteur déclare d'abord le scénario d'application : par exemple, la messagerie instantanée sur le Web doit pouvoir prendre des photos ou sélectionner des images de la galerie à télécharger. Dans ce scénario, le contenu de cet article peut être utilisé

Tout d' abord
, si vous avez ajouté les autorisations de la caméra et du dossier d'accès et que les opérations de base de WebView sont terminées, et que vous êtes à court de téléchargement d'images, reportez-vous au code suivant. Si vous réécrivez setWebChormeClient(){} Le méthode onShowFileChooser(){}

   private ValueCallback<Uri> mUploadMessage; 
   private ValueCallback<Uri[]> mUploadCallbackAboveL;
   private Uri imageUri; //图片地址

   mWv.setWebChromeClient(new WebChromeClient() {
    
    
            //相机  相册
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
    
    
                mUploadCallbackAboveL = filePathCallback;
                takePhoto();
                return true;
            }
        });

	/**
     * 调用相机/相册选择窗
     */
    private void takePhoto() {
    
    
        String filePath = Environment.getExternalStorageDirectory() +File.separator;
//                + File.separator
//                + Environment.DIRECTORY_PICTURES + File.separator;
        String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
        imageUri = Uri.fromFile(new File(filePath + fileName));
        //相册相机选择窗
        Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        Intent Photo = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        Intent chooserIntent = Intent.createChooser(Photo, "选择上传方式");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{
    
    captureIntent});
        startActivityForResult(chooserIntent, 1);
    }

 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    
    
        super.onActivityResult(requestCode, resultCode, data);
        if (Build.VERSION.SDK_INT >= 21) {
    
    
            chooseAbove(resultCode, data);
        } else {
    
    
            chooseBelow(resultCode, data);
        }
    }

  	/**
     * Android API < 21(Android 5.0)版本的回调处理
     */
    public void chooseBelow(int resultCode, Intent data) {
    
    
        Log.e("Base", "调用方法  chooseBelow");
        if (Activity.RESULT_OK == resultCode) {
    
    
            updatePhotos();

            if (data != null) {
    
    
                // 这里是针对文件路径处理
                Uri uri = data.getData();
                if (uri != null) {
    
    
                    Log.e("Base", "系统里取到的图片:" + uri.toString());
                    mUploadMessage.onReceiveValue(uri);
                } else {
    
    
                    mUploadMessage.onReceiveValue(null);
                }
            } else {
    
    
                // 以指定图像存储路径的方式调起相机,成功后返回data为空
                Log.e("Base", "自己命名的图片:" + imageUri.toString());
                mUploadMessage.onReceiveValue(imageUri);
            }
        } else {
    
    
            mUploadMessage.onReceiveValue(null);
        }
        mUploadMessage = null;
    }

    /**
     * Android API >= 21(Android 5.0) 版本的回调处理
     */
    public void chooseAbove(int resultCode, Intent data) {
    
    
        Log.e("Base", "调用方法  chooseAbove   " +data);

        if (Activity.RESULT_OK == resultCode) {
    
    
            updatePhotos();

            if (data != null) {
    
    
                // 这里是针对从文件中选图片的处理
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null) {
    
    
                    results = new Uri[]{
    
    uriData};
                    for (Uri uri : results) {
    
    
                        Log.e("Base", "系统里取到的图片:" + uri.toString());
                    }
                    mUploadCallbackAboveL.onReceiveValue(results);
                } else {
    
    
                    mUploadCallbackAboveL.onReceiveValue(null);
                }
            } else {
    
    
                Log.e("Base", "自己命名的图片:" + imageUri.toString());
                mUploadCallbackAboveL.onReceiveValue(new Uri[]{
    
    imageUri});
            }
        } else {
    
    
            mUploadCallbackAboveL.onReceiveValue(null);
        }
        mUploadCallbackAboveL = null;
    }

    //发送广播进行更新相册
    private void updatePhotos() {
    
    
        // 该广播即使多发(即选取照片成功时也发送)也没有关系,只是唤醒系统刷新媒体文件
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(imageUri);
        sendBroadcast(intent);
    }

Ce qui précède est essentiellement tout le contenu de l'appel de l'appareil photo ou de l'ouverture de l'album photo sur la page Web, mais il y a encore quelques points à noter. Le
premier point : si vous sélectionnez l'appareil photo ou l'album photo dans la fenêtre contextuelle qui a surgi, une erreur sera signalée et provoquera un crash , alors vous devez ajouter le code suivant à la méthode onCreate() de l'activité

//为了避免点击相册或者相机的按钮时报错
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());

Le deuxième point : parce que le chemin où la photo est stockée après avoir pris la photo dans le code est

storage/emulated/0/图片名.jpg

Vous devez donc juger si vous avez l'autorisation d'accéder au dossier. Si vous n'avez pas l'autorisation, les photos que vous avez prises ne peuvent pas être envoyées au frontal, donc après avoir pris les photos et cliqué sur la coche sur l'image , vous constaterez qu'il n'y a pas de réponse. Cela est dû au fait que vous ne pouvez pas obtenir l'image car il n'y a pas d'autorisation. Vous pouvez également trouver le fichier dans l'explorateur de fichiers de l'appareil sur Android Studio pour voir s'il peut être ouvert. S'il s'affiche, cela insérez la description de l'image ici
prouve qu'il n'y a pas d'autorisation pour le moment. Vous pouvez obtenir l'autorisation ou utiliser une autre méthode simple, qui est sous le projet Changez la valeur de targetSdk à 23 ou moins de 23 (l'auteur utilise 23) dans le build.gradle (la valeur de targetSdk ou l'autorisation dépend de la situation de votre propre projet), ce qui précède est tout le contenu, s'il y a des

Guess you like

Origin blog.csdn.net/m0_46366678/article/details/128861985