美文网首页
Android webview支持获取本地图片或拍照

Android webview支持获取本地图片或拍照

作者: 五月笑忘 | 来源:发表于2018-10-16 15:11 被阅读156次

    注意:Android6.0以上需要首先获取摄像头权限,不然无法获取照片

    package com.wshoto.user.anyong.ui.activity;
    
    public class BBSActivity extends InitActivity {
    
        @BindView(R.id.wv_bbs)
        WebView mWvBbs;
        private ValueCallback<Uri> mUploadMessage;// 表单的数据信息
        private ValueCallback<Uri[]> mUploadCallbackAboveL;
        private final static int FILECHOOSER_RESULTCODE = 1;// 表单的结果回调
        private Uri imageUri;
    
        @Override
        public void initView(Bundle savedInstanceState) {
            setContentView(R.layout.activity_bbs);
            ButterKnife.bind(this);
            init();
        }
    
        @Override
        public void initData() {
            mWvBbs.loadUrl("https://xxx");
        }
    
    
        private void init() {
            WebSettings webSettings = mWvBbs.getSettings();
            webSettings.setUseWideViewPort(true);//设置此属性,可任意比例缩放
            webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
    
            webSettings.setUseWideViewPort(true);
            webSettings.setLoadWithOverviewMode(true);
            webSettings.setJavaScriptEnabled(true);
            webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
            String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
            webSettings.setAppCachePath(appCachePath);
            webSettings.setAllowFileAccess(true);
            webSettings.setSupportZoom(true);
            webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
            webSettings.setTextSize(WebSettings.TextSize.NORMAL);
    
            mWvBbs.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
            //open dom storage
            webSettings.setDomStorageEnabled(true);
            //priority high
            webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
            webSettings.setAppCacheEnabled(true);
            webSettings.setDatabaseEnabled(true);
            webSettings.setDatabasePath(BBSActivity.this.getApplicationContext().getCacheDir().getAbsolutePath());
            //add by wjj end
            String ua = webSettings.getUserAgentString();
            mWvBbs.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();
                }
            });
            mWvBbs.setWebViewClient(new WebViewClient() {
    
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    //该方法在Build.VERSION_CODES.LOLLIPOP以前有效,从Build.VERSION_CODES.LOLLIPOP起,建议使用shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead
                    //返回false,意味着请求过程里,不管有多少次的跳转请求(即新的请求地址),均交给webView自己处理,这也是此方法的默认处理
                    //返回true,说明你自己想根据url,做新的跳转,比如在判断url符合条件的情况下,我想让webView加载http://ask.csdn.net/questions/178242
                    return false;
                }
    
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                    //返回false,意味着请求过程里,不管有多少次的跳转请求(即新的请求地址),均交给webView自己处理,这也是此方法的默认处理
                    //返回true,说明你自己想根据url,做新的跳转,比如在判断url符合条件的情况下,我想让webView加载https://maydaychen.github.io/
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        if (request.getUrl().toString().contains("github.io")) {
                            view.loadUrl("https://maydaychen.github.io/");
                            return true;
                        }
                    }
    
                    return false;
                }
    
            });
        }
    
        @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[]{}));
            BBSActivity.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];
                    }
                }
                // 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支持获取本地图片或拍照

          本文链接:https://www.haomeiwen.com/subject/dzjhzftx.html