Android手机监控应用(一)

16 篇文章 0 订阅
8 篇文章 0 订阅
// 客户端部分

<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Android远程控制@hexf00</title>
    <script src="{{screen_uri}}/jquery.js"></script>
    <style>
        #screen {
            position: relative;
        }
        #screen img {
            position: absolute;
            top: 0;
            left: 0;
        }
        .hide {
            width: 0;
            height: 0;
        }
        #screen2 {
            position: absolute;
        }
        #tool{
            float:left
        }
    </style>
</head>

<body onload="bodyLoad()">
    
  
    
    <div id="screen">
        <img alt="屏幕" src="{{screen_uri}}/screen">
        <img alt="屏幕" src="{{screen_uri}}/screen">
    </div>
    <div id="screen2">
    </div>

  

    <script>
        var imgSrc = "{{screen_uri}}/screen?"
        function getNext() {
            $("#screen").append('<img onload="getNext();" alt="连接已经断开请重新连接" src="' + imgSrc + new Date().getTime() +
                Math.random() + '">')
            setTimeout(() => {
                $("img")[0].remove()
            }, 500)
        }
        var bodyLoad = () => {
            $("#screen2").width($("img").width() + "px")
            $("#screen2").height($("img").height() + "px")
            getNext()
        }
        var isDown = false
        var downEvent
        $("#screen2").on("mousedown", (e) => {
            isDown = true
            downEvent = e
        })
        $("#screen2").on("mouseup", (e) => {
            isDown = false
            duration = Math.ceil(e.timeStamp - downEvent.timeStamp)
            x1 = downEvent.offsetX * 2
            y1 = downEvent.offsetY * 2
            x2 = e.offsetX * 2
            y2 = e.offsetY * 2
            $.ajax({
                url: "{{screen_uri}}/swipe",
                type: "get",
                dataType: "jsonp",
                data: {
                    duration,
                    x1,
                    y1,
                    x2,
                    y2
                }
            });
        })
    </script>
</body>

</html>
// 服务端部分

# Activity
package com.example.chinaso.appcrawlermaster;

import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.view.View;
import android.content.Intent;
import android.widget.Button;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.ServiceConnection;
import android.content.ComponentName;
import android.widget.Toast;
import android.view.WindowManager;
import android.view.KeyEvent;
import android.util.DisplayMetrics;
import android.media.projection.MediaProjectionManager;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.os.Build;
import java.net.*;
import java.util.*;

public class MainActivity extends Activity {
    private Intent broadcast_intent = null;
    private String local_ip;

    // 与service通信有关
    private Intent service_intent = null;
    HttpServiceConn http_service_conn;
    HttpService.ServiceBinder binder = null;

    // 与截屏有关
    private static final int REQUEST_MEDIA_PROJECTION = 1;
    private int mScreenDensity;
    private int mResultCode;
    private int screen_width;
    private int screen_height;
    private Intent mResultData;
    private MediaProjectionManager mMediaProjectionManager;
    private boolean is_started_service = false;

    // 与无障碍有关
    private Vector<SwipeCommand> action_queue = new Vector<>();
    private NotificationManager notification_manager = null;
    NotificationCompat.Builder builder = null;
    NotificationChannel channel = null;

    // 无障碍动作执行线程
    public class ActionThread extends Thread {
        private int sleep_time;
        private boolean is_running = true;
        public ActionThread(int sleep_time) {
            this.sleep_time = sleep_time;
        }

