当前位置:   article > 正文

Android手机监控应用(一)_android 视图逻辑监控

android 视图逻辑监控
  1. // 客户端部分
  2. <!DOCTYPE html>
  3. <html lang="zh-cn">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8. <title>Android远程控制@hexf00</title>
  9. <script src="{{screen_uri}}/jquery.js"></script>
  10. <style>
  11. #screen {
  12. position: relative;
  13. }
  14. #screen img {
  15. position: absolute;
  16. top: 0;
  17. left: 0;
  18. }
  19. .hide {
  20. width: 0;
  21. height: 0;
  22. }
  23. #screen2 {
  24. position: absolute;
  25. }
  26. #tool{
  27. float:left
  28. }
  29. </style>
  30. </head>
  31. <body onload="bodyLoad()">
  32. <div id="screen">
  33. <img alt="屏幕" src="{{screen_uri}}/screen">
  34. <img alt="屏幕" src="{{screen_uri}}/screen">
  35. </div>
  36. <div id="screen2">
  37. </div>
  38. <script>
  39. var imgSrc = "{{screen_uri}}/screen?"
  40. function getNext() {
  41. $("#screen").append('<img onload="getNext();" alt="连接已经断开请重新连接" src="' + imgSrc + new Date().getTime() +
  42. Math.random() + '">')
  43. setTimeout(() => {
  44. $("img")[0].remove()
  45. }, 500)
  46. }
  47. var bodyLoad = () => {
  48. $("#screen2").width($("img").width() + "px")
  49. $("#screen2").height($("img").height() + "px")
  50. getNext()
  51. }
  52. var isDown = false
  53. var downEvent
  54. $("#screen2").on("mousedown", (e) => {
  55. isDown = true
  56. downEvent = e
  57. })
  58. $("#screen2").on("mouseup", (e) => {
  59. isDown = false
  60. duration = Math.ceil(e.timeStamp - downEvent.timeStamp)
  61. x1 = downEvent.offsetX * 2
  62. y1 = downEvent.offsetY * 2
  63. x2 = e.offsetX * 2
  64. y2 = e.offsetY * 2
  65. $.ajax({
  66. url: "{{screen_uri}}/swipe",
  67. type: "get",
  68. dataType: "jsonp",
  69. data: {
  70. duration,
  71. x1,
  72. y1,
  73. x2,
  74. y2
  75. }
  76. });
  77. })
  78. </script>
  79. </body>
  80. </html>
  1. // 服务端部分
  2. # Activity
  3. package com.example.chinaso.appcrawlermaster;
  4. import android.app.Activity;
  5. import android.os.Bundle;
  6. import android.os.IBinder;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.support.v4.app.NotificationCompat;
  10. import android.view.View;
  11. import android.content.Intent;
  12. import android.widget.Button;
  13. import android.annotation.SuppressLint;
  14. import android.content.Context;
  15. import android.content.ServiceConnection;
  16. import android.content.ComponentName;
  17. import android.widget.Toast;
  18. import android.view.WindowManager;
  19. import android.view.KeyEvent;
  20. import android.util.DisplayMetrics;
  21. import android.media.projection.MediaProjectionManager;
  22. import android.app.NotificationManager;
  23. import android.app.NotificationChannel;
  24. import android.os.Build;
  25. import java.net.*;
  26. import java.util.*;
  27. public class MainActivity extends Activity {
  28. private Intent broadcast_intent = null;
  29. private String local_ip;
  30. // 与service通信有关
  31. private Intent service_intent = null;
  32. HttpServiceConn http_service_conn;
  33. HttpService.ServiceBinder binder = null;
  34. // 与截屏有关
  35. private static final int REQUEST_MEDIA_PROJECTION = 1;
  36. private int mScreenDensity;
  37. private int mResultCode;
  38. private int screen_width;
  39. private int screen_height;
  40. private Intent mResultData;
  41. private MediaProjectionManager mMediaProjectionManager;
  42. private boolean is_started_service = false;
  43. // 与无障碍有关
  44. private Vector<SwipeCommand> action_queue = new Vector<>();
  45. private NotificationManager notification_manager = null;
  46. NotificationCompat.Builder builder = null;
  47. NotificationChannel channel = null;
  48. // 无障碍动作执行线程
  49. public class ActionThread extends Thread {
  50. private int sleep_time;
  51. private boolean is_running = true;
  52. public ActionThread(int sleep_time) {
  53. this.sleep_time = sleep_time;
  54. }
  55. @Override
  56. public void run() {
  57. try {
  58. while(is_running) {
  59. if (action_queue.size() > 0) {
  60. SwipeCommand cmd = action_queue.remove(0);
  61. BarrierFreeService.setCurrentCommand(cmd);
  62. System.out.println("线程正在执行滑动命令: " + cmd.getDuration());
  63. cmd = null;
  64. notification_manager.notify(1, builder.build());
  65. sleep(20);
  66. notification_manager.cancel(1);
  67. }
  68. sleep(sleep_time);
  69. }
  70. } catch (InterruptedException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. public void exit(boolean is_running) {
  75. this.is_running = is_running;
  76. }
  77. }
  78. ActionThread action_thread = null;
  79. @Override
  80. protected void onCreate(Bundle savedInstanceState) {
  81. super.onCreate(savedInstanceState);
  82. setContentView(R.layout.activity_main);
  83. local_ip = getIP();
  84. notification_manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
  85. getNotificationBuilder();
  86. getNotificationChannel();
  87. action_thread = new ActionThread(50);
  88. action_thread.start();
  89. initScreenCapture();
  90. mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
  91. if (is_started_service == false) {
  92. startActivityForResult(
  93. mMediaProjectionManager.createScreenCaptureIntent(),
  94. REQUEST_MEDIA_PROJECTION);
  95. is_started_service = true;
  96. }
  97. setOnClick();
  98. initBroadCastIntent();
  99. }
  100. // 初始化截屏
  101. public void initScreenCapture() {
  102. WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
  103. DisplayMetrics metrics = new DisplayMetrics();
  104. //wm.getDefaultDisplay().getMetrics(metrics);
  105. wm.getDefaultDisplay().getRealMetrics(metrics);
  106. System.out.println("手机物理宽高: " + metrics.widthPixels + ", " + metrics.heightPixels);
  107. screen_width = metrics.widthPixels;
  108. screen_height = metrics.heightPixels;
  109. mScreenDensity = metrics.densityDpi;
  110. }
  111. @Override
  112. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  113. if (requestCode == REQUEST_MEDIA_PROJECTION) {
  114. if (resultCode != Activity.RESULT_OK) {
  115. Toast.makeText(MainActivity.this, "user cancelled", Toast.LENGTH_SHORT).show();
  116. return;
  117. }
  118. mResultCode = resultCode;
  119. mResultData = data;
  120. service_intent = new Intent(this, HttpService.class);
  121. service_intent.putExtra("screen_density", mScreenDensity);
  122. service_intent.putExtra("screen_width", screen_width);
  123. service_intent.putExtra("screen_height", screen_height);
  124. service_intent.putExtra("result_code", mResultCode);
  125. System.out.println("Activity屏幕宽高: " + screen_width + ", " + screen_height);
  126. // 启动 http service
  127. startService(service_intent);
  128. // 绑定 http service
  129. http_service_conn = new HttpServiceConn();
  130. Intent bind_intent = new Intent(this, HttpService.class);
  131. bindService(bind_intent, http_service_conn, Context.BIND_AUTO_CREATE);
  132. }
  133. }
  134. @Override
  135. public void onDestroy() {
  136. super.onDestroy();
  137. action_thread.exit(false);
  138. // 解绑Service
  139. if (binder != null) {
  140. unbindService(http_service_conn);
  141. stopService(service_intent);
  142. }
  143. }
  144. @Override
  145. public boolean onKeyDown(int keyCode, KeyEvent event) {
  146. if (keyCode==KeyEvent.KEYCODE_BACK){
  147. moveTaskToBack(true);
  148. return false;
  149. }
  150. return super.onKeyDown(keyCode, event);
  151. }
  152. // 与service绑定绑定相关类
  153. class HttpServiceConn implements ServiceConnection {
  154. // 服务被绑定成功之后执行
  155. @Override
  156. public void onServiceConnected(ComponentName name, IBinder service) {
  157. // IBinder service为onBind方法返回的Service实例
  158. binder = (HttpService.ServiceBinder) service;
  159. if (binder != null) {
  160. System.out.println("binder不空!");
  161. }
  162. binder.setScreenCaptureIntent(mResultData);
  163. binder.getService().setCallback(new HttpService.Callback() {
  164. @Override
  165. public void dispatchCommand(Command cmd) {
  166. Message msg = new Message();
  167. Bundle bundle = new Bundle();
  168. SwipeCommand real_cmd = (SwipeCommand)cmd;
  169. bundle.putString("tag", "swipe");
  170. bundle.putInt("x1", real_cmd.getUpLeftX());
  171. bundle.putInt("y1", real_cmd.getUpLeftY());
  172. bundle.putInt("x2", real_cmd.getDownRightX());
  173. bundle.putInt("y2", real_cmd.getDownRightY());
  174. bundle.putInt("duration", real_cmd.getDuration());
  175. msg.setData(bundle);
  176. //发送通知
  177. handler.sendMessage(msg);
  178. }
  179. });
  180. }
  181. @SuppressLint("HandlerLeak")
  182. Handler handler = new Handler() {
  183. public void handleMessage(android.os.Message msg) {
  184. Bundle bundle = msg.getData();
  185. SwipeCommand cmd = null;
  186. switch (bundle.getString("tag")) {
  187. case "swipe":
  188. int x1 = bundle.getInt("x1");
  189. int y1 = bundle.getInt("y1");
  190. int x2 = bundle.getInt("x2");
  191. int y2 = bundle.getInt("y2");
  192. int duration = bundle.getInt("duration");
  193. cmd = new SwipeCommand("swipe", x1, y1, x2, y2, duration);
  194. System.out.println("发送滑动命令到线程: " + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ", " + duration);
  195. action_queue.add(cmd);
  196. break;
  197. }
  198. }
  199. };
  200. // 服务奔溃或者被杀掉执行
  201. @Override
  202. public void onServiceDisconnected(ComponentName name) {
  203. binder = null;
  204. }
  205. }
  206. // 获取本机IP地址
  207. public String getIP(){
  208. try {
  209. for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
  210. NetworkInterface intf = en.nextElement();
  211. for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
  212. InetAddress inetAddress = enumIpAddr.nextElement();
  213. if (!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address)) {
  214. return inetAddress.getHostAddress().toString();
  215. }
  216. }
  217. }
  218. } catch (SocketException ex){
  219. ex.printStackTrace();
  220. }
  221. return null;
  222. }
  223. // 初始化广播Intent
  224. public void initBroadCastIntent() {
  225. broadcast_intent = new Intent();
  226. broadcast_intent.setAction("aaa");
  227. // 突破 Android 7.0/8.0 中的隐式广播限制
  228. broadcast_intent.addFlags(0x01000000);
  229. }
  230. // 广播自定义意图
  231. public void broadcastIntent() {
  232. sendBroadcast(broadcast_intent);
  233. broadcast_intent.removeExtra("msg");
  234. }
  235. // 生成通知渠道
  236. public void getNotificationChannel() {
  237. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  238. NotificationChannel channel = new NotificationChannel(
  239. "com.chinaso.AppCrawlerMaster",
  240. "app-crawler-client",
  241. NotificationManager.IMPORTANCE_DEFAULT
  242. );
  243. notification_manager.createNotificationChannel(channel);
  244. }
  245. }
  246. // 生成通知创建者
  247. public void getNotificationBuilder() {
  248. builder = new NotificationCompat.Builder(getBaseContext(), "com.chinaso.AppCrawlerMaster")
  249. .setContentTitle("app-crawler-client")
  250. .setAutoCancel(true)
  251. .setTimeoutAfter(100)
  252. .setWhen(System.currentTimeMillis())
  253. .setSmallIcon(R.drawable.ic_launcher_foreground);
  254. }
  255. // 为按钮绑定监听器
  256. public void setOnClick() {
  257. Button button_broadcast = findViewById(R.id.button_broadcast);
  258. button_broadcast.setOnClickListener(new View.OnClickListener() {
  259. @Override
  260. public void onClick(View v) {
  261. broadcast_intent.putExtra("msg", "hello world");
  262. broadcastIntent();
  263. }
  264. });
  265. Button button_get_ip = findViewById(R.id.button_get_ip);
  266. button_get_ip.setOnClickListener(new View.OnClickListener() {
  267. @Override
  268. public void onClick(View v) {
  269. String ip;
  270. ip = getIP();
  271. Toast.makeText(MainActivity.this, "本机ip是: " + ip, Toast.LENGTH_LONG).show();
  272. }
  273. });
  274. Button button_start_service = findViewById(R.id.button_start_service);
  275. button_start_service.setOnClickListener(new View.OnClickListener() {
  276. @Override
  277. public void onClick(View v) {
  278. Intent startIntent = new Intent(MainActivity.this, HttpService.class);
  279. startService(startIntent);
  280. }
  281. });
  282. Button button_stop_service = findViewById(R.id.button_stop_service);
  283. button_stop_service.setOnClickListener(new View.OnClickListener() {
  284. @Override
  285. public void onClick(View v) {
  286. Intent stopIntent = new Intent(MainActivity.this, HttpService.class);
  287. stopService(stopIntent);
  288. }
  289. });
  290. Button notification_send_service = findViewById(R.id.button_send_notification);
  291. notification_send_service.setOnClickListener(new View.OnClickListener() {
  292. @Override
  293. public void onClick(View v) {
  294. //notification_manager.notify(1, builder.build());
  295. }
  296. });
  297. }
  298. }
  1. // 命令基类Bean
  2. package com.example.chinaso.appcrawlermaster;
  3. public class Command {
  4. private String tag = null;
  5. private String response = null;
  6. private int id = 0;
  7. public Command(String tag) {
  8. this.tag = tag;
  9. }
  10. public String getTag() {
  11. return this.tag;
  12. }
  13. public int getId() {
  14. return id;
  15. }
  16. public void setId(int id) {
  17. this.id = id;
  18. }
  19. public String getResponse() {
  20. return response;
  21. }
  22. public void setResponse(String response) {
  23. this.response = response;
  24. }
  25. }
  1. // 截屏命令Bean
  2. package com.example.chinaso.appcrawlermaster;
  3. class ScreenCommand extends Command {
  4. private byte[] bytes = null;
  5. public ScreenCommand(String tag) {
  6. super(tag);
  7. }
  8. public void setBytes(byte[] b) {
  9. this.bytes = b;
  10. }
  11. public byte[] getBytes() {
  12. return bytes;
  13. }
  14. }
  1. // 滑动命令Bean
  2. package com.example.chinaso.appcrawlermaster;
  3. class SwipeCommand extends Command {
  4. private int x1;
  5. private int y1;
  6. private int x2;
  7. private int y2;
  8. private int duration;
  9. public SwipeCommand(String tag, int x1, int y1, int x2, int y2, int duration) {
  10. super(tag);
  11. this.x1 = x1;
  12. this.y1 = y1;
  13. this.x2 = x2;
  14. this.y2 = y2;
  15. this.duration = duration;
  16. }
  17. public int getUpLeftX() {
  18. return x1;
  19. }
  20. public void setUpLeftX(int x1) {
  21. this.x1 = x1;
  22. }
  23. public int getUpLeftY() {
  24. return y1;
  25. }
  26. public void setUpLeftY(int y1) {
  27. this.y1 = y1;
  28. }
  29. public int getDownRightX() {
  30. return x2;
  31. }
  32. public void setDownRightX(int x2) {
  33. this.x2 = x2;
  34. }
  35. public int getDownRightY() {
  36. return y2;
  37. }
  38. public void setDownRightY(int y2) {
  39. this.y2 = y2;
  40. }
  41. public int getDuration() {
  42. return duration;
  43. }
  44. public void setDuration(int duration) {
  45. this.duration = duration;
  46. }
  47. }
  1. // http服务器
  2. package com.example.chinaso.appcrawlermaster;
  3. import java.util.*;
  4. import java.io.IOException;
  5. import org.nanohttpd.protocols.http.NanoHTTPD;
  6. import org.nanohttpd.protocols.http.response.Response;
  7. import org.nanohttpd.protocols.http.IHTTPSession;
  8. import org.nanohttpd.protocols.http.response.Status;
  9. import java.net.ServerSocket;
  10. public class HttpServer extends NanoHTTPD {
  11. private static final String TAG = "Http";
  12. private static int command_id = 0;
  13. private static int wait_res_sleep_time = 1;
  14. private HttpService http_service;
  15. public HttpServer(String host, int port) {
  16. super(host, port);
  17. }
  18. @Override
  19. public ServerSocket getMyServerSocket() {
  20. return super.getMyServerSocket();
  21. }
  22. @Override
  23. public Response serve(IHTTPSession session) {
  24. try {
  25. // 这句必须有,否则获取不到数据
  26. session.parseBody(new HashMap<String, String>());
  27. } catch (IOException e) {
  28. System.out.println("HttpServer IOException");
  29. e.printStackTrace();
  30. } catch (ResponseException e) {
  31. System.out.println("HttpServer ResponseException");
  32. e.printStackTrace();
  33. }
  34. Response response = null;
  35. String uri = session.getUri();
  36. System.out.println("Uri is: " + uri);
  37. // 获取当前命令标识
  38. int id = updateId();
  39. Command cmd;
  40. String miniType = null;
  41. if (uri.equals("/screen")) {
  42. // 截图
  43. cmd = new ScreenCommand("screen");
  44. cmd.setId(id);
  45. miniType = "image/jpeg";
  46. } else if (uri.equals("/swipe")) {
  47. // 滑动
  48. Map<String, List<String>> params = session.getParameters();
  49. int x1 = Integer.parseInt(params.get("x1").get(0));
  50. int y1 = Integer.parseInt(params.get("y1").get(0));
  51. int x2 = Integer.parseInt(params.get("x2").get(0));
  52. int y2 = Integer.parseInt(params.get("y2").get(0));
  53. int duration = Integer.parseInt(params.get("duration").get(0));
  54. cmd = new SwipeCommand("swipe", x1, y1, x2, y2, duration);
  55. cmd.setResponse("200");
  56. cmd.setId(id);
  57. System.out.println("滑动参数: " + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ", " + duration);
  58. } else if (uri.equals("/jquery.js")) {
  59. cmd = new Command("jquery.js");
  60. cmd.setId(id);
  61. miniType = "application/x-javascript";
  62. } else {
  63. cmd = new Command("remote.html");
  64. cmd.setId(id);
  65. miniType = "text/html";
  66. }
  67. // 将命令加入命令接收队列
  68. http_service.addCommand(cmd);
  69. // 等待命令执行结果
  70. if (cmd.getTag() != "screen") {
  71. while(cmd.getResponse() == null) {
  72. try{
  73. Thread.sleep(wait_res_sleep_time);
  74. } catch (InterruptedException e) {
  75. e.printStackTrace();
  76. }
  77. }
  78. } else {
  79. ScreenCommand screen_cmd = (ScreenCommand)cmd;
  80. while(screen_cmd.getBytes() == null) {
  81. try{
  82. Thread.sleep(wait_res_sleep_time);
  83. } catch (InterruptedException e) {
  84. e.printStackTrace();
  85. }
  86. }
  87. screen_cmd = null;
  88. }
  89. if (cmd.getTag() != "screen") {
  90. System.out.println("响应长度: " + cmd.getResponse().length());
  91. response = Response.newFixedLengthResponse(cmd.getResponse());
  92. } else {
  93. ScreenCommand screen_cmd = (ScreenCommand)cmd;
  94. System.out.println("响应长度: " + screen_cmd.getBytes().length);
  95. response = Response.newFixedLengthResponse(Status.OK, "image/jpeg", screen_cmd.getBytes());
  96. screen_cmd = null;
  97. }
  98. response.setMimeType(miniType);
  99. http_service.removeCommand(cmd);
  100. return response;
  101. //Map<String, List<String>> params = session.getParameters();
  102. // 获取发送数据时的key
  103. //String data = params.get("json").get(0);
  104. //data_list.add(data);
  105. //System.out.println("接收的数据为: " + data);
  106. //return Response.newFixedLengthResponse(data);
  107. }
  108. public void registerService(HttpService http_service) {
  109. this.http_service = http_service;
  110. }
  111. public synchronized int updateId() {
  112. command_id++;
  113. return command_id;
  114. }
  115. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/341348
推荐阅读
相关标签
  

闽ICP备14008679号