返回顶部
首页 > 资讯 > 移动开发 >Android截屏一键分享开发与实现方式的反思和总结
  • 176
分享到

Android截屏一键分享开发与实现方式的反思和总结

Android 2022-06-06 13:06:20 176人浏览 安东尼
摘要

本文主要记录Android系统截屏一键分享开发,后续优化。 近期接到新需求,需要做截屏,然后弹出小窗口,显示一键分享与截屏小图预览。类似于同花顺app截图弹出框,点击后出现分享

本文主要记录Android系统截屏一键分享开发,后续优化

近期接到新需求,需要做截屏,然后弹出小窗口,显示一键分享与截屏小图预览。类似于同花顺app截图弹出框,点击后出现分享界面.

效果图如下:

         

·一,分析该需求的整个流程,大致步骤如下

1,监听到截图的动作 2,获取当前图像 3,弹出提示框(显示截屏预览小图,带计时器自动隐藏) 4,点击分享后弹出分享窗,分享图片预览 5,点击某个平台后,生成自定义拼图分享到第三方

   其中监听截图动作,和图片展示与拼接是重点步骤。

二,实现方式,技术选择

    1,目前兼容性较高的截图监听方案为ContentObserver,可以兼容到android9.0。android10目前还在调研中(目前未发现有效方法)

     具体代码不多赘述,百度一大把,标准套路,记录几个核心问题,首先解决如何精准拿到截图问题。

    String[] KEYWordS = { "screenshot", "screenshots", "screen_shot", "screen-shot", "screen shot", "screencapture",      "screen_capture", "screen-capture", "screen capture", "screencap", "screen_cap", "screen-cap", "screen cap", "截屏" }

    过滤拿到的路径是否包含上述关键词,此时,没必要继续拿图片,只是监听到有截图动作即可,调用view截图生成bitmap方式,这样,保证最准确。同时,可以排除无用信息提示框,Toast等窗口。

     


此方法生成当前窗口的截图
/ * 截取当前窗体的截图,根据[isshowStatusBar]判断是否包含当前窗体的状态栏
 * 原理是获取当前窗体decorView的缓存生成图片
 */
public static Bitmap captureWindow(Activity activity) {
    boolean isStatuBar = false;
    // 获取当前窗体的View对象
    View view = activity.getWindow().getDecorView();
    view.setDrawinGCacheEnabled(true);
    // 生成缓存
    view.buildDrawingCache();
    Bitmap bitmap = null;
    if (isStatuBar) {
        // 绘制整个窗体,包括状态栏
        bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, view.getMeasuredWidth(),                         view.getMeasuredHeight());
    } else {
        // 获取状态栏高度
        Rect rect = new Rect();
        view.getWindowVisibleDisplayFrame(rect);
        Display display = activity.getWindowManager().getDefaultDisplay();
        // 减去状态栏高度
       bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0,
                rect.top, display.getWidth(), display.getHeight() - rect.top);
    }
    view.setDrawingCacheEnabled(false);
    view.destroyDrawingCache();
    return bitmap;
}

 生成bitmap 之后,考虑如何添加到当前Activity。方式有三种Popuwindow, dialog,和直接addView 方式。综合考虑,直接addView添加小窗口最合适。考虑如下,PopuWindow 和dialog弹出后,会抢占焦点,这样无法继续与原界面交互,那么倒计时小时的功能也变的无用。

 为了考虑通用型,每个Activity可以操作到的根布局为contentView ,为Framelayout。

//直接拿到contentView然后Inflate窗口view。设置好位置后,addView 到contentView,这样,使用倒计时销毁时,直接contentView.remove()即可。保证了每个界面添加的通用型,即使嵌套Fragment,也不用考虑焦点问题。

final ViewGroup viewById = mContext.findViewById(android.R.id.content);
final View view = View.inflate(mContext,R.layout.screen_shot_dialog,null);

FrameLayout.LayoutParams f = new FrameLayout.LayoutParams(width,height);

f.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;

f.rightMargin = DisplayUtil.dip2px(mContext,20); 

view.setLayoutParams(f);

final Bitmap bitmap = Utils.captureWindow(mContext); //获取当前窗口影像图片 替代从文件库取

imageView.setImageDrawable(new BitmapDrawable(bitmap)); 

viewById.addView(view);//最终添加到当前Activity