        @Override
        public void run() {
            try {
                while(is_running) {
                    if (action_queue.size() > 0) {
                        SwipeCommand cmd = action_queue.remove(0);
                        BarrierFreeService.setCurrentCommand(cmd);
                        System.out.println("线程正在执行滑动命令: " + cmd.getDuration());
                        cmd = null;
                        notification_manager.notify(1, builder.build());
                        sleep(20);
                        notification_manager.cancel(1);
                    }
                    sleep(sleep_time);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void exit(boolean is_running) {
            this.is_running = is_running;
        }
    }
    ActionThread action_thread = null;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        local_ip = getIP();

        notification_manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        getNotificationBuilder();
        getNotificationChannel();
        action_thread = new ActionThread(50);
        action_thread.start();

        initScreenCapture();
        mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        if (is_started_service == false) {
            startActivityForResult(
                    mMediaProjectionManager.createScreenCaptureIntent(),
                    REQUEST_MEDIA_PROJECTION);
            is_started_service = true;
        }
        setOnClick();
        initBroadCastIntent();
    }

    // 初始化截屏
    public void initScreenCapture() {
        WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        //wm.getDefaultDisplay().getMetrics(metrics);
        wm.getDefaultDisplay().getRealMetrics(metrics);
        System.out.println("手机物理宽高: " + metrics.widthPixels + ", " + metrics.heightPixels);
        screen_width = metrics.widthPixels;
        screen_height = metrics.heightPixels;
        mScreenDensity = metrics.densityDpi;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_MEDIA_PROJECTION) {
            if (resultCode != Activity.RESULT_OK) {
                Toast.makeText(MainActivity.this, "user cancelled", Toast.LENGTH_SHORT).show();
                return;
            }
            mResultCode = resultCode;
            mResultData = data;
            service_intent = new Intent(this, HttpService.class);
            service_intent.putExtra("screen_density", mScreenDensity);
            service_intent.putExtra("screen_width", screen_width);
            service_intent.putExtra("screen_height", screen_height);
            service_intent.putExtra("result_code", mResultCode);
            System.out.println("Activity屏幕宽高: " + screen_width + ", " + screen_height);
            // 启动 http service
            startService(service_intent);

            // 绑定 http service
            http_service_conn = new HttpServiceConn();
            Intent bind_intent = new Intent(this, HttpService.class);
            bindService(bind_intent, http_service_conn, Context.BIND_AUTO_CREATE);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        action_thread.exit(false);
        // 解绑Service
        if (binder != null) {
            unbindService(http_service_conn);
            stopService(service_intent);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode==KeyEvent.KEYCODE_BACK){
            moveTaskToBack(true);
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }

    // 与service绑定绑定相关类
    class HttpServiceConn implements ServiceConnection {

        // 服务被绑定成功之后执行
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // IBinder service为onBind方法返回的Service实例
            binder = (HttpService.ServiceBinder) service;
            if (binder != null) {
                System.out.println("binder不空!");
            }
            binder.setScreenCaptureIntent(mResultData);
            binder.getService().setCallback(new HttpService.Callback() {
                @Override
                public void dispatchCommand(Command cmd) {
                    Message msg = new Message();
                    Bundle bundle = new Bundle();
                    SwipeCommand real_cmd = (SwipeCommand)cmd;
                    bundle.putString("tag", "swipe");
                    bundle.putInt("x1", real_cmd.getUpLeftX());
                    bundle.putInt("y1", real_cmd.getUpLeftY());
                    bundle.putInt("x2", real_cmd.getDownRightX());
                    bundle.putInt("y2", real_cmd.getDownRightY());
                    bundle.putInt("duration", real_cmd.getDuration());
                    msg.setData(bundle);
                    //发送通知
                    handler.sendMessage(msg);
                }
            });
        }

        @SuppressLint("HandlerLeak")
        Handler handler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                Bundle bundle = msg.getData();
                SwipeCommand cmd = null;
                switch (bundle.getString("tag")) {
                    case "swipe":
                        int x1 = bundle.getInt("x1");
                        int y1 = bundle.getInt("y1");
                        int x2 = bundle.getInt("x2");
                        int y2 = bundle.getInt("y2");
                        int duration = bundle.getInt("duration");
                        cmd = new SwipeCommand("swipe", x1, y1, x2, y2, duration);
                        System.out.println("发送滑动命令到线程: " + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ", " + duration);
                        action_queue.add(cmd);
                        break;
                }
            }
        };

