Java Android使用MediaProjectionManager、OnImageAvailable和#x27;开始
我正在做一个android项目,在这个项目中,有一个覆盖按钮也位于其他应用程序的顶部,当点击这个按钮时,应该拍摄一个屏幕截图。覆盖按钮可以工作,但屏幕截图部分不能。我不知道为什么,但似乎OnImageAvailable没有启动。这里是一个单独的项目,我只测试屏幕截图部分:Java Android使用MediaProjectionManager、OnImageAvailable和#x27;开始,java,android,mediaprojectionmanager,Java,Android,Mediaprojectionmanager,我正在做一个android项目,在这个项目中,有一个覆盖按钮也位于其他应用程序的顶部,当点击这个按钮时,应该拍摄一个屏幕截图。覆盖按钮可以工作,但屏幕截图部分不能。我不知道为什么,但似乎OnImageAvailable没有启动。这里是一个单独的项目,我只测试屏幕截图部分: public class MainActivity extends Activity { private static final int REQUEST_CODE= 100; private MediaProjectio
public class MainActivity extends Activity {
private static final int REQUEST_CODE= 100;
private MediaProjectionManager mProjectionManager;
private MediaProjection mProjection;
private ImageReader mImageReader;
private Handler mHandler = new Handler(Looper.getMainLooper());
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// call for the projection manager
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
imageView = (ImageView) findViewById(R.id.imageView);
// start projection
final Button startButton = (Button)findViewById(R.id.button);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startProjection();
}
});
// start capture handling thread
new Thread() {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}.start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
mProjection = mProjectionManager.getMediaProjection(resultCode, data);
if (mProjection != null) {
final DisplayMetrics metrics = getResources().getDisplayMetrics();
final int density = metrics.densityDpi;
final int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
final Display display = getWindowManager().getDefaultDisplay();
final Point size = new Point();
display.getSize(size);
final int width = size.x;
final int height = size.y;
mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 2);
mProjection.createVirtualDisplay("screencap", width, height, density, flags, mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
Bitmap bitmap = null;
try {
image = mImageReader.acquireLatestImage();
if (image != null) {
final Image.Plane[] planes = image.getPlanes();
int width = image.getWidth();
int height = image.getHeight();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
byte[] newData = new byte[width*height*4];
int offset = 0;
bitmap = Bitmap.createBitmap(metrics, width, height, Bitmap.Config.ARGB_8888);
ByteBuffer buffer = planes[0].getBuffer();
for(int i = 0; i < height; ++i){
for(int j = 0; j < width; ++j){
int pixel = 0;
pixel |= (buffer.get(offset) & 0xff) << 16; // R
pixel |= (buffer.get(offset + 1) & 0xff) << 8; // G
pixel |= (buffer.get(offset + 2) & 0xff); // B
pixel |= (buffer.get(offset + 3) & 0xff) << 24; // A
bitmap.setPixel(j, i, pixel);
offset += pixelStride;
}
offset += rowPadding;
}
imageView.setImageBitmap(bitmap);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bitmap!=null)
bitmap.recycle();
if (image!=null)
image.close();
}
}
}, mHandler);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void startProjection() {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
}
}
公共类MainActivity扩展活动{
私有静态最终整数请求_代码=100;
私有媒体项目管理器mProjectionManager;
私人媒体项目;
私人图像阅读器;
私有处理程序mHandler=新处理程序(Looper.getMainLooper());
私人影像视图;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//打电话给投影经理
mProjectionManager=(MediaProjectionManager)getSystemService(Context.MEDIA\u PROJECTION\u SERVICE);
imageView=(imageView)findViewById(R.id.imageView);
//起始投影
最终按钮开始按钮=(按钮)findViewById(R.id.Button);
startButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
startProjection();
}
});
//启动捕获处理线程
新线程(){
@凌驾
公开募捐{
Looper.prepare();
mHandler=新处理程序();
loop.loop();
}
}.start();
}
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
if(requestCode==请求\代码){
mProjection=mProjectionManager.getMediaProjection(结果代码,数据);
如果(mProjection!=null){
final DisplayMetrics=getResources().getDisplayMetrics();
最终整数密度=metrics.densityDpi;
final int flags=DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY|DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
最终显示=getWindowManager().getDefaultDisplay();
最终点大小=新点();
display.getSize(size);
最终整型宽度=尺寸x;
最终整型高度=尺寸y;
mImageReader=ImageReader.newInstance(宽度、高度、ImageFormat.JPEG,2);
mProjection.createVirtualDisplay(“screencap”、宽度、高度、密度、标志、mImageReader.getSurface()、null、mHandler);
setOnImageAvailableListener(新的ImageReader.OnImageAvailableListener(){
@凌驾
公共图像可用(图像阅读器){
图像=空;
位图=空;
试一试{
image=mImageReader.acquiredlatestimage();
如果(图像!=null){
final Image.Plane[]planes=Image.getPlanes();
int width=image.getWidth();
int height=image.getHeight();
int pixelStride=平面[0]。getPixelStride();
int rowStride=平面[0]。getRowStride();
int rowPadding=rowStride-pixelStride*width;
字节[]新数据=新字节[宽度*高度*4];
整数偏移=0;
bitmap=bitmap.createBitmap(度量、宽度、高度、bitmap.Config.ARGB_8888);
ByteBuffer buffer=平面[0]。getBuffer();
对于(int i=0;i 像素|=(buffer.get(offset)&0xff)我认为应该设置不同的标志。
你告诉MediaProjection只显示它自己的内容,但你没有在它的表面上画任何东西。
要进行屏幕截图,您必须使用“DisplayManager.VIRTUAL\u DISPLAY\u FLAG\u AUTO\u MIRROR”标志复制不同的显示