介绍
因为某些原因,需要显示器上监听安卓开发板的屏幕状态,网上找了些资料说是可以通过adb命令去实现
可以参考资料:http://www.jianshu.com/p/fee5b31774be
这篇文章实现方法应该不是通用的,我们在手机和安卓开发板上各自都进行了尝试,结果显示并不通用。
我们使用在pc端连接wifi天线开设个固定的ip:见上篇博客;
pc端做服务端(c语言),安卓端做客户端(java),使用socket通信,进行数据传递。
scoket通信
我们没有对数据格式进行严格的定义,只是进行了通信,下面我就附上自己写的粗劣代码,在main中开启服务同时结束这个界面,主题配置 android:theme=”@android:style/Theme.NoDisplay”>
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent(MainActivity.this, ConfigService.class);
startService(intent);
finish();
}
}
在服务中监听开发板的屏幕状态变化,并且将变化通过socket通信传递给服务端,接受服务端的确认信息。
public class ConfigService extends Service {
private byte[] mBytes;
private byte[] mMtes;
private Socket mSocket;
boolean iSconnect;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
LogUtils.wyjlog("打开服务");
initData();//初始化数据
initNertWork();
}
private void initNertWork() {
new Thread(new Runnable() {
@Override
public void run() {
initSocket();
}
}).start();
}
private void initData() {
/* unsigned int magic; //魔数 0x20170707
unsigned int id; //命令类型 0x00000001
unsigned int len; //数据长度,包括头 16
int cmdFlag; //0 代表横屏, 1代表竖屏*/
byte[]aData = new byte[4];
byte[]bData = new byte[4];
byte[]cData = new byte[4];
byte[]dData = new byte[4];
byte[]fData = new byte[4];
int[] mPortraitData = new int[]{538380039,1,16,1};
aData = DataChange.intToBytes(mPortraitData[0]);
bData = DataChange.intToBytes(mPortraitData[1]);
cData = DataChange.intToBytes(mPortraitData[2]);
dData = DataChange.intToBytes(mPortraitData[3]);
fData=DataChange.intToBytes(0);
mBytes = new byte[16];
mMtes = new byte[16];
for (int i = 0; i < mBytes.length; i++) {
if (i < 4) {//0-3
mBytes[i] = aData[i];
mMtes[i] = aData[i];
} else if (i<8) {//4-7
mBytes[i] = bData[i-4];
mMtes[i] = bData[i-4];
} else if (i < 12) {//8-11
mBytes[i] = cData[i-8];
mMtes[i] = cData[i-8];
} else {//12-15
mBytes[i] = dData[i-12];//1
mMtes[i] = fData[i-12];//0
}
LogUtils.wyjlog("====="+i+" :"+ mBytes[i]);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//在横竖屏转换前确保socket连接
//切换为竖屏
if (newConfig.orientation == this.getResources().getConfiguration().ORIENTATION_PORTRAIT) {
final String Tag="1";//竖屏
new Thread(new Runnable() {
@Override
public void run() {
while(!iSconnect) {
initSocket();
}
SendMessage(Tag);
}
}).start();
Toast.makeText(getApplicationContext(), "切换为竖屏", Toast.LENGTH_SHORT).show();
}
//切换为横屏
else if (newConfig.orientation == this.getResources().getConfiguration().ORIENTATION_LANDSCAPE) {
final String Tag="0";//横屏
new Thread(new Runnable() {
@Override
public void run() {
while(!iSconnect) {
initSocket();
}
SendMessage(Tag);
}
}).start();
Toast.makeText(getApplicationContext(), "切换为横屏", Toast.LENGTH_SHORT).show();
}
}
private void initSocket() {
try {
mSocket = new Socket("192.168.137.1", 8000);
iSconnect=true;
LogUtils.wyjlog("socket连接成功");
} catch (IOException e) {
e.printStackTrace();
iSconnect=false;
LogUtils.wyjlog("连接失败"+e.getLocalizedMessage()+e.getMessage());
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
private void SendMessage(String s) {
try {
DataOutputStream dos = new DataOutputStream(mSocket.getOutputStream());
DataInputStream in = new DataInputStream(mSocket.getInputStream());
byte[] temp = new byte[16];
if (s.equals("0")) { //7 7 23 32 // 1 0 0 0 // 16 0 0 0 // 1 0 0 0
Task(dos, in, temp,"横屏",s);
} else {//竖屏
Task(dos, in, temp,"竖屏",s);
}
} catch (IOException e) {
e.printStackTrace();
LogUtils.wyjlog("====="+e.getMessage()+e.getLocalizedMessage());
}
}
private void Task(DataOutputStream dos, DataInputStream in, byte[] temp, String type, String sType) throws IOException {
while (true) {
LogUtils.wyjlog(type);
if (sType.equals("0")) {
dos.write(mMtes,0,mMtes.length);//横屏
} else {
dos.write(mBytes,0,mBytes.length);//竖屏
}
dos.flush();
in.read(temp);
String s1 = new String(temp); // 32 23 7 7 0004 00016 0000
for (int i = 0; i < temp.length; i++) {
LogUtils.wyjlog(type+"第"+i+"位"+temp[i]); }
if (temp[11] == 16 && temp[7] == 4) {//回复确认
LogUtils.wyjlog("确认回复数据 :"+type);
TODO:要不要关闭输入输出流? in.close() dos.close();
break;
}
LogUtils.wyjlog("数据发送失败");
}
}
}
此处要注意socket通信在in.read(temp)是一个阻塞线程,在数据读取前要先dos.flush();刷新输出流。接受的数据由于是写C定义的,按照那边的要求进行高位在前。
public class DataChange {
public static byte[] intToBytes(int value)
{
byte[] byte_src = new byte[4];
byte_src[3] = (byte) ((value & 0xFF000000)>>24);
byte_src[2] = (byte) ((value & 0x00FF0000)>>16);
byte_src[1] = (byte) ((value & 0x0000FF00)>>8);
byte_src[0] = (byte) ((value & 0x000000FF));
return byte_src;
}
}