WebView控件是经常用到的,如果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
有删改