Android截屏分享功能

最近项目需要实现Android截屏分享功能,包括Android截屏获取图片、将图片保存到本地、通知系统相册更新、通过微信、QQ、微博分享截屏图片,本篇文章作为总结回顾。

    一、Android截屏获取图片

通过对view进行绘制,得到bitmap,可以对Activity、Fragment进行绘制,也可以对其他的View进行绘制。

   1 Activity截图(带空白的状态栏)

public Bitmap shotScreen(Activity activity) {
 View view = activity.getWindow().getDecorView();
 view.setDrawingCacheEnabled(true);
 view.buildDrawingCache();
 Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
 view.setDrawingCacheEnabled(false);
 view.destroyDrawingCache();
 return bitmap;
}

  2 Activity截图(去掉状态栏)

public Bitmap shotActivityNoBar(Activity activity) {
 // 获取windows中最顶层的view
 View view = activity.getWindow().getDecorView();
 view.buildDrawingCache();
 // 获取状态栏高度
 Rect rect = new Rect();
 view.getWindowVisibleDisplayFrame(rect);
 int statusBarHeights = rect.top;
 Display display = activity.getWindowManager().getDefaultDisplay();
 // 获取屏幕宽和高
 int widths = display.getWidth();
 int heights = display.getHeight();
 // 允许当前窗口保存缓存信息
 view.setDrawingCacheEnabled(true);
 // 去掉状态栏
 Bitmap bmp = Bitmap.createBitmap(view.getDrawingCache(), 0,
   statusBarHeights, widths, heights - statusBarHeights);
 // 销毁缓存信息
 view.destroyDrawingCache();
 return bmp;
} 

3 Fragment截图

public Bitmap getFragmentBitmap(Fragment fragment) {
 View v = fragment.getView();
 v.buildDrawingCache(false);
 return v.getDrawingCache();
}

绘制View的方式只适用于静态View,SurfaceView、IjkVideoView等播放视频的View,不能截取到;此外,某些动画类View也不能截取到。针对上述情况,可获取SurfaceView的一帧生成bitmap,将bitmap进行合并,同理动画类View也可以合并。例如,最底层播放视频、中间层播放动画、最上层是普通的view,可将bitmap合并,如下:

public Bitmap combineBitmapInCenter(Bitmap background, Bitmap midBitmap, Bitmap foreground) {
  if (!background.isMutable()) {
   background = background.copy(Bitmap.Config.ARGB_8888, true);
  }
  Paint paint = new Paint();
  Canvas canvas = new Canvas(background);
  int bw = background.getWidth();
  int bh = background.getHeight();
  int mw = midBitmap.getWidth();
  int mh = midBitmap.getHeight();
  int mx = (mw - bw) / 2;
  int my = (mh - bh) / 2;
  canvas.drawBitmap(midBitmap, mx, my, paint);
  int fw = foreground.getWidth();
  int fh = foreground.getHeight();
  int fx = (fw - bw) / 2;
  int fy = (fh - bh) / 2;
  canvas.drawBitmap(foreground, fx, fy, paint);
  canvas.save(Canvas.ALL_SAVE_FLAG);
  canvas.restore();
  return background;
}

需要注意:view的绘制必须在UI线程完成,否则会crash;bitmap的合并会较耗时,需在子线程完成。

二 、将bitmap保存在本地

public void saveBitmapToFile(String fileName, Bitmap bitmap) {
  if (TextUtils.isEmpty(fileName) || bitmap == null) return;
  try {
   File f = new File(fileName);
   f.createNewFile();
   FileOutputStream fOut = new FileOutputStream(f);
   bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fOut);
   fOut.flush();
   fOut.close();
  } catch (FileNotFoundException e) {
   Log.i("ScreenShotUtil", "保存失败");
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
} 

三、通知系统相册更新

public void AlbumScan(String fileName) {
  MediaScannerConnection.scanFile(mActivity.getApplicationContext(), new String[]{fileName}, new String[]{"image/jpeg"}, null);
}

四、通过微信、QQ、微博分享

