利用逆向进行同屏-Android端

原创 2018年04月16日 15:55:41

逆向同屏:

        第一步,单利模式;

private static ScreenShot instance;
private float[] dims;

static ScreenShot getInstance(Context context) {
    synchronized (ScreenShot.class) {
        if (instance == null) {
            instance = new ScreenShot();
            instance.dims = instance.getPixel(context);
        }
    }
    return instance;
}


void takeScreenshot(String host, int port) {
    try {
        Socket socket = new Socket(host, port);

        Thread send = new Thread(new SendScreenShot(socket));
        Thread receive = new Thread(new ReceiveCommand(socket));
        send.start();
        receive.start();
        send.join();
        receive.join();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

        第二步,屏幕截图;

/** 屏幕截图 */
private byte[] getBitmapByte(){
    return qualityZoom(areaZoom(screenShot((int) dims[0], (int) dims[1])));
}

/** 质量缩放 */
private byte[] qualityZoom(Bitmap bitmap) {
    Bitmap mutable = bitmap.copy(Bitmap.Config.RGB_565, true);
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    mutable.compress(Bitmap.CompressFormat.JPEG, 20, byteStream);
    return byteStream.toByteArray();
}

/** 面积缩放 */
private Bitmap areaZoom(Bitmap image) {
    Matrix matrix = new Matrix();
    matrix.setScale(0.5f, 0.5f);
    return Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);
}

private Bitmap screenShot(int width, int height) {
    try {
        return (Bitmap) getSurfaceClass().invoke(null, width, height);
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return null;
}

private Method getSurfaceClass(){
    Class<?> surfaceClass;
    Method method = null;
    try {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
            surfaceClass = Class.forName("android.view.SurfaceControl");
        } else {
            surfaceClass = Class.forName("android.view.Surface");
        }
        method = surfaceClass.getDeclaredMethod("screenshot", int.class, int.class);
        method.setAccessible(true);
    } catch (Exception e) {
        Log.e("ScreenShot", e.toString());
    }
    return method;
}

private float[] getPixel(Context context) {
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    assert wm != null;
    Display mDisplay = wm.getDefaultDisplay();
    DisplayMetrics mDisplayMetrics = new DisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        mDisplay.getRealMetrics(mDisplayMetrics);
    }
    return new float[]{
            mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels
    };
}

        第三步,进行线程实例;

private class SendScreenShot implements Runnable {
    private Socket socket;

