///ANDROID5.0实现屏幕监控
主要方法 下载地址
效果图()
PC端,利用netty做数据交互
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf bytefu = (ByteBuf) msg;
byte[] iamgeDatas = new byte[bytefu.readableBytes()];
System.out.println("图片数据大小:" + iamgeDatas.length);
// msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中
bytefu.readBytes(iamgeDatas);
byte oragin = iamgeDatas[0];
System.out.println("图片的方向:" + oragin);
ByteArrayInputStream buffin = new ByteArrayInputStream(iamgeDatas, 1, iamgeDatas.length);
BufferedImage img = ImageIO.read(buffin);
onReciveImage.onRecive(oragin, img);
// 释放资源
bytefu.release();
}
andorid端,利用android5.0自带屏幕截取实现
private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { LogUtils.debug("有图片可用"); if (recording) { Image image = imageReader.acquireNextImage(); if (null != image) { final int width = image.getWidth(); final int height = image.getHeight(); final Image.Plane[] planes = image.getPlanes(); final ByteBuffer buffer = planes[0].getBuffer(); final int pixelStride = planes[0].getPixelStride(); final int rowStride = planes[0].getRowStride(); final int rowPadding = rowStride - pixelStride * width; final Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); sendToServer(bitmap); image.close(); } } } };
private void sendToServer(Bitmap bitmap) { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 60, out); out.flush(); if (null == sendChannel || !sendChannel.isOpen() || !sendChannel.isActive()) { connectedToServer(); } byte[] imageData = out.toByteArray(); byte[] imageOration = new byte[]{getScreenOrigin()}; ByteBuf byteBuf = Unpooled.copiedBuffer(imageOration, imageData); sendChannel.writeAndFlush(byteBuf).sync(); out.close(); } catch (Exception ex) { ex.printStackTrace(); } }
3.具体代码上传到CSDN
///下面的是在2013年的时候写的
android实现屏幕监控 <代码下载>
1、问题1、性能问题还未解决
2、需要手机拥有ROOT权限。
3、FRAMBUFFER数据读写的需要人为配置(/fb0中数据的存储没搞太懂)
2、实现
1、android屏幕同步到电脑延迟(0.5-1秒左右)
2、屏幕横竖屏切换电脑屏幕同步切换
3、电脑屏幕全屏显示,按android屏幕显示,固定大小显示(代码中修改常量值)
3、代码(PC)
包结构
com.xiaoqiang(主程序)
com.xiaoqiang.network(图片数据网络接收)
com.xiaoqiang.network.control(控制数据网络接收)
com.xiaoqiang.old(性能提升用,暂时没有解决FRAMBUFFER数据在PC中来读取)
com.xiaoqiang.ui(UI)
//主要代码 基于java的没什么好说的,贴出解析网络数据包的
public void run() {
int i = 0;
while (isrunning) {
try {
// 获得ZIP流的ENTRY
zis.getNextEntry();
// 把ZIP流转换为图片
Image cimage = ImageIO.read(zis);
// 重试3次
if (cimage == null) {
if (i > 3) {
ASMPRINT.sysout("Recive Picture Data is NULL TO 3 Times,Stop Current Thread" + i);
this.setIsrunning(false);
} else {
ASMPRINT.sysout("Recive Picture Data is NULL" + i);
i++;
}
} else {
ASMPRINT.sysout("Recive Picture Data");
if (null != imIasMmessage) {
ASMPRINT.sysout("Notify ASMMessageEvent");
ASMMessageEvent sEvent = new ASMMessageEvent(cimage);
this.imIasMmessage.messageArrive(sEvent);
}
}
zis.closeEntry();
}
catch (IOException e) {
ASMPRINT.sysout(e.toString());
}
}
this.closeSocket();
if (null != address_port)
ASMPRINT.sysout("Client:" + address_port + "is stoped");
}
4、代码(android)
包结构(有点儿乱和有其他人做了一些)
com.xiaoqiang.old(性能提升用,暂时没有解决FRAMBUFFER数据在PC中来读取)
com.yangxbfuj.sysclient
com.yangxbfuj.syclient.network
com.yangxbfuj.syclient.sensorMgr(方向传感器)
com.yangxbfuj.sysclient.utl(root工具包)
//主要代码
1、获取FB0数据并转为bitmap
/**
* 2013-10-17 上午9:52:02 Created By niexiaoqiang
*/
package com.yangxbfuj.syclient;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
public class TakePic {
private static String Tag = "TakePic";
private int height;
private int width;
private int deepth;
/**
* 修正高度,默认为0
*/
private int mH = 0;
/**
* 修正宽度,默认为0,基本值修改宽度
*/
private int mW = 0;
public TakePic(Context context, int mH, int mW) {
this.mH = mH;
this.mW = mW;
DisplayMetrics metrics = new DisplayMetrics();
WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = WM.getDefaultDisplay();
display.getMetrics(metrics);
// 如果花屏,增加高或宽
this.height = metrics.heightPixels; // 屏幕高
this.width = metrics.widthPixels; // 屏幕的宽
// 获取显示方式
int pixelformat = display.getPixelFormat();
PixelFormat localPixelFormat1 = new PixelFormat();
PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);
this.deepth = localPixelFormat1.bytesPerPixel;// 位深
// 修正高宽
this.height = this.height + mH;
this.width = this.width + mW;
}
public Bitmap takepic(long starttime) throws Exception {
Log.i(Tag, starttime + "----开始获取/dev/graphic/fb0的数据-------");
InputStream stream = new FileInputStream(new File("/dev/graphics/fb0"));
byte[] piex = new byte[height * width * deepth];
@SuppressWarnings("resource")
DataInputStream dStream = new DataInputStream(stream);
dStream.read(piex, 0, height * width * deepth);
// 保存图片
int[] colors = new int[height * width];
for (int m = 0; m < piex.length; m++) {
if (m % 4 == 0) {
int r = (piex[m] & 0xFF);
int g = (piex[m + 1] & 0xFF);
int b = (piex[m + 2] & 0xFF);
int a = (piex[m + 3] & 0xFF);
colors[m / 4] = (a << 24) + (r << 16) + (g << 8) + b;
}
}
Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_4444);
long endtime = System.currentTimeMillis();
Log.i(Tag, endtime + "----转码完成-----耗时" + (endtime - starttime) + "毫秒------");
return bitmap;
}
}
2、压缩并网络发送
1、获取FB0数据并转为bitmap
public void run() {
long l = 0;
try {
Socket socket = new Socket(ipaddress, port);
ZipOutputStream os = null;
while (isrunning) {
byte[] buf = new byte[1024];
os = new ZipOutputStream(socket.getOutputStream());
long starttime = System.currentTimeMillis();
Log.i(Tag, starttime + "----开始获取/dev/graphic/fb0");
Bitmap bitmap = takePic.takepic(starttime);
Log.i(Tag, System.currentTimeMillis() + "----开始转码-----------");
os.setLevel(1);
ZipEntry zipEntry = new ZipEntry(l + "shotpic.jpg");
os.putNextEntry(zipEntry);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, compress, baos);
ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray());
InputStream is = new BufferedInputStream(bin);
int readLen = -1;
while ((readLen = is.read(buf, 0, 1024)) != -1) {
os.write(buf, 0, readLen);
}
is.close();
bin.close();
baos.close();
Log.i(Tag, System.currentTimeMillis() + "----发送到客户端-----------");
os.flush();
os.closeEntry();
}
Log.i(Tag, System.currentTimeMillis() + "-----断开连接-----------");
os.close();
os = null;
socket.close();
socket = null;
Log.i(Tag, System.currentTimeMillis() + "-----断开连接成功-----------");
}
catch (Exception e) {
System.out.println(e);
}
}
3、传感器数据
private static class MySensorEventListener implements SensorEventListener {
private String s_y = "0";
private String ip;
public MySensorEventListener(String ip) {
this.ip = ip;
}
@Override
public void onSensorChanged(SensorEvent event) {
int y = (int) event.values[2];
String current = null;
if (y > -10 && y < 10) {
current = "0";
} else if (y > 70 && y < 90) {
current = "3";
} else if (y >= -90 && y < -70) {
current = "1";
}
if (null != current && !current.equals(s_y)) {
s_y = current;
SendSensorDirction.sendToSever(ip, s_y);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
SendSensorDirction.sendToSever(ip, s_y);
System.out.println("init Sensor ");
}
}
全部代码过两天发到csdn资源中,到时候再贴出链接