混合式开发收藏本版 +发表新主题

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

h5中调用摄像头的代码是:
  1. <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 如下
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:paddingBottom="@dimen/activity_vertical_margin"
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"
  7.     android:paddingRight="@dimen/activity_horizontal_margin"
  8.     android:paddingTop="@dimen/activity_vertical_margin"
  9.     tools:context=".MainActivity" >

  10.    <WebView
  11.         android:id="@+id/webView01"
  12.         android:layout_width="match_parent"
  13.         android:layout_height="match_parent"
  14.         android:layout_alignParentLeft="true"
  15.         android:layout_alignParentTop="true"/>

  16. </RelativeLayout>


代码如下
  1. package example.beisun.com.myapplication02;
  2. import android.annotation.SuppressLint;
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.ClipData;
  6. import android.content.ComponentName;
  7. import android.content.ContentUris;
  8. import android.content.Context;
  9. import android.content.Intent;
  10. import android.content.pm.PackageManager;
  11. import android.content.pm.ResolveInfo;
  12. import android.database.Cursor;
  13. import android.graphics.Bitmap;
  14. import android.net.Uri;
  15. import android.os.Build;
  16. import android.os.Bundle;
  17. import android.os.Environment;
  18. import android.os.Parcelable;
  19. import android.provider.DocumentsContract;
  20. import android.provider.MediaStore;
  21. import android.webkit.ValueCallback;
  22. import android.webkit.WebChromeClient;
  23. import android.webkit.WebSettings;
  24. import android.webkit.WebView;
  25. import android.webkit.WebViewClient;

  26. import java.io.File;
  27. import java.util.ArrayList;
  28. import java.util.List;
  29. /**
  30. * 可以选择文件且可以拍照
  31. */
  32. @TargetApi(19)
  33. @SuppressLint("NewApi")
  34. public class MainActivity extends Activity {
  35.     private WebView mWebView;
  36.     private String TMP_URL = "https://www.hl05.com";
  37.     private ValueCallback<Uri> mUploadMessage;// 表单的数据信息
  38.     private ValueCallback<Uri[]> mUploadCallbackAboveL;
  39.     private final static int FILECHOOSER_RESULTCODE = 1;// 表单的结果回调</span>
  40.     private Uri imageUri;
  41.     @Override
  42.     protected void onCreate(Bundle savedInstanceState) {
  43.         super.onCreate(savedInstanceState);
  44.         setContentView(R.layout.activity_main01);
  45.         mWebView=(WebView) findViewById(R.id.webView01);
  46.         mWebView.loadUrl(TMP_URL);
  47.         mWebView.getSettings().setJavaScriptEnabled(true);
  48.         mWebView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
  49.         WebSettings settings = mWebView.getSettings();
  50.         settings.setUseWideViewPort(true);
  51.         settings.setLoadWithOverviewMode(true);
  52.         settings.setJavaScriptEnabled(true);
  53.         settings.setSupportZoom(true);
  54.         mWebView.setWebViewClient(new WebViewClient(){
  55.             @Override
  56.             public boolean shouldOverrideUrlLoading(WebView view, String url) {
  57.                 // TODO Auto-generated method stub
  58.                 return super.shouldOverrideUrlLoading(view, url);
  59.             }

  60.             @Override
  61.             public void onPageStarted(WebView view, String url, Bitmap favicon) {
  62.                 // TODO Auto-generated method stub
  63.                 super.onPageStarted(view, url, favicon);
  64.             }
  65.             @Override
  66.             public void onPageFinished(WebView view, String url) {
  67.                 // TODO Auto-generated method stub
  68.                 super.onPageFinished(view, url);
  69.             }
  70.         });
  71.         mWebView.setWebChromeClient(new WebChromeClient(){

  72.             @Override
  73.             public boolean onShowFileChooser(WebView webView,
  74.                                              ValueCallback<Uri[]> filePathCallback,
  75.                                              FileChooserParams fileChooserParams) {
  76.                 mUploadCallbackAboveL=filePathCallback;
  77.                 take();
  78.                 return true;
  79.             }


  80.             public void openFileChooser(ValueCallback<Uri> uploadMsg) {
  81.                 mUploadMessage=uploadMsg;
  82.                 take();
  83.             }
  84.             public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType) {
  85.                 mUploadMessage=uploadMsg;
  86.                 take();
  87.             }
  88.             public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType, String capture) {
  89.                 mUploadMessage=uploadMsg;
  90.                 take();
  91.             }
  92.         });

  93.     }


  94.     @Override
  95.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  96.         super.onActivityResult(requestCode, resultCode, data);
  97.         if(requestCode==FILECHOOSER_RESULTCODE)
  98.         {
  99.             if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
  100.             Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
  101.             if (mUploadCallbackAboveL != null) {
  102.                 onActivityResultAboveL(requestCode, resultCode, data);
  103.             }
  104.             else  if (mUploadMessage != null) {

  105.                 if (result != null) {
  106.                     String path = getPath(getApplicationContext(),
  107.                             result);
  108.                     Uri uri = Uri.fromFile(new File(path));
  109.                     mUploadMessage
  110.                             .onReceiveValue(uri);
  111.                 } else {
  112.                     mUploadMessage.onReceiveValue(imageUri);
  113.                 }
  114.                 mUploadMessage = null;



  115.             }
  116.         }
  117.     }



  118.     @SuppressWarnings("null")
  119.     @TargetApi(Build.VERSION_CODES.BASE)
  120.     private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
  121.         if (requestCode != FILECHOOSER_RESULTCODE
  122.                 || mUploadCallbackAboveL == null) {
  123.             return;
  124.         }

  125.         Uri[] results = null;

  126.         if (resultCode == Activity.RESULT_OK) {

  127.             if (data == null) {

  128.                 results = new Uri[]{imageUri};
  129.             } else {
  130.                 String dataString = data.getDataString();
  131.                 ClipData clipData = data.getClipData();

  132.                 if (clipData != null) {
  133.                     results = new Uri[clipData.getItemCount()];
  134.                     for (int i = 0; i < clipData.getItemCount(); i++) {
  135.                         ClipData.Item item = clipData.getItemAt(i);
  136.                         results[i] = item.getUri();
  137.                     }
  138.                 }

  139.                 if (dataString != null)
  140.                     results = new Uri[]{Uri.parse(dataString)};
  141.             }
  142.         }
  143.         if(results!=null){
  144.             mUploadCallbackAboveL.onReceiveValue(results);
  145.             mUploadCallbackAboveL = null;
  146.         }else{
  147.             results = new Uri[]{imageUri};
  148.             mUploadCallbackAboveL.onReceiveValue(results);
  149.             mUploadCallbackAboveL = null;
  150.         }

  151.         return;
  152.     }



  153.     private void take(){
  154.         File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");
  155.         // Create the storage directory if it does not exist
  156.         if (! imageStorageDir.exists()){
  157.             imageStorageDir.mkdirs();
  158.         }
  159.         File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
  160.         imageUri = Uri.fromFile(file);

  161.         final List<Intent> cameraIntents = new ArrayList<Intent>();
  162.         final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  163.         final PackageManager packageManager = getPackageManager();
  164.         final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
  165.         for(ResolveInfo res : listCam) {
  166.             final String packageName = res.activityInfo.packageName;
  167.             final Intent i = new Intent(captureIntent);
  168.             i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
  169.             i.setPackage(packageName);
  170.             i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
  171.             cameraIntents.add(i);

  172.         }
  173.         Intent i = new Intent(Intent.ACTION_GET_CONTENT);
  174.         i.addCategory(Intent.CATEGORY_OPENABLE);
  175.         i.setType("image/*");
  176.         Intent chooserIntent = Intent.createChooser(i,"Image Chooser");
  177.         chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
  178.         MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE);
  179.     }

  180.     @SuppressLint("NewApi")
  181.     @TargetApi(Build.VERSION_CODES.KITKAT)
  182.     public static String getPath(final Context context, final Uri uri) {
  183.         final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

  184.         // DocumentProvider
  185.         if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
  186.             // ExternalStorageProvider
  187.             if (isExternalStorageDocument(uri)) {
  188.                 final String docId = DocumentsContract.getDocumentId(uri);
  189.                 final String[] split = docId.split(":");
  190.                 final String type = split[0];

  191.                 if ("primary".equalsIgnoreCase(type)) {
  192.                     return Environment.getExternalStorageDirectory() + "/" + split[1];
  193.                 }

  194.                 // TODO handle non-primary volumes
  195.             }
  196.             // DownloadsProvider
  197.             else if (isDownloadsDocument(uri)) {

  198.                 final String id = DocumentsContract.getDocumentId(uri);
  199.                 final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

  200.                 return getDataColumn(context, contentUri, null, null);
  201.             }
  202.             // MediaProvider
  203.             else if (isMediaDocument(uri)) {
  204.                 final String docId = DocumentsContract.getDocumentId(uri);
  205.                 final String[] split = docId.split(":");
  206.                 final String type = split[0];

  207.                 Uri contentUri = null;
  208.                 if ("image".equals(type)) {
  209.                     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  210.                 } else if ("video".equals(type)) {
  211.                     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
  212.                 } else if ("audio".equals(type)) {
  213.                     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  214.                 }

  215.                 final String selection = "_id=?";
  216.                 final String[] selectionArgs = new String[]{split[1]};

  217.                 return getDataColumn(context, contentUri, selection, selectionArgs);
  218.             }
  219.         }
  220.         // MediaStore (and general)
  221.         else if ("content".equalsIgnoreCase(uri.getScheme())) {
  222.             return getDataColumn(context, uri, null, null);
  223.         }
  224.         // File
  225.         else if ("file".equalsIgnoreCase(uri.getScheme())) {
  226.             return uri.getPath();
  227.         }

  228.         return null;
  229.     }


  230.     /**
  231.      * Get the value of the data column for this Uri. This is useful for
  232.      * MediaStore Uris, and other file-based ContentProviders.
  233.      *
  234.      * @param context       The context.
  235.      * @param uri           The Uri to query.
  236.      * @param selection     (Optional) Filter used in the query.
  237.      * @param selectionArgs (Optional) Selection arguments used in the query.
  238.      * @return The value of the _data column, which is typically a file path.
  239.      */
  240.     public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
  241.         Cursor cursor = null;
  242.         final String column = "_data";
  243.         final String[] projection = {column};

  244.         try {
  245.             cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
  246.             if (cursor != null && cursor.moveToFirst()) {
  247.                 final int column_index = cursor.getColumnIndexOrThrow(column);
  248.                 return cursor.getString(column_index);
  249.             }
  250.         } finally {
  251.             if (cursor != null) cursor.close();
  252.         }
  253.         return null;
  254.     }


  255.     /**
  256.      * @param uri The Uri to check.
  257.      * @return Whether the Uri authority is ExternalStorageProvider.
  258.      */
  259.     public static boolean isExternalStorageDocument(Uri uri) {
  260.         return "com.android.externalstorage.documents".equals(uri.getAuthority());
  261.     }


  262.     /**
  263.      * @param uri The Uri to check.
  264.      * @return Whether the Uri authority is DownloadsProvider.
  265.      */
  266.     public static boolean isDownloadsDocument(Uri uri) {
  267.         return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  268.     }


  269.     /**
  270.      * @param uri The Uri to check.
  271.      * @return Whether the Uri authority is MediaProvider.
  272.      */
  273.     public static boolean isMediaDocument(Uri uri) {
  274.         return "com.android.providers.media.documents".equals(uri.getAuthority());
  275.     }

  276. }

扫描二维码,手机查看
声明:本文来源于互联网,观点仅代表作者本人,不代表欢乐你我,真实性请妥善甄别。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则