Android realizes long press the picture pop-up menu to save the picture in the webview
In the project, I encountered a problem of saving the QR code picture in the webview, and make a note.
The effect is shown in the figure:
three methods of using webview:
- getHitTestResult()——Gets a HitTestResult based on the current cursor node
- getType() ——Gets the type of the hit test result (gets the type of the selected target, which can be a picture, hyperlink, email, phone, etc.)
- getExtra() ——Gets additional type-dependant information about the result (to obtain additional information, such as the address of the picture)
1. The first step: add long-press monitoring to webview
_mWebview.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
}
});
2. Step 2: Obtain the HitTestResult object through the getHitTestResult() method of webview
(1) Get the type through getType(), and judge whether it is a picture by the type
WebView.HitTestResult result = ((WebView) v).getHitTestResult();
int type = result.getType();
- 1
- 2
There are several types of 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) Get extra information through getExtra(), the picture here is the picture address
String imgurl = result.getExtra();
Different display effects can be made by judging the type. Here I only process the picture. Long press the picture to pop up a PopWindow, and write the effect by myself.
3. The third step: download the picture through the obtained picture address
Finally, sort out all the codes:
Custom 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 layout file-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>
Get the pressed position through GestureDetector to locate the position displayed by 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();
}
});
Monitor webview in Activity
_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;
}
});
Finally download the picture
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);
}
}
Original: http://www.educity.cn/wenda/179077.html
Android WebView Long Press long press to save the picture to the phone
private String imgurl = ""; /*** * Function: Long press the picture to save to the phone*/ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {super.onCreateContextMenu(menu, v, menuInfo); MenuItem .OnMenuItemClickListener handler = new MenuItem.OnMenuItemClickListener() {public boolean onMenuItemClick(MenuItem item) {if (item.getTitle() == "Save to phone") {new SaveImage().execute(); // To be required after Android 4.0 Use threads to access the network} else {return false;} return true;} }; if (v instanceof WebView) {WebView.HitTestResult result = ((WebView) v).getHitTestResult(); if (result != null) {int type = result.getType(); if (type == WebView.HitTestResult.IMAGE_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) { imgurl = result.getExtra(); menu.setHeaderTitle("提示"); menu.add(0, v.getId(), 0, "保存到手机").setOnMenuItemClickListener(handler); } } } } /*** * 功能:用线程保存图片 * * @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) { MsgBox("提示", result); } } } return result; } @Override protected void onPostExecute(String result) { MsgBox("提示", result); } } } return result; } @Override protected void onPostExecute(String result) { MsgBox("提示", result); } }
Android WebView intercepts all content to generate long images above 5.0. System exception problem
Recently, there have been some problems when doing webview interception of all content to generate long images. The system can generate long images normally under Android 5.0, but above 5.0, it will only capture the content of the first screen, and the rest are all blank. Check According to the data, it turns out that the system is on version 5.0+. Android has optimized the webview. In order to reduce memory usage and improve performance, it will intelligently draw the part of HTML that needs to be drawn by default, which is actually the HTML content displayed on the current screen. , So the undisplayed image is blank. The solution is as follows:
As shown above: add a sentence enableSlowWholeDocumentDraw() before the setContentView in the activity's onCreate method; it means to cancel the intelligent drawing of the system. Of course, the performance will decrease after this, but in order to realize the function, it can only be so.
After adding, the system will crash under Android5.0, it is because there is no enableSlowWholeDocumentDraw() method under 5.0, so you need to make a judgment to get the local system version number, when the version number is greater than 5.0, call the enableSlowWholeDocumentDraw() method, Otherwise, it is not called.
The code is: API=21 is the Android5.0 system
if (android.os.Build.VERSION.SDK_INT >= 21) { enableSlowWholeDocumentDraw(); } The following is the code for generating long images:
public Bitmap viewShot(final View view) {
if (view == null)
return null;
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
int measureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(measureSpec, measureSpec);
if (view.getMeasuredWidth() <= 0 || view.getMeasuredHeight() <= 0) {
return null;
}
Bitmap bm;
try {
bm = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError e) {
System.gc();
try {
bm = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError ee) { return null; } } Canvas bigCanvas = new Canvas(bm); Paint paint = new Paint(); int iHeight = bm.getHeight(); bigCanvas.drawBitmap(bm, 0, iHeight, paint); view.draw(bigCanvas); showToast(getString(R.string.already_share_save_img)); return bm; } — ——————————————— Copyright Statement: This article is the original article of CSDN blogger "A_mnesia", and it follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this statement for reprinting. Original link: https://blog.csdn.net/m13984458297/article/details/78687015