2,自定义分享图片的拼接问题。

   思路有二,一可以使用canvas绘制bitmap,拼接。方法主要难点在绘制位置,以及性能开销。(标准api,课自行百度)

                    二,可以同样借鉴View生成图片方案,先创建一个布局,在相关位置填好截屏图片,二维码,文字等。然后生成bitmap。注意,在调用以下方法,view必须添加到布局且重绘完毕,所以,可以使用view.postRunable()。在runalbe任务里面生成图片,以保证view准备完毕。



public static Bitmap captureView(View view) {
    view.setDrawingCacheEnabled(true);
    // 生成缓存
    view.buildDrawingCache();
    Bitmap bitmap = null;
    // 绘制整个view
    bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0,view.getWidth(), view.getHeight());
    view.setDrawingCacheEnabled(false);
    view.destroyDrawingCache();
    return bitmap;
}

在此注意,可以先添加到contentview 中,设置为隐藏,待生成完毕后,再移除掉。以保证生成正确。


               final View shareView = View.inflate(mContext,R.layout.share_view_splash,null);//用于生成分享图片的布局
               final ImageView iv_shot_share = shareView.findViewById(R.id.iv_shot_share);
               shareView.setVisibility(View.INVISIBLE);//设置为不可见,但是占用空间
                           contentView.addView(shareView);
                           contentView.requestLayout();
                            iv_shot_share.post(new Runnable() {//使用post方法,保证view绘制完毕
                                @Override
                                public void run() {
                                           Bitmap shareImg = Utils.captureView(shareView);//生成图片
                                            shareView.setVisibility(View.GoNE);
                                            contentView.removeView(shareView);//移除
                                        }
                                    });
                                }
                            });

3,关于截屏预览裁剪。

   Android  ImageVIew中现有的适配模式,centerCrop 等,无法满足,宽度充满,从顶部往下,超出则截掉的需求。所以,在ImageView 设置预览图时,需要对生成窗口视图bitmap进行二次处理。思路,使用Matrix将窗口视图缩放到与要展示的容器宽度比例。然后重新生成图片,从顶部开始,截出新图片。


public static Bitmap reClip(Bitmap bitmapOri,int widthTarget,int heightTarget){//xxxTarget 为ImageView 容器宽高
        int width = bitmapOri.getWidth();
        int height = bitmapOri.getHeight();
        Bitmap bitmap = null;
        float scaleWidth = (float) (widthTarget/1.0/width);
        //缩放
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth,scaleWidth);
        Bitmap bitmapScale = Bitmap.createBitmap(bitmapOri,0,0,width,height,matrix,false);//按照缩放比例生成新图
       //在此要做判断,新截图片不能大于原始图片高度。否则异常终止,尤其注意普通屏幕,一般没问题。全面屏,不做此判断,会出现崩               溃,具体和要展示的容器宽高有关
        if(bitmapScale.getHeight()> heightTarget){
            bitmap = Bitmap.createBitmap(bitmapScale,0,0,bitmapScale.getWidth(),heightTarget);
        }else{
            bitmap = Bitmap.createBitmap(bitmapScale,0,0,bitmapScale.getWidth(),bitmapScale.getHeight());
        }
        return bitmap;
    }

使用bitmap 注意及时回收。

4,关于分享图片问题,生成的本地图片保存到公共空间,


Environment.getExternalStorageDirectory()//比如这里

开发中,保存到应用包名下(context.getCacheDir),微信可以,但是QQ会出现无反应问题,报错信息也不明显。原因是读取权限问题,之后android10 还会进一步限制,所以,涉及到第三方app传递文件时,注意存储位置。


作者:Activity-Pj


--结束END--

本文标题: Android截屏一键分享开发与实现方式的反思和总结

本文链接: https://lsjlt.com/news/29180.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android截屏一键分享开发与实现方式的反思和总结
    本文主要记录android系统截屏一键分享开发,后续优化。 近期接到新需求,需要做截屏,然后弹出小窗口,显示一键分享与截屏小图预览。类似于同花顺app截图弹出框,点击后出现分享...
    99+
    2022-06-06
    Android
  • Android开发中实现登录微信与分享的方法
    本篇文章给大家分享的是有关Android开发中实现登录微信与分享的方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。第一步:申请你的AppID;第二步:依赖dependenci...
    99+
    2023-05-31
    android roi
  • Java项目开发中实现分页的三种方式总结
    目录前言使用1、SpringDataJPA分页2、MyBatis分页3、Hutools工具类分页总结前言 Java项目开发中经常要用到分页功能,现在普遍使用SpringBoot进行快...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作