最近因为手里有了一批主板机,没得屏幕,也没有usb线插口,难以操作,于是开始做了一款基于mediaprojection和无障碍服务的手机群控软件,效果如下:

基于mediaprojection和无障碍服务的群控软件

软件分为三个部分:mediaprojection和无障碍的手机界面操作功能,socket网络通信的数据传输功能和电脑端的管理程序。
因为使用socket通信,不需要使用usb连接,所以手机只需要主板就能够工作,但一些功能是用不了的。

这里首先介绍socket网络通信部分,这也是软件工作的核心,也因为这一部分是传递信息的关键,socket工作不正常的话很容易导致失联,所以异常处理很重要,因为是在无屏幕下工作,稳定性完全是看socket工作情况的。socket这部分是重写了2遍,调试过程也几经波折,但好在最后稳定下来了,以下是socket这一块的代码。其中大部分为异常处理代码,实际工作代码其实就是接受和发送。

public class socket1 {Socket socket = null;String ipadress;int port;public ImageReader imreader;public int mWidth= 1920;public int mHeight= 1080;int widt=480;int hig=270;public String szImei;public int quality=50;public String tp;public float scale=0.25f;public boolean init(String ipadress,int port,String szImei0,String tp){this.tp=tp;this.ipadress=ipadress;this.port=port;try {this.szImei=szImei0;if(this.szImei==null){Random rand=new Random();int randint=rand.nextInt(1000)+1;this.szImei = "35" + //we make this look like a valid IMEIBuild.BOARD.length()%10 +Build.BRAND.length()%10 +Build.CPU_ABI.length()%10 +randint+Build.DEVICE.length()%10 +Build.DISPLAY.length()%10 +Build.HOST.length()%10 +randint;}if(this.szImei.equals("null")){Random rand=new Random();int randint=rand.nextInt(1000)+1;this.szImei = "35" + //we make this look like a valid IMEIBuild.BOARD.length()%10 +Build.BRAND.length()%10 +Build.CPU_ABI.length()%10 +randint+Build.DEVICE.length()%10 +Build.DISPLAY.length()%10 +Build.HOST.length()%10 +randint;}Log.wtf("socket4", Thread.currentThread().getName()+port+"初始化端口");socket = new Socket(ipadress, port);socket.setKeepAlive(true);Log.wtf("socket5", Thread.currentThread().getName()+port+"初始化成功");return true;} catch (IOException e) {Log.wtf("socket6 ",Thread.currentThread().getName()+port+e);return false;}// 判断客户端和服务器是否连接成功}public boolean init(String ipadress,int port){this.ipadress=ipadress;this.port=port;try {Log.wtf("socket4", Thread.currentThread().getName()+port+"初始化端口");socket = new Socket(ipadress, port);socket.setKeepAlive(true);Log.wtf("socket5", Thread.currentThread().getName()+port+"初始化成功");return true;} catch (IOException e) {Log.wtf("socket6 ",Thread.currentThread().getName()+port+e);return false;}// 判断客户端和服务器是否连接成功}//链接服务器端的代码public boolean reconnect(){try {if(socket!=null){socket.close();}Log.wtf("socket", this.szImei+":"+port+"重新连接");Log.wtf("socket",this.szImei+":"+ipadress+":"+port);TestService.intero=true;if(tp.equals("click")){mysql.Send_log(TestService.user,szImei,tp+"reconnect");while(TestService.intero){mysql.Send_log(TestService.user,szImei,tp+"reconnection interupted 3");Thread.sleep(15000);}}while(mysql.get_socket_flag(TestService.user)==0){mysql.Send_log(TestService.user,szImei,tp+"reconnection interupted 3");if(mWidth<mHeight){InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);}int nowtime=0;while(true){if(nowtime>=60){break;}nowtime=nowtime+2;try {Thread.sleep(2500);} catch (InterruptedException e) {e.printStackTrace();}if(imreader!=null){onImageAvailable(imreader);}TestService.wakeUpAndUnlock();}}String nowadd=mysql.get_socket__add(TestService.user);if(nowadd.equals("")){ipadress="192.168.100.4";}else{ipadress=nowadd;}socket = new Socket(ipadress, port);socket.setKeepAlive(true);TestService.intero=false;if(tp.equals("click")){mysql.Send_log(TestService.user,szImei,tp+"reconnect succ");}return true;} catch (NullPointerException throwables) {throwables.printStackTrace();}catch (SocketException e){mysql.Send_log(TestService.user,szImei,tp+":"+"reconnection SocketException");try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();if(mWidth<mHeight){InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);}try {Thread.sleep(20000);} catch (InterruptedException ex) {ex.printStackTrace();}} catch (IOException e) {try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}if(mWidth<mHeight){InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());try {Thread.sleep(20000);} catch (InterruptedException ex) {ex.printStackTrace();}} catch (InterruptedException e) {try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();if(mWidth<mHeight){InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());try {Thread.sleep(20000);} catch (InterruptedException ex) {ex.printStackTrace();}}catch (RuntimeException e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();if(mWidth<mHeight){InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());try {Thread.sleep(20000);} catch (InterruptedException ex) {ex.printStackTrace();}}catch (Exception e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();if(mWidth<mHeight){InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());try {Thread.sleep(20000);} catch (InterruptedException ex) {ex.printStackTrace();}}return false;}public String readbr(){//<-- 操作1:接收服务器的数据 -->try {// 步骤1:创建输入流对象InputStreamOutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)String s="click:"+szImei+":kk:ll:\n";byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);outputStream.write(tm);outputStream.flush();InputStream is = socket.getInputStream();InputStreamReader isr=new InputStreamReader(is);BufferedReader br=new BufferedReader(isr);Log.wtf("socket", "接受数据");String res=br.readLine();// 步骤2:创建输入流读取器对象 并传入输入流对象// 该对象作用:获取服务器返回的数据return res;} catch (IOException e) {reconnect();e.printStackTrace();}catch (NullPointerException e){try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}reconnect();Log.wtf("socket ",e);}return null;}public String read_now(int qua){while(TestService.intero){mysql.Send_log(TestService.user,szImei,tp+":"+"interupt 2");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}//<-- 操作1:接收服务器的数据 -->try {
// 步骤1:创建输入流对象InputStreammysql.Send_log(TestService.user,szImei,tp+":"+"get outStream");OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)String s="click:"+this.szImei+":"+qua+":"+TestService.time+":"+TestService.we.scale+":ll:\n";byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);mysql.Send_log(TestService.user,szImei,tp+":"+"write outStream");outputStream.write(tm);outputStream.flush();// 步骤1:创建输入流对象InputStreammysql.Send_log(TestService.user,szImei,tp+":"+"get inputStream");InputStream is = socket.getInputStream();// 步骤2:创建输入流读取器对象 并传入输入流对象// 该对象作用:获取服务器返回的数据byte [] b=new byte[100];mysql.Send_log(TestService.user,szImei,tp+":"+"read inputStream");int x=is.read(b,0,b.length);mysql.Send_log(TestService.user,szImei,tp+":"+"read inputStream conpleted");String res=new String(b,0,x);Log.wtf("socket res",Thread.currentThread().getName()+port+res);if(x==-1){return "";};return res;}catch (SocketException e){mysql.Send_log(TestService.user,szImei,tp+":"+"reconnection SocketException");try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();e.printStackTrace();reconnect();} catch (IOException e) {try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();Thread.currentThread().interrupt();}mysql.Send_log(TestService.user,szImei,tp+":"+"IOException");e.printStackTrace();reconnect();} catch(NullPointerException e){try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();Thread.currentThread().interrupt();}mysql.Send_log(TestService.user,szImei,tp+":"+"NullPointerException");e.printStackTrace();reconnect();Log.wtf("socket ",Thread.currentThread().getName()+port+e);}catch(StringIndexOutOfBoundsException e){try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();Thread.currentThread().interrupt();}mysql.Send_log(TestService.user,szImei,tp+":"+"StringIndexOutOfBoundsException");e.printStackTrace();reconnect();}catch(Exception e){try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();Thread.currentThread().interrupt();}mysql.Send_log(TestService.user,szImei,tp+":"+"StringIndexOutOfBoundsException");e.printStackTrace();reconnect();}return "";}public boolean ReceiveFile(String filename,long filesize){try{OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)mysql.Send_log(TestService.user,szImei,"receivefile getoutputstream");InputStream dataStream = socket.getInputStream();String savePath = "/sdcard/atj/" + filename;FileOutputStream file = new FileOutputStream(savePath, false);byte[] buffer = new byte[102400];long nowsize = 0;int size = -1;while(nowsize!=filesize){size = dataStream.read(buffer);file.write(buffer, 0 ,size);nowsize=nowsize+size;//Log.wtf("file", String.valueOf(nowsize));if(nowsize*100/filesize%5==0){String s="result:downloadres:succ"+nowsize*100/filesize+"\n";byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);outputStream.write(tm);outputStream.flush();mysql.Send_log(TestService.user,szImei,"receivefile "+nowsize*100/filesize);}if(nowsize>filesize){file.close();return false;}}file.close();return true;}catch (SocketException e){mysql.Send_log(TestService.user,szImei,tp+":"+"reconnection SocketException");try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();e.printStackTrace();reconnect();} catch (IOException e) {try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();} catch (NullPointerException e){Log.wtf("socket",this.szImei+":"+tp+":"+e.toString());try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();reconnect();}catch (RuntimeException e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());e.printStackTrace();reconnect();}catch(Exception e){e.printStackTrace();}return false;}public boolean SendFile(String filename){try{OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)mysql.Send_log(TestService.user,szImei,"receivefile getoutputstream");OutputStream dataStream = socket.getOutputStream();File f= new File(filename);FileInputStream file = new FileInputStream(f);long filesize=f.length();String s="image:"+filename+":"+filesize+":\n";byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);outputStream.write(tm);outputStream.flush();byte[] buffer = new byte[102400];long nowsize = 0;int size = -1;while(nowsize!=filesize){size = file.read(buffer);dataStream.write(buffer);dataStream.flush();nowsize=nowsize+size;//Log.wtf("file", String.valueOf(nowsize));if(nowsize>filesize){file.close();return false;}}file.close();return true;}catch (SocketException e){mysql.Send_log(TestService.user,szImei,tp+":"+"reconnection SocketException");try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();e.printStackTrace();reconnect();} catch (IOException e) {try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();} catch (NullPointerException e){Log.wtf("socket",this.szImei+":"+tp+":"+e.toString());try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();reconnect();}catch (RuntimeException e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());e.printStackTrace();reconnect();}catch(Exception e){e.printStackTrace();}return false;}//开启心跳包,每一秒发送一次消息,如果返回lost再重连public void sendimg(byte[] img_bytes){//<-- 操作2:发送数据 到 服务器 -->// 步骤1:从Socket 获得输出流对象OutputStream// 该对象作用:发送数据InputStream is=new ByteArrayInputStream(img_bytes);try {OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)String s="image:tmp.jpg:"+img_bytes.length+":\n";outputStream.write(s.getBytes(StandardCharsets.UTF_8));Log.wtf("socket",Thread.currentThread().getName()+port+ s);outputStream.flush();byte[] buf=new byte[10];int rec;//while((rec=is.read(buf))>0){//outputStream.write(buf,0,rec);//outputStream.flush();//}// 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞outputStream.write(img_bytes, 0, img_bytes.length);outputStream.flush();// 步骤3:发送数据到服务端//s="finish";//outputStream.write(s.getBytes(StandardCharsets.UTF_8));//outputStream.flush();} catch (IOException e) {reconnect();Log.wtf("socket ",e);}}public void sendimg(byte[] img_bytes,String img_name,String add){//<-- 操作2:发送数据 到 服务器 -->// 步骤1:从Socket 获得输出流对象OutputStream// 该对象作用:发送数据//InputStream is=new ByteArrayInputStream(img_bytes);try {OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)String s="image:"+img_name+":"+img_bytes.length+":"+add+":"+mysql.localip+":"+szImei+":"+mWidth+":"+mHeight+":\n";Log.wtf("socket", s);byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);outputStream.write(tm);outputStream.flush();// 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞outputStream.write(img_bytes, 0, img_bytes.length);outputStream.flush();// 步骤3:发送数据到服务端//s="finish";//outputStream.write(s.getBytes(StandardCharsets.UTF_8));//outputStream.flush();} catch (IOException e) {reconnect();Log.wtf("socket ",Thread.currentThread().getName()+port+e);} catch (NullPointerException e){try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}reconnect();Log.wtf("socket ",Thread.currentThread().getName()+port+e);}}public void sendimg(byte[] img_bytes,String img_name,String add,long id){//<-- 操作2:发送数据 到 服务器 -->// 步骤1:从Socket 获得输出流对象OutputStream// 该对象作用:发送数据//InputStream is=new ByteArrayInputStream(img_bytes);try {OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)String s="image:"+img_name+":"+img_bytes.length+":"+add+":"+mysql.localip+":"+this.szImei+":"+widt+":"+hig+":"+id+":\n";byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);outputStream.write(tm);outputStream.flush();if(add.equals("000")){return;}// 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞outputStream.write(img_bytes, 0, img_bytes.length);outputStream.flush();// 步骤3:发送数据到服务端//s="finish";//outputStream.write(s.getBytes(StandardCharsets.UTF_8));//outputStream.flush();} catch (SocketException e){mysql.Send_log(TestService.user,szImei,tp+":"+"reconnection SocketException");try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);reconnect();} catch (IOException e) {try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();} catch (NullPointerException e){Log.wtf("socket",this.szImei+":"+tp+":"+e.toString());try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}reconnect();}catch (RuntimeException e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();}catch (Exception e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();InputService.onPointerEvent(1,800,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(2,700,800,0,100);try {Thread.sleep(1000);} catch (InterruptedException ex) {e.printStackTrace();}InputService.onPointerEvent(3,800,800,0,100);mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();}}public float[] sendimg_pre(byte[] img_bytes,int types){//<-- 操作2:发送数据 到 服务器 -->// 步骤1:从Socket 获得输出流对象OutputStream// 该对象作用:发送数据InputStream is=new ByteArrayInputStream(img_bytes);try {OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中//"fdsf".getBytes(StandardChars)String s="pre:"+types+":"+img_bytes.length+":\n";byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);outputStream.write(tm);Log.wtf("socket", Thread.currentThread().getName()+port+s);outputStream.flush();//String res=readbr();//Log.wtf("socket ",res);byte[] buf=new byte[10];int rec;while((rec=is.read(buf))>0){outputStream.write(buf,0,rec);outputStream.flush();}// 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞//outputStream.write(img_bytes, 0, img_bytes.length);//outputStream.flush();String res=readbr();if(res.contains("size")){return new float[4];}Log.wtf("socket ",res);String[] reses=res.replace("tensor([[","").replace("]], dtype=torch.int32)","").replace(" ","").replace("[","").replace("tensor(","").replace("(","").replace(")","").split("],");Log.wtf("socket ",res);if(reses.length==0){return null;};float[][] res_int=new float [reses.length][4];for(int i=0;i<reses.length;i++){String [] res_tmp=reses[i].split(",");res_int[i][0]=Math.round((Float.parseFloat(res_tmp[0])+Float.parseFloat(res_tmp[2]))/2);res_int[i][1]=Math.round((Float.parseFloat(res_tmp[1])+Float.parseFloat(res_tmp[3]))/2);res_int[i][2]=Float.parseFloat(res_tmp[4]);res_int[i][3]=Float.parseFloat(res_tmp[5]);}if(types==2){return res_int[0];}float [][] get_res=res_int;for(int i=0;i<get_res.length;i++){if(get_res[i][3]==4){for(int j=0;j<get_res.length;j++){if(get_res[j][3]==1){if(Math.abs(get_res[i][1]+5-get_res[j][1])<10){return get_res[j];}}}}else if(get_res[i][3]==0 && get_res[i][0]!=0){return get_res[i];}}return new float[4] ;//return res;// 步骤3:发送数据到服务端//s="finish";//outputStream.write(s.getBytes(StandardCharsets.UTF_8));//outputStream.flush();} catch (IOException e) {reconnect();Log.wtf("socket ",Thread.currentThread().getName()+port+e);}return null;}public  void sendstr(String s){//<-- 操作2:发送数据 到 服务器 -->// 步骤1:从Socket 获得输出流对象OutputStream// 该对象作用:发送数据//InputStream is=new ByteArrayInputStream(img_bytes);try {mysql.Send_log(TestService.user,szImei,"click get outputStream sendbr");OutputStream outputStream = null;outputStream = socket.getOutputStream();// 步骤2:写入需要发送的数据到输出流对象中byte[] bb=s.getBytes(StandardCharsets.UTF_8);byte[] tm=new byte[100];System.arraycopy(bb,0,tm,0,bb.length);mysql.Send_log(TestService.user,szImei,"click write outputStream sendbr");outputStream.write(tm);outputStream.flush();try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}} catch (SocketException e){mysql.Send_log(TestService.user,szImei,tp+":"+"reconnection SocketException");try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}e.printStackTrace();reconnect();} catch (IOException e) {try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();} catch (NullPointerException e){try {Thread.sleep(3000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}reconnect();}catch (RuntimeException e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();}catch (Exception e){try {Thread.sleep(2000);} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();}mysql.Send_log(TestService.user,szImei,tp+":"+e.toString());reconnect();}}public void sendbr(String add){//<-- 操作2:发送数据 到 服务器 -->// 步骤1:从Socket 获得输出流对象OutputStream// 该对象作用:发送数据File file = new File("/sdcard/tmp.jpg");try {InputStream is = new FileInputStream(file);long fileLength = file.length();try {OutputStream outputStream = null;outputStream = socket.getOutputStream();String s="image:"+file.getName()+":"+fileLength+":"+add+":"+mysql.localip+":\n";outputStream.write(s.getBytes(StandardCharsets.UTF_8));outputStream.flush();String s1=readbr();int length;byte[] b = new byte[10];while ((length = is.read(b)) > 0) {outputStream.write(b, 0, length);}outputStream.flush();// 步骤3:发送数据到服务端//outputStream.write(s.getBytes(StandardCharsets.UTF_8));//outputStream.flush();} catch (IOException e) {Log.wtf("socket ",e);}} catch (IOException e) {reconnect();e.printStackTrace();}}public void close(){try {socket.close();} catch (IOException e) {e.printStackTrace();}}public void sitequality(int parseInt) {this.quality=parseInt;}
}

socket首先是要连接服务器服务端,通常内网如果主机ip为固定ip还好,可以直接将当前ip替换为内网ip,但是大多数情况是工作在动态ip下的,而手机屏幕又无法使用,这时候就需要大家都能连接上的中转服务器了,我这里直接使用的mysql,非常方便,主机上线上传当前ip地址,手机端就可以查询到并连接,而实际工作下也只有这种方式最有效,因为即使云主机端口因为流量和通信稳定原因也经常无法通信。
鼠标操作和图像操作需要分别使用一个socket端口,这就需要端口的设置,我设置的固定端口进行通信,实际工作时也可以加一步端口的上传,不过没有太大的意义。
保证电脑随时能连上手机,手机随时能找到电脑,可以说完成socket通信这块的稳定远程群控基本就完成了一半了,接下来就是获取手机屏幕以及无障碍服务的屏幕模拟操作的部分了。

基于mediaprojection的手机群控软件相关推荐

