ebView控件是经常用到的,如果WebView中有选择图片这种操作,光是settings.setJavaScriptEnabled(true); 还是不够的,还需要重写WebChromeClient 和 WebViewClient
初始化操作
mWebView.setWebChromeClient(new MyWebChromeClient()); mWebView.setWebViewClient(new MyWebViewClient());
代码
private class MyWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { LogUtil.i("URL地址:" + url); super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { LogUtil.i("onPageFinished"); super.onPageFinished(view, url); } } private ValueCallback<Uri> mUploadMessage; public static final int FILECHOOSER_RESULTCODE = 1; private static final int REQ_CAMERA = FILECHOOSER_RESULTCODE + 1; private static final int REQ_CHOOSE = REQ_CAMERA + 1; private class MyWebChromeClient extends WebChromeClient { // For Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { if (mUploadMessage != null) return; mUploadMessage = uploadMsg; selectImage(); } // For Android < 3.0 public void openFileChooser(ValueCallback<Uri> uploadMsg) { openFileChooser(uploadMsg, ""); } // For Android > 4.1.1 public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { openFileChooser(uploadMsg, acceptType); } } /** * 检查SD卡是否存在 * * @return */ public final boolean checkSDcard() { boolean flag = Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); if (!flag) { Toast.makeText(this, "请插入手机存储卡再使用本功能", Toast.LENGTH_SHORT).show(); } return flag; } private String compressPath = ""; protected final void selectImage() { if (!checkSDcard()) return; String[] selectPicTypeStr = {"相机", "图库"}; new AlertDialog.Builder(this) .setItems(selectPicTypeStr, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { // 相机拍摄 case 0: openCamera(); break; // 手机相册 case 1: chosePic(); break; default: break; } compressPath = Environment.getExternalStorageDirectory().getPath() + "/fuiou_wmp/temp"; new File(compressPath).mkdirs(); compressPath = compressPath + File.separator + "compress.jpg"; } }).setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { mUploadMessage.onReceiveValue(null); mUploadMessage = null; } }).show(); } private String imagePaths; private Uri cameraUri; /** * 打开照相机 */ private void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); imagePaths = Environment.getExternalStorageDirectory().getPath() + "/fuiou_wmp/temp/" + (System.currentTimeMillis() + ".jpg"); // 必须确保文件夹路径存在,否则拍照后无法完成回调 File vFile = new File(imagePaths); if (!vFile.exists()) { File vDirPath = vFile.getParentFile(); vDirPath.mkdirs(); } else { if (vFile.exists()) { vFile.delete(); } } cameraUri = Uri.fromFile(vFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri); startActivityForResult(intent, REQ_CAMERA); } /** * 拍照结束后 */ private void afterOpenCamera() { File f = new File(imagePaths); addImageGallery(f); File newFile = FileUtil.compressFile(f.getPath(), compressPath); } /** * 解决拍照后在相册中找不到的问题 */ private void addImageGallery(File file) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath()); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } /** * 本地相册选择图片 */ private void chosePic() { FileUtil.delFile(compressPath); Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT" String IMAGE_UNSPECIFIED = "image/*"; innerIntent.setType(IMAGE_UNSPECIFIED); // 查看类型 Intent wrapperIntent = Intent.createChooser(innerIntent, null); startActivityForResult(wrapperIntent, REQ_CHOOSE); } /** * 选择照片后结束 * * @param data */ private Uri afterChosePic(Intent data) { Cursor cursor; // 获取图片的路径: String[] proj = {MediaStore.Images.Media.DATA}; if (null!=data){ // 好像是android多媒体数据库的封装接口,具体的看Android文档 cursor = managedQuery(data.getData(), proj, null, null, null); }else return null; if (null == cursor) { Toast.makeText(this, "上传的图片仅支持png或jpg格式", Toast.LENGTH_SHORT).show(); return null; } // 按我个人理解 这个是获得用户选择的图片的索引值 int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); // 将光标移至开头 ,这个很重要,不小心很容易引起越界 cursor.moveToFirst(); // 最后根据索引值获取图片路径 String path = cursor.getString(column_index); if (path != null && (path.endsWith(".png") || path.endsWith(".PNG") || path.endsWith(".jpg") || path.endsWith(".JPG") || path.endsWith(".jpeg") || path.endsWith(".JPEG"))) { File newFile = FileUtil.compressFile(path, compressPath); return Uri.fromFile(newFile); } else { Toast.makeText(this, "上传的图片仅支持png或jpg格式", Toast.LENGTH_SHORT).show(); } return null; } /** * 返回文件选择 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (null == mUploadMessage) return; Uri uri = null; if (requestCode == REQ_CAMERA) { afterOpenCamera(); uri = cameraUri; } else if (requestCode == REQ_CHOOSE) { uri = afterChosePic(intent); } mUploadMessage.onReceiveValue(uri); mUploadMessage = null; super.onActivityResult(requestCode, resultCode, intent); } public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && wbUpdate.canGoBack()) { wbUpdate.goBack(); return true; } else { finish(); } return super.onKeyDown(keyCode, event); }
用到的FileUtil
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.ExifInterface; import android.text.TextUtils; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import static com.luck.picture.lib.tools.PictureFileUtils.rotaingImageView; public class FileUtil { /** * 把图片压缩到200K * * @param oldpath 压缩前的图片路径 * @param newPath 压缩后的图片路径 * @return */ public static File compressFile(String oldpath, String newPath) { Bitmap compressBitmap = decodeFile(oldpath); Bitmap newBitmap = ratingImage(oldpath, compressBitmap); ByteArrayOutputStream os = new ByteArrayOutputStream(); newBitmap.compress(Bitmap.CompressFormat.PNG, 100, os); byte[] bytes = os.toByteArray(); File file = null; try { file = getFileFromBytes(bytes, newPath); } catch (Exception e) { e.printStackTrace(); } finally { if (newBitmap != null) { if (!newBitmap.isRecycled()) { newBitmap.recycle(); } newBitmap = null; } if (compressBitmap != null) { if (!compressBitmap.isRecycled()) { compressBitmap.recycle(); } compressBitmap = null; } } return file; } private static Bitmap ratingImage(String filePath, Bitmap bitmap) { int degree = readPictureDegree(filePath); return rotaingImageView(degree, bitmap); } /** * 读取图片属性:旋转的角度 * * @param path 图片绝对路径 * @return degree旋转的角度 */ public static int readPictureDegree(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } /** * 把字节数组保存为一个文件 * * @param b * @param outputFile * @return */ public static File getFileFromBytes(byte[] b, String outputFile) { File ret = null; BufferedOutputStream stream = null; try { ret = new File(outputFile); FileOutputStream fstream = new FileOutputStream(ret); stream = new BufferedOutputStream(fstream); stream.write(b); } catch (Exception e) { // log.error("helper:get file from byte process error!"); e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // log.error("helper:get file from byte process error!"); e.printStackTrace(); } } } return ret; } /** * 图片压缩 * * @param fPath * @return */ public static Bitmap decodeFile(String fPath) { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; opts.inDither = false; // Disable Dithering mode opts.inPurgeable = true; // Tell to gc that whether it needs free opts.inInputShareable = true; // Which kind of reference will be used to BitmapFactory.decodeFile(fPath, opts); final int REQUIRED_SIZE = 200; int scale = 1; if (opts.outHeight > REQUIRED_SIZE || opts.outWidth > REQUIRED_SIZE) { final int heightRatio = Math.round((float) opts.outHeight / (float) REQUIRED_SIZE); final int widthRatio = Math.round((float) opts.outWidth / (float) REQUIRED_SIZE); scale = heightRatio < widthRatio ? heightRatio : widthRatio; } opts.inJustDecodeBounds = false; opts.inSampleSize = scale; Bitmap bm = BitmapFactory.decodeFile(fPath, opts).copy(Bitmap.Config.ARGB_8888, false); return bm; } /** * 删除该目录下的文件 * * @param path */ public static void delFile(String path) { if (!TextUtils.isEmpty(path)) { File file = new File(path); if (file.exists()) { file.delete(); } } } }
主要代码来自:http://blog.csdn.net/woshinia/article/details/19030437
有删改