Android实现在webview中长按图片弹出菜单保存图片
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();
- 1
- 2
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);
}
}
原文:http://www.educity.cn/wenda/179077.html
Android WebView Long Press长按保存图片到手机
private String imgurl = ""; /*** * 功能:长按图片保存到手机 */ @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() == "保存到手机") { new SaveImage().execute(); // Android 4.0以后要使用线程来访问网络 } 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); } }
Android WebView截取所有内容生成长图在5.0以上系统异常问题
最近在做webview截取所有内容生成长图时出现一些问题,在Android5.0以下系统能正常生成长图,但是在5.0以上会出现只能截取第一屏的内容,剩下的全部为空白,查看资料发现原来是系统在5.0+版本上,Android对webview做了优化,为了减少内存占用以提高性能,因此在默认情况下会智能的绘制html中需要绘制的部分,其实就是当前屏幕展示的html内容,因此会出现未显示的图像是空白的。解决方法如下:
如上图:在activity的onCreate方法中的setContentView前加上一句enableSlowWholeDocumentDraw();意思为取消系统的智能绘制,当然这样之后性能会有所下降,但为了实现功能,也只能如此。
加上之后在Android5.0以下系统会崩溃,那是因为在5.0以下没有enableSlowWholeDocumentDraw()这个方法,因此需要做个判断,获取本机系统版本号,当版本号大于5.0则调用enableSlowWholeDocumentDraw()方法,否则不调用。
代码为:API=21即为Android5.0系统
if (android.os.Build.VERSION.SDK_INT >= 21) {
enableSlowWholeDocumentDraw();
}
下面为生成长图代码:
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;
}
————————————————
版权声明:本文为CSDN博主「A_mnesia」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m13984458297/article/details/78687015
上一篇: PHP多文件上传操作,