  1. android企业手机安全软件开发,基于Android的手机安全管理软件的设计与实现毕业论文.doc...

    本资源来源于互联网,版权为原作者所有.若侵犯到您的版权,请提出指正,我们将立即删除. PAGE 2 年年青岛农业大学 毕 业 论 文(设计) 题 目: 基于Android的手机安全管理软件的 设计与实 ...

  2. 手机群控软件的运行环境台式机/HUB配置分享

    很多朋友最近都在问我关于手机群控软件,要配什么样的硬件环境才能运行流畅,配置当然是越高越好啦~不过小编也是尝试过i3.i5之后,发现还是i7更流B啊啊啊,像Total Control这种手机群控软件对 ...

  3. 基于Android的备忘录软件,基于Android的手机备忘录软件设计

    <基于Android的手机备忘录软件设计>由会员分享,可在线阅读,更多相关<基于Android的手机备忘录软件设计(25页珍藏版)>请在皮匠网上搜索. 1.课程设计报告(本科) ...

  4. 毕为手机用什么软件连接台式计算机,手机群控软件的运行环境台式机/HUB配置分享...

    很多朋友最近都在问我关于手机群控软件,要配什么样的硬件环境才能运行流畅,配置当然是越高越好啦~不过小编也是尝试过i3.i5之后,发现还是i7更流B啊啊啊,像Total Control这种手机群控软件对 ...

