自定義圖片選擇器
/**
* 拍照或者從相冊獲取圖片
* Created by PersonalFolder on 16/11/10.
*/
public class ImagePick implements View.OnClickListener {
private final int PICK_REQUEST = 0x1001;
private final int TAKE_REQUEST = 0x1002;
private static final String imgDir = Environment.getExternalStorageDirectory() + File.separator + "cloud";
public static String imgFile = imgDir + File.separator + "tmp.jpg";
private Activity activity;
private Dialog dialog;
public interface MyUri {
void getUri(Uri uri);
}
public interface MyDismiss {
void dismiss();
}
private MyDismiss md;
public ImagePick(Activity activity) {
this.activity = activity;
dialog = new Dialog(activity, R.style.DialogStyle);
//dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
View root = LayoutInflater.from(activity).inflate(R.layout.select_img, null);
// 設置點擊監聽
root.findViewById(R.id.take_photo).setOnClickListener(this);
root.findViewById(R.id.album_photo).setOnClickListener(this);
root.findViewById(R.id.cancel).setOnClickListener(this);
dialog.setContentView(root);
}
public void setCancel(MyDismiss md) {
this.md = md;
}
/**
* 顯示Dialog
*/
public void show() {
//這樣先md.dismiss可以保證dialog取消後可以再次打開
if (md != null) {
md.dismiss();
}
dialog.show();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_photo:
takePhoto();
break;
case R.id.album_photo:
getAlbum();
break;
case R.id.cancel:
if (md != null) {
md.dismiss();
}
break;
}
dialog.dismiss();
}
public void dismissImagePick(){
if (md != null) {
md.dismiss();
}
dialog.dismiss();
}
/**
* 拍照
*/
private void takePhoto() {
String sdState = Environment.getExternalStorageState();
// 如果SD卡可讀寫
if (sdState.equals(Environment.MEDIA_MOUNTED)) {
new File(imgDir).mkdirs();
File file = new File(imgFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
activity.startActivityForResult(intent, TAKE_REQUEST);
} else {
Toast.makeText(activity, "請確認已經插入SD卡", Toast.LENGTH_SHORT).show();
}
}
/**
* 從相冊獲取
*/
private void getAlbum() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setType("image/*");
activity.startActivityForResult(intent, PICK_REQUEST);
}
public void onActivityResult(int requestCode, int resultCode, Intent data, MyUri uri) {
if (resultCode != activity.RESULT_OK) {
return;
}
if (requestCode == PICK_REQUEST) {
if (data.getData() != null) {
uri.getUri(data.getData());
}
} else if (requestCode == TAKE_REQUEST) {
if (data != null) {
Uri myUri;
if (data.getData() != null) {
uri.getUri(data.getData());
return;
}
if (data.hasExtra("data")) {
Bitmap bitmap = data.getParcelableExtra("data");
try {
myUri = Uri.parse(MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, null, null));
uri.getUri(myUri);
} catch (Exception e) {
e.printStackTrace();
// 大神手機這行代碼報異常:MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, null, null)
getUri(uri);
}
} else {
// Nexus 6 返回Intent{}得不到數據
getUri(uri);
}
} else {
getUri(uri);
}
}
}
private void getUri(MyUri uri) {
File file = new File(imgFile);
if (file != null && file.exists()) {
uri.getUri(Uri.fromFile(file));
}
}
/**
* 裁剪圖片,並按照給定的長寬輸出
*
* @param activity
* @param uri 拍照或者選擇照片後獲得的URI
* @param outputWidth 輸出的寬度
* @param outputHeight 輸出的高度
* @param requestCode 請求碼
*/
public void cropImg(Activity activity, Uri uri, int outputWidth, int outputHeight, int requestCode) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", outputWidth);
intent.putExtra("aspectY", outputHeight);
intent.putExtra("outputX", outputWidth);
intent.putExtra("outputY", outputHeight);
intent.putExtra("outputFormat", "JPEG");
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
activity.startActivityForResult(intent, requestCode);
}
}
重寫WebView輔助類WebChromeClient,返回數據給H5
private ValueCallback<Uri> mFilePathCallback;
private ValueCallback<Uri[]> mFilePathCallbackArray;
private ImagePick ip;
//...
public class MainWebChromeClient extends WebChromeClient {
// file upload callback (Android 2.2 (API level 8) -- Android 2.3 (API level 10)) (hidden method)
public void openFileChooser(ValueCallback<Uri> filePathCallback) {
handle(filePathCallback);
}
// file upload callback (Android 3.0 (API level 11) -- Android 4.0 (API level 15)) (hidden method)
public void openFileChooser(ValueCallback filePathCallback, String acceptType) {
handle(filePathCallback);
}
// file upload callback (Android 4.1 (API level 16) -- Android 4.3 (API level 18)) (hidden method)
public void openFileChooser(ValueCallback<Uri> filePathCallback, String acceptType, String capture) {
handle(filePathCallback);
}
// for Lollipop
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallbackArray != null) {
mFilePathCallbackArray.onReceiveValue(null);
}
mFilePathCallbackArray = filePathCallback;
showDialog();
return true;
}
/**
* 處理5.0以下系統回調
*
* @param filePathCallback
*/
private void handle(ValueCallback<Uri> filePathCallback) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
showDialog();
}
/**
* 顯示照片選取Dialog
*/
public void showDialog() {
if (ip == null) {
ip = new ImagePick(MainActivity.this);
}
ip.setCancel(new ImagePick.MyDismiss() {
@Override
public void dismiss() {
handleCallback(null);
}
});
ip.show();
}
/**
* 攔截js彈窗
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
if (!message.contains("404") && !message.contains("服務器異常") && !message.contains("網絡無法連接")) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
}
result.confirm();
return true;
}
/**
* Webview加載頁面進度
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) { // 正常照片選取的時候調用
ip.onActivityResult(requestCode, resultCode, data, new ImagePick.MyUri() {
@Override
public void getUri(Uri uri) {
handleCallback(uri);
}
});
} else {
// 取消了照片選取的時候調用
handleCallback(null);
}
}
/**
* 處理WebView的回調
*
* @param uri
*/
private void handleCallback(Uri uri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mFilePathCallbackArray != null) {
if (uri != null) {
mFilePathCallbackArray.onReceiveValue(new Uri[]{uri});
} else {
mFilePathCallbackArray.onReceiveValue(null);
}
mFilePathCallbackArray = null;
}
} else {
if (mFilePathCallback != null) {
if (uri != null) {
mFilePathCallback.onReceiveValue(uri);
} else {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = null;
}
}
}
通過上面兩大步就可以完成WebView其調用ImagePicker來選擇圖片,然後通過將用戶圖片數據返回給網頁。