    SendScreenShot(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
            while (socket.isConnected()) {
                byte[] img = getBitmapByte();
                byte[] byteLen = intToBytes(img.length);
                bos.write(byteLen);
                bos.write(img);
            }
            socket.close();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private class ReceiveCommand implements Runnable {
    private Socket socket;

    ReceiveCommand(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            while (socket.isConnected()) {
                byte[] byteLen = new byte[4];
                int len;
                int count = 0;
                int result;
                while ((result = bis.read(byteLen, count, 4 - count)) != -1) {
                    count += result;
                    if (count == 4) {
                        count = 0;
                        break;
                    }
                }

                len = bytesToInt(byteLen, 0);
                if (len <= 0) {
                    back();
                    continue;
                }
                byte[] coordinate = new byte[len];
                while ((result = bis.read(coordinate, count, len - count)) != -1) {
                    count += result;
                    if (count == len) {
                        break;
                    }
                }
                Point[] points = new Point[len / 8];
                for (int i = 0, l = 0; i < len; i += 4, l = i / 8) {
                    Point point = points[l];
                    if (point == null) {
                        points[l] = new Point();
                    } else {
                        point.setX(bytesToInt(coordinate, l * 8));
                        point.setY(bytesToInt(coordinate, l * 8 + 4));
                    }
                }
                executeSwipe(points);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

        第四步,传回命令执行;

private void back() {
    try {
        Instrumentation inst = new Instrumentation();
        inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void executeSwipe(Point[] points) {
    Point start = points[0];
    Point end = points[1];
    int x = (end.getX() - start.getX()) / 10;
    int y = (end.getY() - start.getY()) / 10;

    Instrumentation inst = new Instrumentation();
    long dowTime = SystemClock.uptimeMillis();
    inst.sendPointerSync(MotionEvent.obtain(dowTime, dowTime,
            MotionEvent.ACTION_DOWN, start.getX(), start.getY(), 0));
    for (int i = 0; i < 10; i++) {
        inst.sendPointerSync(MotionEvent.obtain(dowTime, dowTime + i * 10,
                MotionEvent.ACTION_MOVE, start.getX() + x * i, start.getY() + y * i, 0));
    }
    inst.sendPointerSync(MotionEvent.obtain(dowTime, dowTime + 100,
            MotionEvent.ACTION_UP, end.getX(), end.getY(), 0));
}

private class Point {
    private int x;
    private int y;

    Point() {
    }

    int getX() {
        return x;
    }

    void setX(int x) {
        this.x = x;
    }

    int getY() {
        return y;
    }

    void setY(int y) {
        this.y = y;
    }

    @Override
    public String toString() {
        return "Point{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

static byte[] intToBytes(int value) {
    byte[] des = new byte[4];
    des[0] = (byte) (value & 0xff);  // 低位(右边)的8个bit位
    des[1] = (byte) ((value >> 8) & 0xff); //第二个8 bit位
    des[2] = (byte) ((value >> 16) & 0xff); //第三个 8 bit位
    /*
     * (byte)((value >> 24) & 0xFF);
     * value向右移动24位, 然后和0xFF也就是(11111111)进行与运算
     * 在内存中生成一个与 value 同类型的值
     * 然后把这个值强制转换成byte类型, 再赋值给一个byte类型的变量 des[3]
     */
    des[3] = (byte) ((value >> 24) & 0xff); //第4个 8 bit位
    return des;
}

static int bytesToInt(byte[] des, int offset) {
    int value;
    value = des[offset] & 0xff
            | ((des[offset + 1] & 0xff) << 8)
            | ((des[offset + 2] & 0xff) << 16)
            | (des[offset + 3] & 0xff) << 24;
    return value;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alin693/article/details/79961629

数据类型及混合运算与类型转换

原文地址:http://www.cnblogs.com/corvoh/p/5141746.html 「C语言」数据类型及混合运算与类型转换     深入学习C语言时,有必要...
  • qq_33706673
  • qq_33706673
  • 2017-10-10 22:21:26
  • 226

Android-ScreenShot-Library

  • 2011年11月10日 18:19
  • 324KB
  • 下载

mqtt协议实现 Android推送(服务端、客户端代码)

  • 2016年12月05日 09:13
  • 4.52MB
  • 下载

Android端投屏demo

  • 2017年11月02日 14:51
  • 33.55MB
  • 下载

Android端控制LED屏

Android端控制LED屏,今天老师给讲了LED屏的协议,写了一个控制LED的程序,为了深入了解,我自己给代码全部加上注释。...
  • S18338378052
  • S18338378052
  • 2018-02-03 13:20:13
  • 107

EchartDemo

  • 2016年02月18日 14:53
  • 2.65MB
  • 下载

面试算法:利用堆栈计算逆向波兰表达式

给定一个四则运算表达式的字符串,如果该表达式满足逆向波兰表达式,那么该字符串要满足以下条件: 1: 该表达式含有一个数字字符或一串数字字符。 2:它拥有给定格式,如”A, B, 。“,其中A,B是...
  • tyler_download
  • tyler_download
  • 2017-02-15 11:11:32
  • 703

中文版 进入紫屏,改序列号

  • 2014年03月12日 23:44
  • 5.22MB
  • 下载

【BLE】CC2541之OLED

本文介绍如何使用oled(SSD1306)
  • feilusia
  • feilusia
  • 2015-10-03 15:23:34
  • 2690

第五届全国信息水平设计大赛C语言程序设计A卷答案

#include #include /* 1、编程实现:有二维数组a[3][3]={{5.4,3.2,8},{6,4,3.3},{7,3,1.3}}, 将数组a的每一行元素均除以该行上的主对...
  • woaifen3344
  • woaifen3344
  • 2012-10-22 22:09:41
  • 825
收藏助手
不良信息举报
您举报文章:利用逆向进行同屏-Android端
举报原因:
原因补充:

(最多只允许输入30个字)