
手機(jī)居然可以控制電腦瀏覽器顯示,一開始我也是吃了一驚,但就是可以的,而且只需要修改手機(jī)端的程序,不需要修改瀏覽器?;驹硎鞘謾C(jī)與瀏覽器通過socket 通信。
前言
這個(gè)東西最初我是看簡書一個(gè)大神的文章知道的
http://www.itdecent.cn/p/89ccae3e590b
《調(diào)試手機(jī)中數(shù)據(jù)庫的福音:Android-Debug-Database》
文章介紹了老外的一個(gè)庫Android-Debug-Database ,通過這個(gè)庫,可以在瀏覽器顯示與修改當(dāng)前應(yīng)用的數(shù)據(jù)庫,sharepreferce等內(nèi)容。這可刷新了我的世界觀。在我的想象中,手機(jī)與電腦通信,起碼要寫兩個(gè)軟件,一個(gè)是手機(jī)端,一個(gè)電腦端的。結(jié)果,這個(gè)庫,只需要寫手機(jī)端的。我想,估計(jì)是瀏覽器已經(jīng)是一個(gè)標(biāo)準(zhǔn)的客戶端,手機(jī)只需要完成服務(wù)器的搭建即可。
下圖是我通過手機(jī),在電腦瀏覽器顯示一段基本的html代碼,酷炫得不行

通信過程##
整個(gè)過程是手機(jī)作為服務(wù)器端,瀏覽器作為客戶端。大概通信步驟如下
1.使電腦與手機(jī)位于同一局域網(wǎng)。實(shí)操就是直接用usb連接手機(jī)與電腦,并進(jìn)行端口轉(zhuǎn)發(fā),將電腦端口9989的數(shù)據(jù),轉(zhuǎn)發(fā)到手機(jī)9989端口(當(dāng)然你也可以用其他端口,要保證端口沒有被占用)
adb forward tcp:9989 tcp:9989
2.手機(jī)開啟一個(gè)socket,,指定手機(jī)端口9989監(jiān)聽客戶端連接
mServerSocket = new ServerSocket(9989);
Socket socket = mServerSocket.accept();
3.瀏覽器向電腦端口9989 發(fā)送http請(qǐng)求,該請(qǐng)求被轉(zhuǎn)發(fā)到手機(jī)的9989端口,通信連通。具體就是在瀏覽器輸入一個(gè)網(wǎng)址http://localhost:9989/
3.連接后,手機(jī)返回html文件給瀏覽器,瀏覽器進(jìn)行顯示。
//返回html給瀏覽器
String route = "wenfeng.html";
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
output = new PrintStream(socket.getOutputStream());
byte[] bytes;
bytes = loadContent(route, mAssets);
//把狀態(tài)返回給瀏覽器
output.println("HTTP/1.0 200 OK");
output.println("Content-Type: " + "text/html");
output.println("Content-Length: " + bytes.length);
output.println();
output.write(bytes);
output.flush();
看看代碼##
在oncreate開啟socket,進(jìn)行監(jiān)聽
public class MainActivity extends AppCompatActivity {
private ClientServer mclient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mclient = new ClientServer(this,9989);
mclient.start(); //開啟監(jiān)聽
}
}
連接成功后,把html文件返回給瀏覽器,并且返回狀態(tài)碼給瀏覽器。
public class ClientServer implements Runnable {
private static final String TAG = "ClientServer";
private final int mPort;
private boolean mIsRunning;
private ServerSocket mServerSocket;
private Context context;
public ClientServer(Context context, int port) {
mPort = port;
this.context=context;
}
public void start() {
Log.i("wenfeng","start");
mIsRunning = true;
new Thread(this).start();
}
@Override
public void run() {
try {
mServerSocket = new ServerSocket(mPort);
Log.i("wenfeng","wait for accept"); //等待連接
Socket socket = mServerSocket.accept();
handle(socket); //處理連接
} catch (SocketException e) {
// The server was stopped; ignore.
Log.i("wenfeng","SocketException",e);
} catch (IOException e) {
Log.i("wenfeng","IOException",e);
} catch (Exception ignore) {
}
}
public void handle(Socket socket) throws IOException {
BufferedReader reader = null;
PrintStream output = null;
try {
AssetManager mAssets = context.getResources().getAssets();
String route = "wenfeng.html";
output = new PrintStream(socket.getOutputStream());
byte[] bytes;
//裝載wenfeng.html文件,用于返回給瀏覽器
bytes = loadContent(route, mAssets);
//返回服務(wù)器狀態(tài)
output.println("HTTP/1.0 200 OK");
output.println("Content-Type: " + "text/html");
output.println("Content-Length: " + bytes.length);
output.println();
//返回?cái)?shù)據(jù)
output.write(bytes);
output.flush();
} finally {
try {
if (null != output) {
output.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//該函數(shù)用于裝載html文件
public static byte[] loadContent(String fileName, AssetManager assetManager) throws IOException {
InputStream input = null;
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
input = assetManager.open(fileName);
byte[] buffer = new byte[1024];
int size;
while (-1 != (size = input.read(buffer))) {
output.write(buffer, 0, size);
}
output.flush();
return output.toByteArray();
} catch (FileNotFoundException e) {
return null;
} finally {
try {
if (null != input) {
input.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
例子的傳送門,可以體驗(yàn)一下。
https://github.com/wenfengtou/RubbishDemo
日更中,歡迎關(guān)注。