在版本迭代中需要上傳圖片做統計,把鏈接發QQ上,里面的網頁可以正常上傳圖片,但是我們自己app里不能上傳。查了一些相關資料
默認情況下,Android的webview是不支持的,點擊沒有任何反應,如果希望點擊上傳,彈出選擇文件、圖片的窗口,我們可以重寫webview的webchromeClient中的openFileChooser方法,由於android系統有多個版本,因此需要重寫多個openFileChooser進行兼容,而android5.0以后,需要重寫onShowFileChooser方法,其上傳的參數Uri變成了Uri[]類型,說明5.0以后支持多傳圖片。查了很多文章,要么實現不了,要么對一些手機系統版本5.0及以上系統不適配或者手機型號不適配,總結前人經驗及遇到的坑查找stackoverflow 外國大佬提供的經驗,把實現方法分享一下,幫助小伙伴較少彎路。
可以用下面這個鏈接進行測試:
https://www.wenjuan.com/s/j67NJrg/
public class MyChromeClient extends WebChromeClient {
public static ValueCallback uriValueCallback;
public static ValueCallback valueCallbacks;
private Activity activity;
public static final int FILECHOOSER_RESULTCODE = 5173;
public static String mCameraFilePath = "";
@SuppressWarnings("deprecation")
public MyChromeClient(Activity cordova) {
this.activity = cordova;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback filePathCallback,
FileChooserParams fileChooserParams) {
// TODO 自動生成的方法存根
valueCallbacks = filePathCallback;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);
return true;
}
public void openFileChooser(ValueCallback uploadMsg,
String acceptType, String capture) {
uriValueCallback = uploadMsg;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);
}
// 3.0 +
@SuppressWarnings("static-access")
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
uriValueCallback = uploadMsg;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);
}
// Android < 3.0
@SuppressWarnings("static-access")
public void openFileChooser(ValueCallback uploadMsg) {
uriValueCallback = uploadMsg;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);
}
private Intent createDefaultOpenableIntent() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
"image/*");
// Intent chooser = createChooserIntent(createCameraIntent());
// chooser.putExtra(Intent.EXTRA_INTENT, i);
return i;
}
private Intent createChooserIntent(Intent... intents) {
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);
chooser.putExtra(Intent.EXTRA_TITLE, "選擇圖片");
return chooser;
}
@SuppressWarnings("static-access")
private Intent createCameraIntent() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File externalDataDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File cameraDataDir = new File(externalDataDir.getAbsolutePath()
+ File.separator + "515aaa");
cameraDataDir.mkdirs();
String mCameraFilePath = cameraDataDir.getAbsolutePath()
+ File.separator + System.currentTimeMillis() + ".jpg";
this.mCameraFilePath = mCameraFilePath;
cameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(mCameraFilePath)));
return cameraIntent;
}
public static void update(Uri[] uris) {
if ( valueCallbacks != null
&& uris[0] != null) {
valueCallbacks.onReceiveValue(uris);
valueCallbacks = null;
}
if(uriValueCallback != null
&& uris[0] != null){
uriValueCallback.onReceiveValue(uris[0]);
uriValueCallback = null;
}
}
}
在 對應的Activity中事件處理:
/**
* 返回文件選擇
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == MyChromeClient.FILECHOOSER_RESULTCODE&&
intent!=null&&resultCode == RESULT_OK) {
Uri[] uris = new Uri[1];
uris[0] = intent.getData();
MyChromeClient.update(uris);
}
}
測試手機有限,不知道還存在部分機型適配問題不,華為,小米,三星,以及4.x,5.x,6.x系統測試暫時沒問題。