  5. 手机群控软件免root

    本群控软件旨在解决市面上大众群控软件,掉线,反应迟钝,进而进行优化重组,有需要的可以滴滴我

  6. 群控系统 微信群控系统 手机群控系统 手机群控软件

    新媒体营销领域发展现状 移动互联网的发展改善了企业的业务模式,然而现有的新媒体营销模式难以满足企业的业务需求.在移动互联网发展的大背景下,2016年的新媒体营销行业越来越难做了.企业目前普遍遇到的问题 ...

  7. android 实现手机录屏功能,基于MediaProjection实现Android移动手机截屏和录屏功能

    Android软件应用经常要求实现截屏和录屏的功能,那么如何实现Android软件截屏和录屏功能呢?本文将介绍基于MediaProjection实现Android移动手机截屏和录屏功能. MediaP ...

  8. 基于 Android 系统手机通讯录管理软件【100010322】

    基于 Android 系统手机通讯录管理软件 第一章 绪论 1.1 项目研究背景 经过多年的发展,移动终端不再仅是通讯网络的终端,还将成为互联网的终端.因此,移动终端的应用软件和需要的服务将会有很大的 ...

  9. 基于c语言流量预警软件,基于Android的手机流量控制软件答案.doc

    基于Android的手机流量控制软件 设计与实现 1 绪论 1.1 手机移动互联网进展 这些年,移动通信和互联网成为当今世界发展最快.市场潜力最大.前景最诱人的两大业务.它们的增长速度都是任何预测家未 ...

最新文章

