Android realizes long press the picture pop-up menu to save the picture in the webview

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: Write picture description here
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













 

 

Guess you like

Origin blog.csdn.net/MYBOYER/article/details/104642091