所谓高权限就是利用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
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2321
- 用户1336
- 访客12138657
每日一句
Ice will melt and make way for flow.
冰会融化,为水流让路。
冰会融化,为水流让路。
OllyDbg中如何找出B模块中所有调用了A模块的C方法的地方
diskgenius 保存分区表时出现错误 代码00000032方法解决
easypoi快捷表格框架使用
Cocos2dx 3.x 解决首次项目复制库文件编译慢的问题
MPAndroidChart视图设置
Django框架最适合Web开发?
T440S完美黑苹果mac10.14.1上图求点赞!
利用Internet Download Manager下载Google云盘大文件
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
Android8.0系统中通知栏的适配