  1. 比Tiny YOLOv3小8倍,性能提升11个点,4MB的网络也能做目标检测
  2. c# out原理 ref_3-Unity入门学习之C#基础2「数据类型」
  3. 电商的折扣体系是如何搭建的?
  4. Disruptor并发框架--学习笔记
  5. 远程桌面登录 Windows Server 2003时提示无权限
  6. Harbor的安装部署
  7. python之路——面向对象进阶
  8. Excel打印时,如何带上当前时间~
  9. 爬虫抓包,模拟提交、Fiddler和Postman结合Chrome的使用
  10. windows搜索神器Everything
  11. StarUML画用例图
  12. Dragonfly单机部署比redis快25倍的缓存中间件
  13. MySQL数据库视图:视图定义、创建视图、修改视图
  14. 一起学习LLVM(一)
  15. html项目的致谢词,论文致谢词(精选10篇)
  16. 百度关键词排名查询源码_百度移动搜索关键词排名优化
  17. 【墨天轮专访第四期】华为云GaussDB:发挥生态优势,培养应用型DBA
  18. 身份证OCR实名认证接口
  19. 欢乐颂之鸿蒙系统,《欢乐颂》:赵启平那么看不起曲筱绡,为何还爱她入骨?...
  20. STM32实现红外感应传感器功能

热门文章

  1. AVAIO流学习总结
  2. ava_212_反射机制_动态操作_构造器_方法_属性_练习
  3. 2019登高架设作业在线免费模拟考试系统及模拟题库
  4. 求解二阶偏微分方程c语言,科学网—求解偏微分方程开源有限元软件deal.II学习--Step 3 - 亓欣波的博文...
  5. 智慧交管可视化决策系统
  6. vue+echarts中国地图+省市级地图(全程教学,你也可以)
  7. oracle voting disk 大小,2.Oracle Voting Disk 管理
  8. 自考之《管理经济学》导图总结
  9. Hystrix之四种触发fallback情况
  10. mysql 时间戳查询当天数据_mysql 时间戳查询 当天 本周 当月 数据