首页 > 代码库 > android 之 webView 显示h5 执行选择图片或者拍照功能

android 之 webView 显示h5 执行选择图片或者拍照功能

开发工具是 android studio SDK版本是 4.3
实现过程基本是这样
h5中调用手机选择文件图片的代码是:

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

然后给webView 设置WebChromeClient WebChromeClient 主要处理解析,渲染网页等浏览器做的事情
设置完毕后 重写WebChromeClient 的openFileChooser方法即可实现h5调用手选择文体了。

h5中调用摄像头的代码是:
<input accept="image/*" capture="camera" id="imgFile" name="imgFile" type="file">

用安卓的 webView 控件来显示h5网页
然后给webView 设置WebChromeClient WebChromeClient 主要处理解析,渲染网页等浏览器做的事情
设置完毕后 重写WebChromeClient 的openFileChooser方法即可实现h5调用手机摄像头了。


但是这个方法的使用却不简单,这个方法是要调用webview的setWebChromeClient方法,然后重写一个WebChromeClient类。来到这一步,相信有点开发经验的同行都不难解决。问题的关键就在于,当你重写WebChromeClient这个类的时候会发现,根本就没有openFileChooser这个方法,那要怎么重写呢?是不是意味着这个方法其实行不通?于是再次翻查资料,发现原来这个方法居然是隐藏方法,并不不存在显性的继承重写关系。
最后,我发现要使用这个方法,还得自己继承WebChromeClient这个类把openFileChooser(ValueCallback<Uri> uploadFile)这个方法给写出来,代码如下:

 
activity_main01.xml 如下
 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >   <WebView        android:id="@+id/webView01"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"/></RelativeLayout>

 

代码如下

 

