First, let’s briefly talk about the function to achieve in this article: when the user is browsing the web, long press a certain area, identify if it is a picture, then the pop-up box, the function of saving the picture appears. At the same time, identify whether the picture is two-dimensional code, if it is, add the function of identifying two-dimensional code in the pop-up box.

Details: The frame to save the picture should be displayed at the position of the finger long press; After selecting pictures to save, users can directly go to the album to view; Choose to identify the QR code, determine whether it is a url, if it is, you can let users choose to copy or access, otherwise you can let users choose to copy or search.

Then take a look at the renderings:

Save the picture

Recognition of qr codes containing common text:

Identify the QR code containing the url:

Classes and libraries used by the above functions:

  • Get long press content:WebView.HitTestResult
  • List of pop-ups:DialogFragment
  • Image download:Glide
  • Qr code recognition:Zxing

Realize the point

Record the position of the long press

Inheriting WebView to record touch location:

  @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        touchX = (int) event.getRawX();
        touchY = (int) event.getRawY();
        return super.onInterceptTouchEvent(event);
    }
Copy the code

The reason I chose DialogFragment instead of PoupWindow is that poupWindow displays usually rely on another View and have compatibility issues above 7.0. Determine whether the content type of the long press position is a picture:

Get picture information

     setOnLongClickListener(new View.OnLongClickListener() {

            public boolean onLongClick(View v) {
                WebView.HitTestResult result = getHitTestResult();
                if (null == result)
                    return false;
                int type = result.getType();
                switch (type) {
                    caseWebView. HitTestResult. EDIT_TEXT_TYPE: / / selected text typesbreak;
                    caseWebView. HitTestResult. PHONE_TYPE: dial / / processingbreak;
                    caseWebView. HitTestResult. EMAIL_TYPE: / / deal with Emailbreak;
                    caseWebView.HitTestResult.GEO_TYPE: //   The map typebreak;
                    caseWebView. HitTestResult. SRC_ANCHOR_TYPE: / / hyperlinksbreak;
                    caseWebView. HitTestResult. SRC_IMAGE_ANCHOR_TYPE: / / picture type with linkscaseWebView. HitTestResult. IMAGE_TYPE: / / processing according to the menu item of the picture long String url = result. GetExtra ();if(mOnSelectItemListener ! = null && url ! = null && URLUtil.isValidUrl(url)) { mOnSelectItemListener.onSelected(touchX, touchY, result.getType(), url); }return true;
                    caseWebView. HitTestResult. UNKNOWN_TYPE: / / unknownbreak;
                }
                return false; }});Copy the code

The popup box pops up at the position where the finger is long pressed

HitTestResult is an entity class that records only two pieces of information: the type of the selected content and the specific value of the content. As you can see, with webView.hitTestResult, we can get a lot more content types than just images. Of course, we just need to determine whether it’s an image or not, and then call back the position of the long press and the URL to the outer layer. Long press the finger to display the dialog box, mainly to set the DialogFragment display position:

 public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if(dialog ! = null) { Window window = dialog.getWindow();if(window ! = null) { WindowManager.LayoutParams lp = window.getAttributes(); window.setGravity(Gravity.LEFT | Gravity.TOP); lp.x = LocationX; Lp. y = LocationY; Lp. width = uiHelper.dip2px (100); Lp. DimAmount = 0.0 f; / / outer background transparent, default dimming lp. Width = ViewGroup. LayoutParams. WRAP_CONTENT; lp.height = ViewGroup.LayoutParams.WRAP_CONTENT; window.setAttributes(lp); window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // Internal background transparent}}}Copy the code

Save to photo album

Use Glide to download images, Glide comes with preloading and image caching, no need to download from the network every time:

GlideApp.with(appContext).asFile().load(url).submit().get();
Copy the code

You can preload it when you long press to recognize the image:

 GlideApp.with(appContext).asBitmap().load(url).preload();
Copy the code

To save pictures in albums:

 public static void displayToGallery(Context context, File photoFile) {
        if(photoFile == null || ! photoFile.exists()) {return; } String photoPath = photoFile.getAbsolutePath(); String photoName = photoFile.getName(); / / the file is inserted into the gallery system try {ContentResolver ContentResolver = context. GetContentResolver (); MediaStore.Images.Media.insertImage(contentResolver, photoPath, photoName, null); } catch (FileNotFoundException e) { e.printStackTrace(); SendBroadcast (new Intent(Intent.action_media_scanner_scan_file, uri.parse ())."file://" + photoPath)));
    }
Copy the code

Identify the QR code in the picture

It is also necessary to judge whether the picture contains a QR code while displaying the pop-up box, which is part of Zxing’s built-in function, so the code is not posted. Note that you should not wait for Zxing to determine whether it is a QR code before displaying the pop-up box, because this part of the operation may take a long time (see Figure 2). The content of the pop-up list should be updated after identifying the content of the QR code.

conclusion

In general, the implementation of this function is very much attention to the place, but fortunately, they are not complex. Of course, there are still places to be optimized in this example, and to achieve more advanced functions, such as to search for a picture, view a large picture function, you can also use WebView.HitTestResult to obtain other types of content for processing, limited to the length will not expand. The Github address of the project is posted at the end, and those interested in WebView can learn about it:

Github