android webview 打开相机 相册 图片上传。

权限必须打开 相册,相机 、 文件。

在使用 Android 的 WebView 进行拍照并通过上传功能时,可能会遇到一些问题,特别是涉及到拍照后图片的选取和上传。以下是一些步骤和技巧,可以帮助你解决在 WebView 中拍照无法上传的问题:

  1. 确保权限
    首先,确保你的应用已经请求了必要的权限。在 AndroidManifest.xml 中添加以下权限:
java 复制代码
 <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />
  
uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

并创建一个 res/xml/provider_paths.xml 文件:

java 复制代码
 <?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <root-path
        name="root"
        path="." />
    <files-path
        name="files"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-path
        name="external"
        path="." />
<!--    <external-files-path-->
<!--        name="external_file_path"-->
<!--        path="." />-->
    <external-cache-path
        name="external_cache_path"
        path="." />
    <external-files-path
        name="download"
        path="/Download"
        />
</paths>
java 复制代码
 

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.provider.Settings;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.Toast;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class ZhiHuiWebActivity extends AppCompatActivity {
    WebView web;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zhihui_web);
        Button fanhui_button = findViewById(R.id.fanhui_button);
//        GeckoView
        fanhui_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        web = findViewById(R.id.web);
        WebSettings webSettings = web.getSettings();
        webSettings.setJavaScriptEnabled(true);  // 支持 JS 交互
        webSettings.setDomStorageEnabled(true);  // 允许访问本地存储
        //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
        webSettings.setJavaScriptEnabled(true);

//设置自适应屏幕,两者合用
        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

//缩放操作
        webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

//其他细节操作
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setDefaultTextEncodingName("UTF-8");
        webSettings.setAllowContentAccess(true); // 是否可访问Content Provider的资源,默认值 true
        webSettings.setAllowFileAccess(true);    // 是否可访问本地文件,默认值 true
        // 是否允许通过file url加载的Javascript读取本地文件,默认值 false
        webSettings.setAllowFileAccessFromFileURLs(false);
        // 是否允许通过file url加载的Javascript读取全部资源(包括文件,http,https),默认值 false
        webSettings.setAllowUniversalAccessFromFileURLs(false);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        //开启JavaScript支持
        webSettings.setJavaScriptEnabled(true);
        // 支持缩放
        webSettings.setSupportZoom(true);
        web.setWebChromeClient(new WebChromeClient() {
                                   @Override
                                   public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                                       FileChooserParams fileChooserParams1 = fileChooserParams;
                                       mfilePathCallback = filePathCallback;
                                        takePhoto();
                                       return true;
                                   }
                               }
        );
        web.loadUrl(ZhiHuiTiYu_phoneActivity.school_url);
        web.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 在这里拦截URL,并决定是否在当前WebView中加载
                view.loadUrl(url); // 在WebView内部加载URL
                return true; // 返回true表示此URL已被处理,不再由默认浏览器打开
            }
        });

        if( (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
            ActivityCompat.requestPermissions(ZhiHuiWebActivity.this, new String[]
                    {
                            android.Manifest.permission.CAMERA,
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE
                    }, 1);
        }

    }

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

    /**
     * 调用相机/相册选择窗
     */
    private void takePhoto() {
        String filePath = Environment.getExternalStorageDirectory()
                + 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));
        if(Build.VERSION.SDK_INT>=24){
            imageUri = FileProvider.getUriForFile(ZhiHuiWebActivity.this,getPackageName()+".fileprovider",new File(filePath + fileName));
        }else {
            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, "chooseCame_pic");
        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);
            chooseCame_pic(resultCode, data);
    }

    /**
     * Android API >= 21(Android 5.0) 版本的回调处理
     */
    public void chooseCame_pic(int resultCode, Intent data) {
        Log.e("chooseCame_pic", "调用方法  chooseCame_pic   " + data);
        if (Activity.RESULT_OK == resultCode) {
            //发送广播进行更新相册
                // 该广播即使多发(即选取照片成功时也发送)也没有关系,只是唤醒系统刷新媒体文件
                Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                intent.setData(imageUri);
                sendBroadcast(intent);
            if (data != null) {
                // 这里是针对从文件中选图片的处理
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null) {
                    results = new Uri[]{uriData};
                    for (Uri uri : results) {
                        Log.e("chooseCame_pic", "系统里取到的图片:" + uri.toString());
                    }
                    mfilePathCallback.onReceiveValue(results);
                } else {
                    mfilePathCallback.onReceiveValue(null);
                }
            } else {
                Log.e("chooseCame_pic", "自己命名的图片:" + imageUri.toString());
                mfilePathCallback.onReceiveValue(new Uri[]{imageUri});
            }
        } else {
            mfilePathCallback.onReceiveValue(null);
        }
        mfilePathCallback = null;
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        web.destroy();

    }
}
java 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:background="@color/colorF2F5F7"
        android:paddingTop="5dp"
        android:paddingBottom="5dp">

        <Button
            android:id="@+id/fanhui_button"
              android:textAllCaps="false"
            android:layout_width="70dp"
            android:layout_height="28dp"
            android:layout_marginLeft="20dp"
            android:background="@android:color/transparent" 
            android:paddingLeft="2dp"
            android:paddingRight="17dp"
            android:text="string/return2"
            android:textColor="@color/color9AA6B9" />

    </RelativeLayout>

     <WebView
         android:id="@+id/web"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

     </WebView>

</LinearLayout>
相关推荐
Kapaseker1 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
黄林晴2 小时前
Android17 为什么重写 MessageQueue
android
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android