通过微信、QQ、微博分享的sdk实现,如下:

   1 分享到微信朋友圈

public void shareToWexinCircle() {
  if (iShareService.isWeixinInstalled()) {//判断微信是否安装
   Bitmap mWXShareBitmap = mLatesBitmap;//将截屏得到的bitmap赋值
   WXImageObject imgObject = new WXImageObject(mWXShareBitmap);
   WXMediaMessage mediaMessage = new WXMediaMessage();
   mediaMessage.mediaObject = imgObject;
   Log.i(TAG,"mediaMessage.mediaObject = imgObject");
   //设置缩略图
   Bitmap thumbBmp = Bitmap.createScaledBitmap(mWXShareBitmap,50,80,true);
   mediaMessage.thumbData = bmpToByteArray(thumbBmp,true);
   Log.i(TAG,"设置缩略图");
   //request to wx
   SendMessageToWX.Req req = new SendMessageToWX.Req();
   req.transaction = buildTransaction("img");//分享类型是图片
   req.message = mediaMessage;
   req.scene = SendMessageToWX.Req.WXSceneTimeline;//分享到朋友圈
   Log.i(TAG,"request to wx");
   IWXAPI api = WXAPIFactory.createWXAPI(mActivity,"微信分享id",true);
   api.registerApp("微信分享id");
   boolean result = api.sendReq(req);
   Log.i(TAG,"share to circle:"+result);
  } else {
   ToastUtils.show(mActivity, "您没有安装微信客户端");
  }
} 

public byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
  ByteArrayOutputStream output = new ByteArrayOutputStream();
  bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
  if (needRecycle) {
   bmp.recycle();
  }
  byte[] result = output.toByteArray();
  try {
   output.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return result;
} 

<pre name="code" class="java">private String buildTransaction(final String type) {
  return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}</pre>
<h3><a name="t8"></a><br> 

2、分享到微信好友</h3> 

<pre></pre>
<pre name="code" class="java"> public void shareWexinFriend() {
  if (iShareService.isWeixinInstalled()) {
   mWXShareBitmap = mLatesBitmap;
   WXImageObject imgObject = new WXImageObject(mWXShareBitmap);
   WXMediaMessage mediaMessage = new WXMediaMessage();
   mediaMessage.mediaObject = imgObject;
   //设置缩略图
   Bitmap thumbBmp = Bitmap.createScaledBitmap(mWXShareBitmap,50,80,true);
   mediaMessage.thumbData = bmpToByteArray(thumbBmp,true);
   //request to wx
   SendMessageToWX.Req req = new SendMessageToWX.Req();
   req.transaction =buildTransaction("img");
   req.message = mediaMessage;
   req.scene = SendMessageToWX.Req.WXSceneSession;
   IWXAPI api = WXAPIFactory.createWXAPI(mActivity,"微信分享id",true);
   api.registerApp("微信分享id");
   boolean result = api.sendReq(req);
   Log.i(TAG,"share to weixin:"+result );
  } else {
   ToastUtils.show(mActivity, "您没有安装微信客户端");
  }
}</pre>
<h3><a name="t9"></a>3、分享到QQ好友</h3>
<pre name="code" class="java"> public void shareToQQFriend() {
  if (iShareService.isQQInstalled()) {//判断QQ是否安装
   Tencent tencent = Tencent.createInstance("qq id", mActivity);
   Bundle params = new Bundle();
   params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, mLatestImagePath);//QQ分享只能分享本地图片,传入本地图片路径
   params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
   tencent.shareToQQ(mActivity, params, new IUiListener() {//分享后的回调
    @Override
    public void onComplete(Object o) {
     ToastUtils.show(mActivity,"分享成功!");
    }
    @Override
    public void onError(UiError uiError) {
     ToastUtils.show(mActivity,"分享失败,稍后重试!");
     Log.i(TAG,"shareToQQ onError");
    }
    @Override
    public void onCancel() {
     Log.i(TAG,"shareToQQ onCancel");
    }
   });
  } else {
   ToastUtils.show(mActivity, "您没有安装QQ客户端");
  }
}</pre>
<pre></pre>
<pre></pre> 

