• 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 == 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 == 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());
        }
    
    }
  • 相关阅读:
    图解AVL树
    浅析Java7中的ConcurrentHashMap
    浅析CopyOnWriteArrayList
    浅析CAS与AtomicInteger原子类
    IDEA左侧不以树形结构展示项目结构
    maven常见问题
    Mybatis实现多表联合查询
    Mybatis实现单表增删改查操作
    解决mybaits配置错误:Cause: org.xml.sax.SAXParseException; lineNumber: 17; columnNumber: 119; 对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾。
    Deepin_运维实践系列博客导航
  • 原文地址:https://www.cnblogs.com/nmdzwps/p/5841509.html
Copyright © 2020-2023  润新知