您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何搭建Android上的服務器實現隔空取物的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
概述
今天逛簡書的時候,發現了一個庫:
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" ></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>
關于“如何搭建Android上的服務器實現隔空取物的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。