所谓高权限就是利用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)
站点信息
- 文章2313
- 用户1336
- 访客11759589
每日一句
Happiness depends on your mindset.
幸福取决于你的心态。
幸福取决于你的心态。
新会员