        // 服务奔溃或者被杀掉执行
        @Override
        public void onServiceDisconnected(ComponentName name) {
            binder = null;
        }
    }

    // 获取本机IP地址
    public String getIP(){
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address)) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (SocketException ex){
            ex.printStackTrace();
        }
        return null;
    }

    // 初始化广播Intent
    public void initBroadCastIntent() {
        broadcast_intent = new Intent();
        broadcast_intent.setAction("aaa");
        // 突破 Android 7.0/8.0 中的隐式广播限制
        broadcast_intent.addFlags(0x01000000);
    }

    // 广播自定义意图
    public void broadcastIntent() {
        sendBroadcast(broadcast_intent);
        broadcast_intent.removeExtra("msg");
    }

    // 生成通知渠道
    public void getNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    "com.chinaso.AppCrawlerMaster",
                    "app-crawler-client",
                    NotificationManager.IMPORTANCE_DEFAULT

            );
            notification_manager.createNotificationChannel(channel);
        }
    }

    // 生成通知创建者
    public void getNotificationBuilder() {
        builder = new NotificationCompat.Builder(getBaseContext(), "com.chinaso.AppCrawlerMaster")
                .setContentTitle("app-crawler-client")
                .setAutoCancel(true)
                .setTimeoutAfter(100)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.ic_launcher_foreground);
    }

    // 为按钮绑定监听器
    public void setOnClick() {
        Button button_broadcast = findViewById(R.id.button_broadcast);
        button_broadcast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                broadcast_intent.putExtra("msg", "hello world");
                broadcastIntent();
            }
        });

        Button button_get_ip = findViewById(R.id.button_get_ip);
        button_get_ip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String ip;
                ip = getIP();
                Toast.makeText(MainActivity.this, "本机ip是: " + ip, Toast.LENGTH_LONG).show();
            }
        });

        Button button_start_service = findViewById(R.id.button_start_service);
        button_start_service.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startIntent = new Intent(MainActivity.this, HttpService.class);
                startService(startIntent);
            }
        });

        Button button_stop_service = findViewById(R.id.button_stop_service);
        button_stop_service.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent stopIntent = new Intent(MainActivity.this, HttpService.class);
                stopService(stopIntent);
            }
        });

        Button notification_send_service = findViewById(R.id.button_send_notification);
        notification_send_service.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //notification_manager.notify(1, builder.build());
            }
        });
    }
}
// 命令基类Bean

package com.example.chinaso.appcrawlermaster;

public class Command {
    private String tag = null;
    private String response = null;
    private int id = 0;

    public Command(String tag) {
        this.tag = tag;
    }

    public String getTag() {
        return this.tag;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getResponse() {
        return response;
    }

    public void setResponse(String response) {
        this.response = response;
    }
}
// 截屏命令Bean

package com.example.chinaso.appcrawlermaster;

class ScreenCommand extends Command {
    private byte[] bytes = null;
    public ScreenCommand(String tag) {
        super(tag);
    }

    public void setBytes(byte[] b) {
        this.bytes = b;
    }

    public byte[] getBytes() {
        return bytes;
    }
}
// 滑动命令Bean

package com.example.chinaso.appcrawlermaster;

class SwipeCommand extends Command {

    private int x1;
    private int y1;
    private int x2;
    private int y2;
    private int duration;

    public SwipeCommand(String tag, int x1, int y1, int x2, int y2, int duration) {
        super(tag);
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.duration = duration;
    }

    public int getUpLeftX() {
        return x1;
    }
    public void setUpLeftX(int x1) {
        this.x1 = x1;
    }

    public int getUpLeftY() {
        return y1;
    }
    public void setUpLeftY(int y1) {
        this.y1 = y1;
    }

    public int getDownRightX() {
        return x2;
    }
    public void setDownRightX(int x2) {
        this.x2 = x2;
    }

    public int getDownRightY() {
        return y2;
    }
    public void setDownRightY(int y2) {
        this.y2 = y2;
    }