4 QQ空间分享

public void shareToQQZone() {
  if (iShareService.isQQInstalled()) {
   Tencent tencent = Tencent.createInstance("QQ id", mActivity);
   Bundle params = new Bundle();
   params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, mLatestImagePath);
   params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
   params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
   tencent.shareToQQ(mActivity, params, new IUiListener() {
    @Override
    public void onComplete(Object o) {
     ToastUtils.show(mActivity,"分享成功!");
    }
    @Override
    public void onError(UiError uiError) {
     ToastUtils.show(mActivity,"分享失败,请稍后重试!");
     Log.i(TAG,"shareToQQ onError,error code:"+uiError.errorCode);
    }
    @Override
    public void onCancel() {
     Log.i(TAG,"shareToQQ onCancel");
    }
   });
  } else {
   ToastUtils.show(mActivity, "您没有安装QQ客户端");
  } 

5 微博分享

public void shareToWeibo() {
  if (iShareService.isWeiboInstalled()) {
   Log.i(TAG,"iShareService.isWeiboInstalled()");
   IWeiboShareAPI api = WeiboShareSDK.createWeiboAPI(mActivity, "微博id");
   if(api.isWeiboAppInstalled()) {
    api.registerApp();
   }
   WeiboMultiMessage weiboMultiMessage = new WeiboMultiMessage();
   Bitmap bitmap = mLatesBitmap;//截图bitmap
   ImageObject imageObject = new ImageObject();
   imageObject.setImageObject(bitmap);
   weiboMultiMessage.imageObject = imageObject;
   SendMultiMessageToWeiboRequest request = new SendMultiMessageToWeiboRequest();
   request.transaction = String.valueOf(System.currentTimeMillis());
   request.multiMessage = weiboMultiMessage;
   boolean requestWeibo = api.sendRequest(request);
   Log.i(TAG,"share to weibo:"+requestWeibo );
  } else {
   ToastUtils.show(mActivity, "您没有安装微博客户端");
  }
} 

总结

以上所述是小编给大家介绍的Android截屏分享功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

您可能感兴趣的文章:

  • Android截屏方案实现原理解析
  • Android 下调试手机截屏的方法
  • Android 实现截屏功能的实例
  • android长截屏原理及实现代码
  • Android实现截屏方式整理(总结)
  • Android截屏SurfaceView黑屏问题的解决办法
  • Android截屏截图的几种方法总结
  • android中Webview实现截屏三种方式小结
  • Android 获取浏览器当前分享页面的截屏示例
  • Android实现矩形区域截屏的方法
  • Android Activity 不能被截屏的解决方法
(0)

