最近因为手里有了一批主板机,没得屏幕,也没有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 IMEI
Build.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 IMEI
Build.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:创建输入流对象InputStream
OutputStream 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:创建输入流对象InputStream
mysql.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:创建输入流对象InputStream
mysql.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通信这块的稳定远程群控基本就完成了一半了,接下来就是获取手机屏幕以及无障碍服务的屏幕模拟操作的部分了。