Android WebView實踐總結(三)WebView檔案上傳與自定義長按選單
1.WebView檔案上傳
網頁中有需要上傳檔案的情況,如果不做處理點選上傳檔案是沒有任何反應的,如圖片中出現的情況。 這裡以上傳圖片為例 。

點選無效舉例
WebChromeClientl
類中的
onShowFileChooser
方法,重寫此方法開啟檔案,通過
filePathCallback
類完成資料互動即可。
private static final int REQUEST_CODE_CHOOSE = 23; private ValueCallback<Uri[]> uploadMessage; mWebView.setWebChromeClient(new WebChromeClient() { @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { uploadMessage=filePathCallback; //網頁檔案上傳回調 //這裡開啟相簿 Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE_CHOOSE); return true; } });
開啟相簿選擇圖片,通過 activity
中的 onActivityResult
回撥方法獲取圖片資源,再通過 filePathCallback
方法把圖片資料傳給網頁。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //網頁上傳圖片回撥 if (requestCode == REQUEST_CODE_CHOOSE) { //圖片選擇後返回圖示,通過uploadMessage將圖片傳給網頁 if (uploadMessage != null) { onActivityResultAboveL(resultCode, data); } } } //處理網頁回撥 @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void onActivityResultAboveL(int resultCode, Intent intent) { Uri[] results = null; if (resultCode == Activity.RESULT_OK) { if (intent != null) { String dataString = intent.getDataString(); ClipData clipData = intent.getClipData(); if (clipData != null) { results = new Uri[clipData.getItemCount()]; for (int i = 0; i < clipData.getItemCount(); i++) { ClipData.Item item = clipData.getItemAt(i); results[i] = item.getUri(); } } if (dataString != null) results = new Uri[]{Uri.parse(dataString)}; } } uploadMessage.onReceiveValue(results); uploadMessage = null; }
到這裡無法上傳圖片的問題就解決啦, 效果圖如下:

網頁圖片上傳效果圖
2.WebView自定義長按選單
根據網頁中的不同型別(圖片,文字等等)彈出不同的選單對其進行慚怍。重寫 webview
的 setOnLongClickListener
方法,在方法裡面呼叫 getHitTestResult
方法獲取長按的資料和型別即可。
private onSelectItemListener mOnSelectItemListener; private int touchX = 0, touchY = 0; //webview中重寫此方法 setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { HitTestResult result = getHitTestResult(); if (null == result) return false; //得到型別 int type = result.getType(); //獲取長按後的資料 String extra = result.getExtra(); switch (type) { case HitTestResult.PHONE_TYPE: // 處理撥號 break; case HitTestResult.EMAIL_TYPE: // 處理Email break; case HitTestResult.GEO_TYPE: // 地圖型別 break; case HitTestResult.SRC_ANCHOR_TYPE: // 超連結 if (mOnSelectItemListener != null && extra != null && URLUtil.isValidUrl(extra)) { mOnSelectItemListener.onLinkSelected(touchX, touchY, result.getType(), extra); } return true; case HitTestResult.SRC_IMAGE_ANCHOR_TYPE: // 帶有連結的圖片型別 case HitTestResult.IMAGE_TYPE: // 處理長按圖片的選單項 if (mOnSelectItemListener != null && extra != null && URLUtil.isValidUrl(extra)) { mOnSelectItemListener.onImgSelected(touchX, touchY, result.getType(), extra); } return true; case HitTestResult.UNKNOWN_TYPE: //未知 break; case HitTestResult.EDIT_TEXT_TYPE://文字 break; } return true; } }); @Override public boolean onInterceptTouchEvent(MotionEvent event) { touchX = (int) event.getX(); touchY = (int) event.getY(); return super.onInterceptTouchEvent(event); } public void setOnSelectItemListener(onSelectItemListener onSelectItemListener) { mOnSelectItemListener = onSelectItemListener; } public interface onSelectItemListener { void onImgSelected(int x, int y, int type, String extra); void onLinkSelected(int x, int y, int type, String extra); }
設定完了監聽器後在主介面做處理更合適
mWebView.setOnSelectItemListener(new MyWebView.onSelectItemListener() { @Override public void onImgSelected(int x, int y, int type, String extra) { String[] menus = new String[]{"儲存圖片", "預覽圖片", "複製圖片連結", "分享圖片"}; new AlertDialog.Builder(MainActivity.this) .setItems(menus, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); switch (which) { case 0: break; case 1: break; case 2: Toast.makeText(MainActivity.this, "複製圖片連結點選了", Toast.LENGTH_LONG).show(); break; case 3: break; } } }).show(); } @Override public void onLinkSelected(int x, int y, int type, String extra) { String[] menus = new String[]{"複製連結地址", "新視窗開啟"}; new AlertDialog.Builder(MainActivity.this) .setItems(menus, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); switch (which) { case 0: break; case 1: Toast.makeText(MainActivity.this, "新視窗開啟點選了", Toast.LENGTH_LONG).show(); break; } } }).show(); } });
完成,效果圖如下:

網頁長按彈出對應選單