Android實現在webview中長按圖片彈出菜單保存圖片
在項目中遇到一個保存webview中二維碼圖片的問題,做個筆記。
效果如圖:
用到webview的三個方法:
- getHitTestResult()——Gets a HitTestResult based on the current cursor node
- getType()——Gets the type of the hit test result(獲取所選中目標的類型,可以是圖片,超鏈接,郵件,電話等等)
- getExtra()——Gets additional type-dependant information about the result(獲取額外的信息,例如圖片的地址)
1. 第一步:給webview添加長按監聽
_mWebview.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
}
});
2. 第二步:通過webview的getHitTestResult()方法獲取HitTestResult 對象
(1)通過getType()獲取類型,通過類型判斷是否是圖片
WebView.HitTestResult result = ((WebView) v).getHitTestResult();
int type = result.getType();
type有這幾種類型:
WebView.HitTestResult.UNKNOWN_TYPE 未知類型
WebView.HitTestResult.PHONE_TYPE 電話類型
WebView.HitTestResult.EMAIL_TYPE 電子郵件類型
WebView.HitTestResult.GEO_TYPE 地圖類型
WebView.HitTestResult.SRC_ANCHOR_TYPE 超鏈接類型
WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE 帶有鏈接的圖片類型
WebView.HitTestResult.IMAGE_TYPE 單純的圖片類型
WebView.HitTestResult.EDIT_TEXT_TYPE 選中的文字類型
(2)通過getExtra()獲取額外信息,圖片這裏就是圖片地址
String imgurl = result.getExtra();
通過判斷類型來做不同的顯示效果,在這裏我只對圖片處理,長按圖片彈出一個PopWindow,效果自己寫。
3. 第三步:通過獲取的圖片地址下載圖片
最後把所有代碼整理一下:
自定義PopWindow——ItemLongClickedPopWindow.java
public class ItemLongClickedPopWindow extends PopupWindow {
/**
* 書籤條目彈出菜單 * @value * {@value} *
*/
public static final int FAVORITES_ITEM_POPUPWINDOW = 0;
/**
* 書籤頁面彈出菜單 * @value * {@value} *
*/
public static final int FAVORITES_VIEW_POPUPWINDOW = 1;
/**
* 歷史條目彈出菜單 * @value * {@value} *
*/
public static final int HISTORY_ITEM_POPUPWINDOW = 3;
/**
* 歷史頁面彈出菜單 * @value * {@value} *
*/
public static final int HISTORY_VIEW_POPUPWINDOW = 4;
/**
* 圖片項目彈出菜單 * @value * {@value} *
*/
public static final int IMAGE_VIEW_POPUPWINDOW = 5;
/**
* 超鏈接項目彈出菜單 * @value * {@value} *
*/
public static final int ACHOR_VIEW_POPUPWINDOW = 6;
private LayoutInflater itemLongClickedPopWindowInflater;
private View itemLongClickedPopWindowView;
private Context context;
private int type;
/**
* 構造函數 * @param context 上下文 * @param width 寬度 * @param height 高度 *
*/
public ItemLongClickedPopWindow(Context context, int type, int width, int height) {
super(context);
this.context = context;
this.type = type;
//創建
this.initTab();
//設置默認選項
setWidth(width);
setHeight(height);
setContentView(this.itemLongClickedPopWindowView);
setOutsideTouchable(true);
setFocusable(true);
}
//實例化
private void initTab() {
this.itemLongClickedPopWindowInflater = LayoutInflater.from(this.context);
switch (type) {
// case FAVORITES_ITEM_POPUPWINDOW:
// this.itemLongClickedPopWindowView = this.itemLongClickedPopWindowInflater.inflate(R.layout.list_item_longclicked_favorites, null);
// break;
// case FAVORITES_VIEW_POPUPWINDOW: //對於書籤內容彈出菜單,未作處理
// break;
// case HISTORY_ITEM_POPUPWINDOW:
// this.itemLongClickedPopWindowView = this.itemLongClickedPopWindowInflater.inflate(R.layout.list_item_longclicked_history, null);
// break;
// case HISTORY_VIEW_POPUPWINDOW: //對於歷史內容彈出菜單,未作處理
// break;
// case ACHOR_VIEW_POPUPWINDOW: //超鏈接
// break;
case IMAGE_VIEW_POPUPWINDOW: //圖片
this.itemLongClickedPopWindowView = this.itemLongClickedPopWindowInflater.inflate(R.layout.list_item_longclicked_img, null);
break;
}
}
public View getView(int id) {
return this.itemLongClickedPopWindowView.findViewById(id);
}
}
PopWindow的佈局文件——list_item_longclicked_img.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/item_longclicked_viewImage"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="查看圖片"
android:textColor="@android:color/white"
android:textSize="16sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray_9F" />
<TextView
android:id="@+id/item_longclicked_saveImage"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="保存圖片"
android:textColor="@android:color/white"
android:textSize="16sp" />
</LinearLayout>
通過GestureDetector獲取按下的位置,來定位PopWindow顯示的位置
private GestureDetector gestureDetector;
private int downX, downY;
gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
downX = (int) e.getX();
downY = (int) e.getY();
}
});
在Activity中對webview的監聽
_mWebview.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
WebView.HitTestResult result = ((WebView)v).getHitTestResult();
if (null == result)
return false;
int type = result.getType();
if (type == WebView.HitTestResult.UNKNOWN_TYPE)
return false;
if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
//let TextViewhandles context menu return true;
}
final ItemLongClickedPopWindow itemLongClickedPopWindow = new ItemLongClickedPopWindow(HtmlActivity.this,ItemLongClickedPopWindow.IMAGE_VIEW_POPUPWINDOW, UIUtils.dip2px(120), UIUtils.dip2px(90));
// Setup custom handlingdepending on the type
switch (type) {
case WebView.HitTestResult.PHONE_TYPE: // 處理撥號
break;
case WebView.HitTestResult.EMAIL_TYPE: // 處理Email
break;
case WebView.HitTestResult.GEO_TYPE: // TODO
break;
case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超鏈接
// Log.d(DEG_TAG, "超鏈接");
break;
case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
break;
case WebView.HitTestResult.IMAGE_TYPE: // 處理長按圖片的菜單項
imgurl = result.getExtra();
//通過GestureDetector獲取按下的位置,來定位PopWindow顯示的位置
itemLongClickedPopWindow.showAtLocation(v, Gravity.TOP|Gravity.LEFT, downX, downY + 10);
break;
default:
break;
}
itemLongClickedPopWindow.getView(R.id.item_longclicked_viewImage)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemLongClickedPopWindow.dismiss();
}
});
itemLongClickedPopWindow.getView(R.id.item_longclicked_saveImage)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemLongClickedPopWindow.dismiss();
new SaveImage().execute(); // Android 4.0以後要使用線程來訪問網絡
}
});
return true;
}
});
最後下載圖片
private String imgurl = "";
/***
* 功能:用線程保存圖片
*
* @author wangyp
*/
private class SaveImage extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String result = "";
try {
String sdcard = Environment.getExternalStorageDirectory().toString();
File file = new File(sdcard + "/Download");
if (!file.exists()) {
file.mkdirs();
}
int idx = imgurl.lastIndexOf(".");
String ext = imgurl.substring(idx);
file = new File(sdcard + "/Download/" + new Date().getTime() + ext);
InputStream inputStream = null;
URL url = new URL(imgurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20000);
if (conn.getResponseCode() == 200) {
inputStream = conn.getInputStream();
}
byte[] buffer = new byte[4096];
int len = 0;
FileOutputStream outStream = new FileOutputStream(file);
while ((len = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
outStream.close();
result = "圖片已保存至:" + file.getAbsolutePath();
} catch (Exception e) {
result = "保存失敗!" + e.getLocalizedMessage();
}
return result;
}
@Override
protected void onPostExecute(String result) {
showToast(result);
}
}