Android高权限截图例子

Home / Android MrLee 2020-10-12 2160

所谓高权限就是利用adb shell app_process启动进程并截图,类似scrcpy。

流程如下:编写截图代码,为了方便编译,都在写一个无package的类里面。代码如下:

import android.graphics.Bitmap;
import android.os.Build;
import android.util.Base64;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
    public static void main(String[] args) {
        startServer(80);
    }
    //截屏转base64字符串
    public static String cap2base64() {
        int picWidth = 720;
        int picHeight = 1080;
        String result = "";
        String cls;
        if (Build.VERSION.SDK_INT <= 17)
            cls = "android.view.Surface";
        else
            cls = "android.view.SurfaceControl";
        try {
            Class _cls = Class.forName(cls);
            Bitmap bitmap = (Bitmap) _cls.getDeclaredMethod("screenshot", new Class[]{Integer.TYPE, Integer.TYPE})
                    .invoke(null, new Object[]{picWidth, picHeight});
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
            bos.flush();
            byte[] bitmapBytes = bos.toByteArray();
            result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }//http server
    public static String html() {
        String imgBase64 = cap2base64();
        String html = "<!DOCTYPE html>\n" +
                "<html>\n" +
                "<head>\n" +
                "<meta charset=\"utf-8\">\n" +
                "<meta http-equiv=\"Refresh\" content=\"0.1\";/>" +
                "<title>截图</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<img src=\"data:image/png;base64," + imgBase64 + "\" width=\"720\" height=\"1080\"/>" +
                "</body>\n" +
                "</html>";
        return html;
    }
    private static byte[] response() throws IOException {
        String content = html();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PrintWriter pw = new PrintWriter(out);
        pw.println("HTTP/1.1 200 OK");
        pw.println("Content-Type:text/html");
        pw.println();
        pw.println(content);
        pw.flush();
        pw.close();
        out.flush();
        byte[] data = out.toByteArray();
        out.close();
        return data;
    }
    public static void startServer(int port) {
        try {
            ServerSocket ss = new ServerSocket(port);
            while (true) {
                Socket socket = ss.accept();
                OutputStream out = socket.getOutputStream();
                synchronized (out) {
                    //只负责写到通道,不保证硬件马上写出去,所以这里wait
                    out.write(response());
                    out.flush();
                    out.wait(10);
                    out.close();
                    socket.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

写好之后,用Android Studio编译或者手动编译,并切到生成的class文件目录,执行以下命令:

#forward 转发80,执行一次即可
adb forward tcp:80 tcp:80
#切到class文件目录
cd D:\xxx\ScrApp\app\build\intermediates\javac\debug\classes
#生成dex文件
dx --dex --output=D:\Main.dex Main.class
#push到手机内存
adb push D:\Main.dex /data/local/tmp/Main.dex
#执行程序
adb shell app_process -Djava.class.path=/data/local/tmp/Main.dex /data/local/tmp Main -s

然后,在你电脑浏览器输入127.0.0.1(我用的是雷电模拟器,手机USB理论一样)就可以看到截图啦

写个批处理快速启动

adb forward tcp:80 tcp:80 & cd D:\ASProjects\ScrApp\app\build\intermediates\javac\debug\classes & dx --dex --output=D:\Main.dex Main.class & adb push D:\Main.dex /data/local/tmp/Main.dex & start http://127.0.0.1 & adb shell app_process -Djava.class.path=/data/local/tmp/Main.dex /data/local/tmp Main -s & pause


本文链接:https://www.it72.com/12662.htm

推荐阅读
最新回复 (0)
返回