    public int getDuration() {
        return duration;
    }
    public void setDuration(int duration) {
        this.duration = duration;
    }

}
// http服务器

package com.example.chinaso.appcrawlermaster;

import java.util.*;
import java.io.IOException;
import org.nanohttpd.protocols.http.NanoHTTPD;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.IHTTPSession;
import org.nanohttpd.protocols.http.response.Status;


import java.net.ServerSocket;

public class HttpServer extends NanoHTTPD {

    private static final String TAG = "Http";
    private static int command_id = 0;
    private static int wait_res_sleep_time = 1;
    private HttpService http_service;

    public HttpServer(String host, int port) {
        super(host, port);
    }

    @Override
    public ServerSocket getMyServerSocket() {
        return super.getMyServerSocket();
    }

    @Override
    public Response serve(IHTTPSession session) {
        try {
            // 这句必须有,否则获取不到数据
            session.parseBody(new HashMap<String, String>());
        } catch (IOException e) {
            System.out.println("HttpServer IOException");
            e.printStackTrace();
        } catch (ResponseException e) {
            System.out.println("HttpServer ResponseException");
            e.printStackTrace();
        }
        Response response = null;

        String uri = session.getUri();
        System.out.println("Uri is: " + uri);
        // 获取当前命令标识
        int id = updateId();
        Command cmd;
        String miniType = null;
        if (uri.equals("/screen")) {
            // 截图
            cmd = new ScreenCommand("screen");
            cmd.setId(id);
            miniType = "image/jpeg";
        } else if (uri.equals("/swipe")) {
            // 滑动
            Map<String, List<String>> params = session.getParameters();
            int x1 = Integer.parseInt(params.get("x1").get(0));
            int y1 = Integer.parseInt(params.get("y1").get(0));
            int x2 = Integer.parseInt(params.get("x2").get(0));
            int y2 = Integer.parseInt(params.get("y2").get(0));
            int duration = Integer.parseInt(params.get("duration").get(0));
            cmd = new SwipeCommand("swipe", x1, y1, x2, y2, duration);
            cmd.setResponse("200");
            cmd.setId(id);
            System.out.println("滑动参数: " + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ", " + duration);
        } else if (uri.equals("/jquery.js")) {
            cmd = new Command("jquery.js");
            cmd.setId(id);
            miniType = "application/x-javascript";
        } else {
            cmd = new Command("remote.html");
            cmd.setId(id);
            miniType = "text/html";
        }
        // 将命令加入命令接收队列
        http_service.addCommand(cmd);

        // 等待命令执行结果
        if (cmd.getTag() != "screen") {
            while(cmd.getResponse() == null) {
                try{
                    Thread.sleep(wait_res_sleep_time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            ScreenCommand screen_cmd = (ScreenCommand)cmd;
            while(screen_cmd.getBytes() == null) {
                try{
                    Thread.sleep(wait_res_sleep_time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            screen_cmd = null;
        }

        if (cmd.getTag() != "screen") {
            System.out.println("响应长度: " + cmd.getResponse().length());
            response = Response.newFixedLengthResponse(cmd.getResponse());
        } else {
            ScreenCommand screen_cmd = (ScreenCommand)cmd;
            System.out.println("响应长度: " + screen_cmd.getBytes().length);
            response = Response.newFixedLengthResponse(Status.OK, "image/jpeg", screen_cmd.getBytes());
            screen_cmd = null;
        }
        response.setMimeType(miniType);

        http_service.removeCommand(cmd);
        return response;

        //Map<String, List<String>> params = session.getParameters();
        // 获取发送数据时的key
        //String data = params.get("json").get(0);
        //data_list.add(data);
        //System.out.println("接收的数据为: " + data);
        //return Response.newFixedLengthResponse(data);
    }

    public void registerService(HttpService http_service) {
        this.http_service = http_service;
    }

    public synchronized int updateId() {
        command_id++;
        return command_id;
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值