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>
相关推荐
游戏开发爱好者82 小时前
抓包工具有哪些?代理抓包、数据流抓包、拦截转发工具
android·ios·小程序·https·uni-app·iphone·webview
StarShip2 小时前
Android system_server进程介绍
android
StarShip2 小时前
Android Context 的 “上下文”
android
成都大菠萝2 小时前
2-6-1 快速掌握Kotlin-语言的接口定义
android
李小轰_Rex3 小时前
纯算法AEC:播录并行场景的回声消除实战笔记
android·音视频开发
ok406lhq3 小时前
unity游戏调用SDK支付返回游戏会出现画面移位的问题
android·游戏·unity·游戏引擎·sdk
成都大菠萝5 小时前
2-2-2 快速掌握Kotlin-函数&Lambda
android
成都大菠萝5 小时前
2-1-1 快速掌握Kotlin-kotlin中变量&语句&表达式
android
CC.GG5 小时前
【C++】STL----封装红黑树实现map和set
android·java·c++