相关推荐

  • Android实现截屏方式整理(总结)

    本文介绍了Android 实现截屏方式整理,分享给大家.希望对大家有帮助 可能的需求: 截自己的屏 截所有的屏 带导航栏截屏 不带导航栏截屏 截屏并编辑选取一部分 自动截取某个空间或者布局 截取长图 在后台去截屏 1.只截取自己应用内部界面 1.1 截取除了导航栏之外的屏幕 View dView = getWindow().getDecorView(); dView.setDrawingCacheEnabled(true); dView.buildDrawingCache(); Bitmap

  • Android 下调试手机截屏的方法

    Android 下调试手机截屏的方法 Android开发过程中,难免会需要对手机进行截屏.以前截屏时一直到处找截屏软件,操作复杂. 今天刚发现,原来ADT是自带截屏功能的,而且操作简单. 打开DDMS视图,在Device框的右上角有一个照相机的小图标按钮,此按钮即可实现截屏功能,如图. 点击该按钮时,弹出如下对话框: 然后就可以将截屏图片保存或复制了! 如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • Android截屏SurfaceView黑屏问题的解决办法

    最近项目中有截屏的需求,普通的view截屏方法网上一搜一大把,但是SurfaceView截屏黑屏问题很多文章说的并不清楚,自己参考了一些别的博客,再加上自己的思考,算是找到了一种解决方案. 1.首先看我们一般是怎么用SurfaceView的 public class SuperSurfaceView extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder surfaceHolder; public SuperSu

  • Android截屏方案实现原理解析

    Android截屏的原理:获取具体需要截屏的区域的Bitmap,然后绘制在画布上,保存为图片后进行分享或者其它用途 在截屏功能中,有时需要截取全屏的内容,有时需要截取超过一屏的内容(比如:Listview,Scrollview,RecyclerView).下面介绍各种场景获取Bitmap的方法 普通截屏的实现 获取当前Window的DrawingCache的方式,即decorView的DrawingCache /** * shot the current screen ,with the sta

  • Android 获取浏览器当前分享页面的截屏示例

    今天在项目中碰见这么一个需求:获取 Chrome 浏览器分享时,页面的截屏.静下来一想,既然是分享,那么肯定得通过 Intent 来传递数据,如果真的能获取到 Chrome 分享页面时的截屏,那么 Intent 的数据中,一定有 .jpg 或者 .png 结尾的数据.说干就干,Demo 写起来. 首先,新建一个 BrowserScreenShotActivity.java,在 AndroidManifest.xml 注册一下 <intent-filter>. <?xml version=

  • android长截屏原理及实现代码

    小米系统自带的长截屏应该很多人都用过,效果不错.当长截屏时listview就会自动滚动,当按下停止截屏时,就会得到一张完整的截屏. 该篇就介绍一下长截屏的原理 上篇中介绍了android屏幕共享实现方式,该篇的原理和上一篇基本一致. 获取view影像 当我们想得到一个view的影像时,我们可以调用系统api,得到view的bitmap,但有时可能得不到.我们可以通过另一种方式得到. 首先创建一个和view一样大小的bitmap 复制代码 代码如下: Bitmap bmp = Bitmap.cre

  • Android Activity 不能被截屏的解决方法

    在Activity 添加即可 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); 以上这篇Android Activity 不能被截屏的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: Android截屏方案实现原理解析 Android截屏分享功能 Android 下调试手机截屏的方法 Android 实现截屏功能的实例 android长截屏原理及实现代码 Andr

  • Android 实现截屏功能的实例

    Android 实现截屏功能的实例 实现代码: public class ScreenShot { // 获取指定Activity的截屏,保存到png文件 private static Bitmap takeScreenShot(Activity activity) { // View是你需要截图的View View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildD

  • android中Webview实现截屏三种方式小结

    本人最近学习了android中Webview实现截屏三种方式,下面我来记录一下,有需要了解的朋友可参考.希望此文章对各位有所帮助. 第一种方式 通过调用webview.capturePicture(),得到一个picture对象,根据图像的宽和高创建一个Bitmap,再创建一个canvas,绑定bitmap,最后用picture去绘制. //获取Picture对象 Picture picture = wv_capture.capturePicture(); //得到图片的宽和高(没有reflec

  • Android实现矩形区域截屏的方法

    对屏幕进行截屏并裁剪有两种方式:早截图和晚截图.早截图,就是先截取全屏,再让用户对截取到的图片进行修改:与之相对的,晚截图,就是先让用户在屏幕上划好区域,再进行截图和裁剪.其实两者并没有什么太大的区别,这篇就说说怎么实现晚截图. 晚截图可以分成三步: 1. 在屏幕上标出截图的矩形区域 2. 调用系统接口截屏 3. 对截图进行裁剪 效果图如下: 第一步.在屏幕上标识出截图区域 首先确定标识截图区域所需要的功能: 1. 手指拖动形成矩形区域: 2. 可以拖动已经划好的矩形区域进行移动: 3. 可以拖

  • Android截屏截图的几种方法总结

    Android截屏 Android截屏的原理:获取具体需要截屏的区域的Bitmap,然后绘制在画布上,保存为图片后进行分享或者其它用途 一.Activity截屏 1.截Activity界面(包含空白的状态栏) /** * 根据指定的Activity截图(带空白的状态栏) * * @param context 要截图的Activity * @return Bitmap */ public static Bitmap shotActivity(Activity context) { View vie

随机推荐