Androidは、画像ポップアップメニューを長押しして画像をWebビューに保存することを実現します
プロジェクトで、QRコードの画像をWebビューに保存する際に問題が発生し、メモを取りました。
効果を図に示し
ます。webviewを使用する3つの方法:
- getHitTestResult() -現在のカーソルノードに基づいてHitTestResultを取得します
- getType() -ヒットテスト結果のタイプを取得します
- getExtra() -結果に関する追加のタイプ依存情報を取得します(画像のアドレスなどの追加情報を取得するため)
1.最初のステップ:長押しモニタリングをwebviewに追加します
_mWebview.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
}
});
2.ステップ2:webviewのgetHitTestResult()メソッドを介してHitTestResultオブジェクトを取得します
(1)getType()で型を取得し、型で画像かどうかを判断します
WebView.HitTestResult result = ((WebView) v).getHitTestResult();
int type = result.getType();
- 1
- 2
タイプにはいくつかのタイプがあります:
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. 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();
}
});
アクティビティでWebビューを監視する
_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長押し長押しして、画像を電話に保存します
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結果= ""; {String sdcard = Environment.getExternalStorageDirectory()。toString();を試してください。ファイルfile = new File(sdcard + "/ Download"); if(!file。存在()){file.mkdirs(); } int idx = imgurl.lastIndexOf( "。"); 文字列ext = imgurl.substring(idx); file = new File(sdcard + "/ Download /" + new Date()。getTime()+ ext); InputStream inputStream = null; URL url =新しい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(); 結果= "図片已購入至:" + file.getAbsolutePath(); } catch(Exception e){result = "救失败!" + e.getLocalizedMessage(); }結果を返します。} @Override protected void onPostExecute(String result){MsgBox( "完了"、result); }} }結果を返します。} @Override protected void onPostExecute(String result){MsgBox( "完了"、result); }} }結果を返します。} @Override protected void onPostExecute(String result){MsgBox( "完了"、result); }}
Android WebViewはすべてのコンテンツをインターセプトして、5.0を超える長い画像を生成します。システム例外の問題
最近、すべてのコンテンツのWebビューインターセプトを実行して長い画像を生成するときにいくつかの問題が発生しました。システムは通常Android 5.0で長い画像を生成できますが、5.0を超えると、最初の画面のコンテンツのみがキャプチャされ、残りはすべてキャプチャされます。空白。チェックデータによると、システムはバージョン5.0以降であることが判明しました。AndroidはWebビューを最適化しました。メモリ使用量を削減し、パフォーマンスを向上させるために、HTMLの描画が必要な部分をインテリジェントに描画します。デフォルト。これは実際には現在の画面に表示されているHTMLコンテンツです。したがって、表示されていない画像は空白になります。解決策は次のとおりです。
上に示したように、アクティビティの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){ nullを返す; } ビットマップbm; { bm = Bitmap.createBitmap(view.getMeasuredWidth()、view.getMeasuredHeight()、Bitmap.Config.ARGB_8888);を試してください。 } catch(OutOfMemoryError e){ System.gc(); {を試してください
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.0BY-SA著作権契約に従います。元のソースリンクを添付してくださいそして、再印刷のためのこの声明。元のリンク:https://blog.csdn.net/m13984458297/article/details/78687015