適配h5中 < input file>調起相機和相冊的功能代碼:
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
private String mCurrentPhotoPath;
private String mLastPhothPath;
private Thread mThread;
.......
public class MyWebChromeClient extends WebChromeClient
{
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
{
Log.i(TAG, "onJsAlert: " + message);
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
{
Log.i(TAG, "onJsConfirm: " + message);
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
{
Log.i(TAG, "onJsPrompt: " + message);
return super.onJsPrompt(view, url, message, defaultValue, result);
}
@Override
public void onReceivedTitle(WebView view, String title)
{
super.onReceivedTitle(view, title);
}
@Override
public void onProgressChanged(WebView view, int newProgress)
{
if (newProgress == 100)
{
progressBar.setVisibility(View.GONE);
}
else
{
if (progressBar.getVisibility() == View.GONE)
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
//For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
{
uploadMessageAboveL = filePathCallback;
uploadPicture();
return true;
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture)
{
uploadMessage = valueCallback;
uploadPicture();
}
}
Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
takePhoto();
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == REQUEST_CODE_ALBUM || requestCode == REQUEST_CODE_CAMERA)
{
if (uploadMessage == null && uploadMessageAboveL == null)
{
return;
}
//取消拍照或者圖片選擇時,返回null,否則<input file> 就是沒有反應
if (resultCode != RESULT_OK)
{
if (uploadMessage != null)
{
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
if (uploadMessageAboveL != null)
{
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
}
}
//拍照成功和選取照片時
if (resultCode == RESULT_OK)
{
Uri imageUri = null;
switch (requestCode)
{
case REQUEST_CODE_ALBUM:
if (data != null)
{
imageUri = data.getData();
}
break;
case REQUEST_CODE_CAMERA:
if (!TextUtils.isEmpty(mCurrentPhotoPath))
{
File file = new File(mCurrentPhotoPath);
Uri localUri = Uri.fromFile(file);
Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri);
sendBroadcast(localIntent);
imageUri = Uri.fromFile(file);
mLastPhothPath = mCurrentPhotoPath;
}
break;
}
//上傳文件
if (uploadMessage != null)
{
uploadMessage.onReceiveValue(imageUri);
uploadMessage = null;
}
if (uploadMessageAboveL != null)
{
uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
uploadMessageAboveL = null;
}
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults == null && grantResults.length == 0)
{
return;
}
if (requestCode == REQUEST_CODE_PERMISSION_CAMERA)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
takePhoto();
}
else
{
// Permission Denied
new AlertDialog.Builder(mContext).setTitle("無法拍照").setMessage("您未授予拍照權限").setNegativeButton("取消", null).setPositiveButton("去設置", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", getPackageName(), null));
startActivity(localIntent);
}
}).create().show();
}
}
}
/**
* 選擇相機或者相冊
*/
public void uploadPicture()
{
AlertDialog.Builder builder = new AlertDialog.Builder(WebviewForNursingActivity.this);
builder.setTitle("請選擇圖片上傳方式");
//取消對話框
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialog)
{
//一定要返回null,否則<input type='file'>
if (uploadMessage != null)
{
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
if (uploadMessageAboveL != null)
{
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
}
}
});
builder.setPositiveButton("相機", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
if (!TextUtils.isEmpty(mLastPhothPath))
{
//上一張拍照的圖片刪除
mThread = new Thread(new Runnable()
{
@Override
public void run()
{
File file = new File(mLastPhothPath);
if (file != null)
{
file.delete();
}
mHandler.sendEmptyMessage(1);
}
});
mThread.start();
}
else
{
//請求拍照權限
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
{
takePhoto();
}
else
{
ActivityCompat.requestPermissions(WebviewForNursingActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_PERMISSION_CAMERA);
}
}
}
});
builder.setNegativeButton("相冊", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
chooseAlbumPic();
}
});
builder.create().show();
}
/**
* 拍照
*/
private void takePhoto()
{
StringBuilder fileName = new StringBuilder();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileName.append(UUID.randomUUID()).append("_upload.jpg");
File tempFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName.toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".fileprovider", tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
else
{
Uri uri = Uri.fromFile(tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
mCurrentPhotoPath = tempFile.getAbsolutePath();
startActivityForResult(intent, REQUEST_CODE_CAMERA);
}
/**
* 選擇相冊照片
*/
private void chooseAlbumPic()
{
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE_ALBUM);
}
但是這種方法,用相機拍照,傳遞兩張照片,有時候會有異常,可以使用下邊的代碼
private ValueCallback<Uri[]> mUploadCallback;
private Uri imageUri;
private int PHOTO_REQUEST_CODE = 1111;
...
public class MyWebChromeClient extends WebChromeClient
{
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
{
Log.i(TAG, "onJsAlert: " + message);
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
{
Log.i(TAG, "onJsConfirm: " + message);
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
{
Log.i(TAG, "onJsPrompt: " + message);
return super.onJsPrompt(view, url, message, defaultValue, result);
}
@Override
public void onReceivedTitle(WebView view, String title)
{
super.onReceivedTitle(view, title);
}
@Override
public void onProgressChanged(WebView view, int newProgress)
{
if (newProgress == 100)
{
progressBar.setVisibility(View.GONE);
}
else
{
if (progressBar.getVisibility() == View.GONE)
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
//For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
{
mUploadCallback = filePathCallback;
takePhoto();
return true;
}
}
Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
takePhoto();
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == PHOTO_REQUEST_CODE)
{
if (mUploadCallback != null)
{
choosePic(resultCode, data);
}
else
{
Toast.makeText(this, "發生錯誤", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 拍照或相冊
*/
private void takePhoto()
{
String filePath = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_PICTURES + File.separator;
String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
imageUri = Uri.fromFile(new File(filePath + fileName));
Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
Intent Photo = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent chooserIntent = Intent.createChooser(Photo, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
startActivityForResult(chooserIntent, PHOTO_REQUEST_CODE);
}
private void choosePic(int resultCode, Intent data)
{
if (RESULT_OK == resultCode)
{
updatePhotos();
if (data != null)
{
Uri[] results;
Uri uriData = data.getData();
if (uriData != null)
{
results = new Uri[]{uriData};
mUploadCallback.onReceiveValue(results);
}
else if (imageUri != null)
{
mUploadCallback.onReceiveValue(new Uri[]{imageUri});
}
else
{
mUploadCallback.onReceiveValue(null);
}
}
else
{
mUploadCallback.onReceiveValue(new Uri[]{imageUri});
}
}
else
{
mUploadCallback.onReceiveValue(null);
}
mUploadCallback = null;
}
//更新照片
private void updatePhotos()
{
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(imageUri);
sendBroadcast(intent);
}
小米部分機型,調起系統相冊沒反應的解決辦法
小米的部分機型,點擊相冊,沒反應,直接resultCode 0,解決辦法:
將MIUI優化關閉,重啓手機後,打開APP