概述
今天逛簡書的時候,發現了一個庫:
https://github.com/MZCretin/WifiTransfer-master
主要功能是這樣的,先口述一下,當打開app,可以通過浏覽器通路一個位址,然後通過浏覽器可以給手機上上傳apk(也支援已有apk删除),然後手機端可以安裝、解除安裝該apk。
三張圖就明白了:
應用啟動後:

然後PC端通路:
拖拽apk上傳,即可上傳到手機端。
ok,大緻介紹清楚了。
注意一定要在同一個網段。
先不談其用處到底有多大,很多時候我看到一個項目的時候,很少考慮其能幹嘛,考慮最多的是它是如何實作的,我會麼,不會那就學,至于能幹嘛,那要等我學會之後?
那麼思考下他的實作,這種上傳檔案的方式,在PC端更加常見,上傳檔案到伺服器。
說到這,就可以想到,可能這個app在手機端搭建了一個伺服器。
恩,沒錯就是這樣的,在手機端搭建了一個伺服器,這樣就可以通過html,将PC端的檔案傳給手機端,然後手機端收到後再同步界面。
同時,也可以将手機上Sdcard上的檔案,完全在PC上呈現。
手機端的Server利用的是該庫:https://github.com/koush/AndroidAsync
解析源碼的事情就不做了,有興趣可以自己學習下,接下來開始正片。
一個群友的問題
之是以會關注到這個庫,是因為在wanandroid群,有個哥們連續問了好久的一個問題,問題是:
如何通過浏覽器輸入一個位址播放手機上的視訊
當時也很多人回答,回答的核心都是正确的。
當然我恰好看到這個庫,之前也沒推送過相關内容,是以我決定寫個簡易的Demo.
當然是Demo就沒有什麼美觀可言了,僅為快速實作效果。
效果圖是這樣的:
頁面上顯示手機上的視訊清單,然後點選某個視訊,即開始播放該視訊。
有了上例參考,非常簡單。
注:部分代碼直接從上例copy。
該案例需要網絡和Sdcard權限!
先把伺服器搭起來依賴庫
首先,依賴下我們搭建Server需要用到的庫:
compile 'com.koushikdutta.async:androidasync:2.+'
複制
編寫簡易html
然後我們在assets下編寫一個html檔案用于浏覽器通路,index.html
最簡單的即可:
<!DOCTYPE html
<html
<head
<meta charset="UTF-8"
</head
<body
嘿嘿嘿,連通了...
</body
</html
複制
啟動服務,監聽端口
public class MainActivity extends AppCompatActivity {
private AsyncHttpServer server = new AsyncHttpServer();
private AsyncServer mAsyncServer = new AsyncServer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
server.get("/", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
try {
response.send(getIndexContent());
} catch (IOException e) {
e.printStackTrace();
response.code(500).end();
}
}
});
server.listen(mAsyncServer, 54321);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (server != null) {
server.stop();
}
if (mAsyncServer != null) {
mAsyncServer.stop();
}
}
private String getIndexContent() throws IOException {
BufferedInputStream bInputStream = null;
try {
bInputStream = new BufferedInputStream(getAssets().open("index.html"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] tmp = new byte[10240];
while ((len = bInputStream.read(tmp)) 0) {
baos.write(tmp, 0, len);
}
return new String(baos.toByteArray(), "utf-8");
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
if (bInputStream != null) {
try {
bInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
複制
可以看到很簡單,建立AsyncHttpServer對象,我們在onCreate中調用get,對外設定一個get型的url監聽,監聽的url是/即根目錄。
然後調用listen,傳入端口号54321,開啟對該端口的監聽。
onDestroy的時候停止伺服器。
當捕獲到對”/”的通路時,讀取assets下的index.html傳回給浏覽器。
記得添加網絡權限。
好了,運作demo,測試一下。
輸入位址,你的手機的IP:端口号。
注意電腦和手機在同一個網段!
然後你應該看到如下效果圖:
如果沒看到,那不用往下了,先找問題吧~
完善Demo
接下來,我們将手機上的mp4傳回讓其在浏覽器上顯示。
很簡單,既然我們可以監聽/,傳回一個index.html,我們就能監聽另一個url,傳回檔案目錄。
server.get("/files", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
JSONArray array = new JSONArray();
File dir = new File(Environment.getExternalStorageDirectory().getPath());
String[] fileNames = dir.list();
if (fileNames != null) {
for (String fileName : fileNames) {
File file = new File(dir, fileName);
if (file.exists() && file.isFile() && file.getName().endsWith(".mp4")) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", fileName);
jsonObject.put("path", file.getAbsolutePath());
array.put(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
response.send(array.toString());
}
});
複制
我們監聽/files這個Url,然後傳回Sdcard根目錄的視訊檔案,拼接成JSON傳回。
這裡如果你重新啟動,在浏覽器上輸入:
http://192.168.1.100:54321/files
複制
會看到一堆JSON資料:
但是我們需要在剛才的html上顯示,是以這個請求應該是剛才的Html頁面發起:
<!DOCTYPE html
<html
<head
<meta charset="UTF-8"
<script src="jquery-1.7.2.min.js" type="text/javascript" </script
<title 文檔的标題</title
<script type="text/javascript"
$(function() {
var now = new Date();
var url = 'files' + '?' + now.getTime();
// 請求JSON資料
$.getJSON(url, function(data) {
// 編輯JSON數組
for (var i = 0; i < data.length; i++) {
// 為每個對象生成一個li标簽,添加到頁面的ul中
var $li = $('<li ' + data[i].name + '</li ');
$li.attr("path", data[i].path);
$("#filelist").append($li);
}
});
});
</script
</head
<body
<ul id="filelist" style="float:left;" </ul
</body
</html
複制
可能很多朋友沒了解過js,不過應該能看明白,
$.getJSON
擷取傳回的JSON數組,然後周遊為每個Json對象生成一個li标簽,添加到頁面上。
這裡用了jquery,對于js的也需要也請求處理,這裡省略了,很簡單,看源碼即可。
此時通路,已經可以顯示出視訊目錄了:
接下來就是點選播放了,在html裡面有個标簽叫video用于播放視訊的,他有個src屬性用于設定播放的視訊路徑。
是以我們要做的僅為:
點選名字,拿到該視訊對應的url,然後設定給video的src屬性即可。
那麼視訊的url是什麼?
剛才我們傳回了視訊的路徑,是以我們隻要再監聽一個url,将根據傳入的視訊路徑,将視訊檔案流傳回即可。
server.get("/files/.*", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
String path = request.getPath().replace("/files/", "");
try {
path = URLDecoder.decode(path, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
File file = new File(path);
if (file.exists() && file.isFile()) {
try {
FileInputStream fis = new FileInputStream(file);
response.sendStream(fis, fis.available());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
response.code(404).send("Not found!");
}
});
複制
我們又監聽了一個url為files/xxx.*,捕獲到之後,拿到檔案名,去SDCard找到該檔案,傳回檔案流即可。
html端的代碼為:
<script type="text/javascript"
$(function() {
var now = new Date();
// 拿到video對象
var $video = $("#videoplayer");
var url = 'files' + '?' + now.getTime();
$.getJSON(url, function(data) {
for (var i = 0; i < data.length; i++) {
var $li = $('<li ' + data[i].name + '</li ');
$li.attr("path", data[i].path);
$("#filelist").append($li);
// 點選的時候,擷取路徑,設定給video的src屬性
$li.click(function() {
var p = "/files/" + $(this).attr("path");
$video.attr("src", "/files/" + $(this).attr("path"));
$video[0].play();
});
}
});
});
</script
複制
當然頁面上body标簽内部也多了一個video标簽。
<video id="videoplayer" controls="controls"
</video
複制
到這裡,是以的代碼就介紹完了~~
小結
回頭看,其實就是app中啟動伺服器,監聽一些url,然後針對性的傳回文本、json、檔案流等。
當然了,可以做的時候也挺多的,甚至可以做個PC版本的檔案浏覽器。
可能有很多人對html,js不太熟悉,不過還是建議簡單了解下,或者敲一下本例,因為本例代碼很少,值得作為上手教程。
源碼位址:https://github.com/hongyangAndroid/demo_ShowPhoneMp4
以上就是本文的全部内容,希望對大家的學習有所幫助。