admin管理员组文章数量:1570422
最近太过于焦虑,晚上都睡不着啊,谁能告诉我怎么赚大钱啊?何以解忧?唯有暴富啊。555555555555555
好了话不多说,直接进入正题:
1、MediaProjectionManager //获取MediaProjection
2、MediaProjection //获取屏幕内容
3、ImageReader //通过这个类我们可以把Surface转换成图片
首先初始化相关的东西啦
public void initScreenHelper(Activity activity) {
//获取到屏幕的宽高
this.mActivity = activity;
WindowManager windowManager = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
this.mWidth = windowManager.getDefaultDisplay().getWidth() / 2;
this.mHeight = windowManager.getDefaultDisplay().getHeight() / 2;
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
this.mScreenDensity = displayMetrics.densityDpi / 3;
this.mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 5);
this.mMediaManager = (MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
Android截屏的api是Android系统5.0以后开放的api,切需要用户手动开启后才能使用。所以我们先要获取屏幕使用权限。
private boolean startScreenCapture() {
if (mMediaProjection != null) {//已经获取到权限并且获取到了mMediaProjection
setUpVirtualDisplay();
return true;
} else if (mResultCode != 0 && mResultData != null) {//获取到了权限
setUpMediaProjection();
setUpVirtualDisplay();
return true;
} else {//没有获取到权限,开启权限弹窗,并在onActivityResult回调里获取对应的数据
Log.e(TAG, "Requesting confirmation");
mActivity.startActivityForResult(mMediaManager.createScreenCaptureIntent(), REQUEST_CODE_PROJECTION);
return false;
}
}
/**
* 设置VirtualDisplay,屏幕截图载体
*/
private void setUpVirtualDisplay() {
//获取到的数据就已经储存在ImageReader中的surface中
if (mVirtualDisplay == null) {
mVirtualDisplay = mMediaProjection.createVirtualDisplay("AnyChatScreenHelper",
mWidth, mHeight, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);
}
}
private void setUpMediaProjection() {
if (mMediaProjection == null)
mMediaProjection = mMediaManager.getMediaProjection(mResultCode, mResultData);
}
最后就是拿到相关数据了
/**
* 处理截图数据
* Image.Plane中的 buffer 数据并不是完全是Bitmap所需要的,需要注意下面3点
* 1. Image 设置的图片格式与Bitmap设置的必须一致
* 2. 缓冲数据存在行间距,所以我们必须去除这些间距
*3. Image 使用后必须调用image.close();关闭,否则再次使用会报错
*/
private void handleCapture() {
if (mActivity != null && mActivity.isFinishing()) {
closeCapture();
return;
}
if (mImageReader == null) {
return;
}
Image image = mImageReader.acquireLatestImage();
if (image == null) {
open();
return;
}
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
if (planes == null) {
image.close();
return;
}
final ByteBuffer buffer = planes[0].getBuffer();
if (buffer == null) {
image.close();
return;
}
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
mBitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
mBitmap.copyPixelsFromBuffer(buffer);
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height);
image.close();
if (mBitmap != null) {//将数据转换为数据流
int bytes = mBitmap.getByteCount();
ByteBuffer buf = ByteBuffer.allocate(bytes);
mBitmap.copyPixelsToBuffer(buf);
if (!mBitmap.isRecycled()) {
mBitmap.recycle();
mBitmap = null;
}
if (buf == null) {
return;
}
byte[] datas = buf.array();
if (datas == null || datas.length == 0) {
return;
}
if (mPostRunable == null) {
mPostRunable = new PostRunable();
}
mPostRunable.setDatas(datas);
if (cachedThreadPool != null) {
cachedThreadPool.submit(mPostRunable);
}
if (mHandler != null) {
mHandler.sendEmptyMessageDelayed(MSG_SCREEN_CAPTURE, 100);
}
}
}
版权声明:本文标题:Android实现屏幕共享功能封装(原理:通过手机实时截图,并转化为视频流) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727669533a1125017.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论