package example.beisun.com.myapplication02;import android.annotation.SuppressLint;import android.annotation.TargetApi;import android.app.Activity;import android.content.ClipData;import android.content.ComponentName;import android.content.ContentUris;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.database.Cursor;import android.graphics.Bitmap;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.os.Environment;import android.os.Parcelable;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import java.io.File;import java.util.ArrayList;import java.util.List;/** * 可以选择文件且可以拍照 */@TargetApi(19)@SuppressLint("NewApi")public class MainActivity extends Activity {    private WebView mWebView;    //private String TMP_URL = "http://laodongjianguan.chanlytech.com:8088/laodongjianguan/index.php/daohang/daohang/f";    private String TMP_URL = "http://cl.beisun.com/mbp/androdTest/index.html";    //private String TMP_URL = "http://192.168.1.130:8080/cims-viewcapture/afrH5/toAuthDesc.do";    private ValueCallback<Uri> mUploadMessage;// 表单的数据信息    private ValueCallback<Uri[]> mUploadCallbackAboveL;    private final static int FILECHOOSER_RESULTCODE = 1;// 表单的结果回调</span>    private Uri imageUri;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main01);        mWebView=(WebView) findViewById(R.id.webView01);        mWebView.loadUrl(TMP_URL);        mWebView.getSettings().setJavaScriptEnabled(true);        mWebView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);        WebSettings settings = mWebView.getSettings();        settings.setUseWideViewPort(true);        settings.setLoadWithOverviewMode(true);        settings.setJavaScriptEnabled(true);        settings.setSupportZoom(true);        mWebView.setWebViewClient(new WebViewClient(){            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                // TODO Auto-generated method stub                return super.shouldOverrideUrlLoading(view, url);            }            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                // TODO Auto-generated method stub                super.onPageStarted(view, url, favicon);            }            @Override            public void onPageFinished(WebView view, String url) {                // TODO Auto-generated method stub                super.onPageFinished(view, url);            }        });        mWebView.setWebChromeClient(new WebChromeClient(){            @Override            public boolean onShowFileChooser(WebView webView,                                             ValueCallback<Uri[]> filePathCallback,                                             FileChooserParams fileChooserParams) {                mUploadCallbackAboveL=filePathCallback;                take();                return true;            }            public void openFileChooser(ValueCallback<Uri> uploadMsg) {                mUploadMessage=uploadMsg;                take();            }            public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType) {                mUploadMessage=uploadMsg;                take();            }            public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType, String capture) {                mUploadMessage=uploadMsg;                take();            }        });    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode==FILECHOOSER_RESULTCODE)        {            if (null == mUploadMessage && null == mUploadCallbackAboveL) return;            Uri result = data =http://www.mamicode.com/= null || resultCode != RESULT_OK ? null : data.getData();            if (mUploadCallbackAboveL != null) {                onActivityResultAboveL(requestCode, resultCode, data);            }            else  if (mUploadMessage != null) {                if (result != null) {                    String path = getPath(getApplicationContext(),                            result);                    Uri uri = Uri.fromFile(new File(path));                    mUploadMessage                            .onReceiveValue(uri);                } else {                    mUploadMessage.onReceiveValue(imageUri);                }                mUploadMessage = null;            }        }    }    @SuppressWarnings("null")    @TargetApi(Build.VERSION_CODES.BASE)    private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {        if (requestCode != FILECHOOSER_RESULTCODE                || mUploadCallbackAboveL == null) {            return;        }        Uri[] results = null;        if (resultCode == Activity.RESULT_OK) {            if (data =http://www.mamicode.com/= null) {                results = new Uri[]{imageUri};            } else {                String dataString = data.getDataString();                ClipData clipData = data.getClipData();                if (clipData != null) {                    results = new Uri[clipData.getItemCount()];                    for (int i = 0; i < clipData.getItemCount(); i++) {                        ClipData.Item item = clipData.getItemAt(i);                        results[i] = item.getUri();                    }                }                if (dataString != null)                    results = new Uri[]{Uri.parse(dataString)};            }        }        if(results!=null){            mUploadCallbackAboveL.onReceiveValue(results);            mUploadCallbackAboveL = null;        }else{            results = new Uri[]{imageUri};            mUploadCallbackAboveL.onReceiveValue(results);            mUploadCallbackAboveL = null;        }        return;    }    private void take(){        File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");        // Create the storage directory if it does not exist        if (! imageStorageDir.exists()){            imageStorageDir.mkdirs();        }        File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");        imageUri = Uri.fromFile(file);        final List<Intent> cameraIntents = new ArrayList<Intent>();        final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        final PackageManager packageManager = getPackageManager();        final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);        for(ResolveInfo res : listCam) {            final String packageName = res.activityInfo.packageName;            final Intent i = new Intent(captureIntent);            i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));            i.setPackage(packageName);            i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);            cameraIntents.add(i);        }        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, cameraIntents.toArray(new Parcelable[]{}));        MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE);    }    @SuppressLint("NewApi")    @TargetApi(Build.VERSION_CODES.KITKAT)    public static String getPath(final Context context, final Uri uri) {        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;        // DocumentProvider        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {            // ExternalStorageProvider            if (isExternalStorageDocument(uri)) {                final String docId = DocumentsContract.getDocumentId(uri);                final String[] split = docId.split(":");                final String type = split[0];                if ("primary".equalsIgnoreCase(type)) {                    return Environment.getExternalStorageDirectory() + "/" + split[1];                }                // TODO handle non-primary volumes            }            // DownloadsProvider            else if (isDownloadsDocument(uri)) {                final String id = DocumentsContract.getDocumentId(uri);                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));                return getDataColumn(context, contentUri, null, null);            }            // MediaProvider            else if (isMediaDocument(uri)) {                final String docId = DocumentsContract.getDocumentId(uri);                final String[] split = docId.split(":");                final String type = split[0];                Uri contentUri = null;                if ("image".equals(type)) {                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                } else if ("video".equals(type)) {                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;                } else if ("audio".equals(type)) {                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;                }                final String selection = "_id=?";                final String[] selectionArgs = new String[]{split[1]};                return getDataColumn(context, contentUri, selection, selectionArgs);            }        }        // MediaStore (and general)        else if ("content".equalsIgnoreCase(uri.getScheme())) {            return getDataColumn(context, uri, null, null);        }        // File        else if ("file".equalsIgnoreCase(uri.getScheme())) {            return uri.getPath();        }        return null;    }    /**     * Get the value of the data column for this Uri. This is useful for     * MediaStore Uris, and other file-based ContentProviders.     *     * @param context       The context.     * @param uri           The Uri to query.     * @param selection     (Optional) Filter used in the query.     * @param selectionArgs (Optional) Selection arguments used in the query.     * @return The value of the _data column, which is typically a file path.     */    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {        Cursor cursor = null;        final String column = "_data";        final String[] projection = {column};        try {            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);            if (cursor != null && cursor.moveToFirst()) {                final int column_index = cursor.getColumnIndexOrThrow(column);                return cursor.getString(column_index);            }        } finally {            if (cursor != null) cursor.close();        }        return null;    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is ExternalStorageProvider.     */    public static boolean isExternalStorageDocument(Uri uri) {        return "com.android.externalstorage.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is DownloadsProvider.     */    public static boolean isDownloadsDocument(Uri uri) {        return "com.android.providers.downloads.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is MediaProvider.     */    public static boolean isMediaDocument(Uri uri) {        return "com.android.providers.media.documents".equals(uri.getAuthority());    }}

 

android 之 webView 显示h5 执行选择图片或者拍照功能