天天看點

Android實作區域網路二維碼分享圖檔(帶密碼驗證)

最近接到一個需求,需要實作一個區域網路的圖檔二維碼分享功能;具體怎麼樣呢,先看下面的效果圖:

Android實作區域網路二維碼分享圖檔(帶密碼驗證)

由于是區域網路,請使用真機,如果有兩個手機更好了,連接配接同個區域網路就可以看到;如果是隻有一個手機,那就電腦上看把, html 的布局有點醜,因為主要是 适配手機,我也不擅長這一塊,見怪不怪吧。

一、需求分析

要實作區域網路,一般就是搭建個 ServerSocket,裝置連接配接時輸出網址即可

二維碼分享,沒啥好說,zxing .

咦,好像就沒了啊,關鍵是區域網路這個伺服器了, 搭建 Android 的區域網路,自己寫的話,估計調試都調到很久,github 搜了一下,主要有三個,AndServer ,國人寫的,思路比較适合我們,但有時會遇到連接配接逾時的問題,不知道是不是我網絡的問題;還有 NanoHttpd 和 AndroidAsync,NanoHttpd 适合java,且調試不好調試,最後選擇了 AndroidAsync,接入簡單,而且接口也比較好用。(以上隻是個人觀點),但 AndroidAsync 關于伺服器方面的資料還是比較少的,是以得看源碼了,不過這裡也做了一些封裝,到時可以參考一下。

二、代碼配置

區域網路,首先需要有網絡,是以這裡直接檢查網絡好了,需要檢測 WiFi 是否能檢測到,這裡的 WiFi 的 IP 擷取也比較簡單,當檢測到 WiFi 連接配接了,直接拿就是了:

//wifi是否連接配接
       if (CusUtil.isWifiConnected()){
           //擷取 ip
           DEVICE_IP = CusUtil.getWifiIpaddr();
           StringBuilder sb = new StringBuilder();
           sb.append("請在同個wifi下,掃描該二維碼,或者浏覽器中輸入: \n")
                   .append("http://"+DEVICE_IP+":"+SERVER_PORT)
                   .append("\n或者輸入:\n")
                   .append("http://"+DEVICE_IP+":"+SERVER_PORT+"/password");
           textView.setText(sb.toString());
       }else{
           textView.setText("您還未連接配接 wifi ");
       }
           

如果 WiFi 擷取了,則開始配置資料,主要是 ip 和port,當然還有添加攔截器,圖檔和密碼還是需要攔截的。

private void startLanServer(){
        mCheckRequestHandle = CheckRequestHandle.create(this,DEVICE_IP,SERVER_PORT);
        //配置資料,builder 模式
        LanServerBean bean = LanServerBean.lanBuilder()
                .setPort(SERVER_PORT)
                .setIpAddr(DEVICE_IP)
                //配置預設 html 字元串
                .setDefaultHtml(CusUtil.getDefaultString(DEVICE_IP,SERVER_PORT))
                //添加攔截,當檢測 image,輸出圖檔
                .registerHandler("image", ImageRequestHandle.create(this))
                //添加攔截,當檢測 password,彈出密碼驗證框
                .registerHandler("password",mCheckRequestHandle)
                .builder();

        if (mServiceBinder != null) {
            mServiceBinder.startLanServer(bean);
        }

    }
           

如果自己有新的需求,也可以繼續添加攔截器,攔截器也比較簡單,AndroidAsync 的 api 還是比較人性化的:

public class ImageRequestHandle implements HttpServerRequestCallback {
    private static final String TAG = "ImageRequestHandle";
    private Context mContext;
    private ImageRequestHandle(Context context){
        mContext = context;
    }
    public static ImageRequestHandle create(Context context){
        return new ImageRequestHandle(context);
    }

    @Override
    public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
        try {
            InputStream is = mContext.getAssets().open("beauty.jpg");
            //輸入圖檔
            response.sendStream(is,is.available());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
           

html 的擷取都是在 assets 中,而一些動态的,比如 ip 和 端口,則是通過 代碼重新添加,關于 html 的基礎,就不解釋啦,自己去撸吧:

/**
     * 輸出驗證密碼的html
     * @return
     */
    public static  String getCheckPasswordHtml(String ipaddr,int port,String password){

        StringBuilder sb = new StringBuilder();
        sb.append(CusUtil.getAssetsString("checkpass.html")).append("\n")
                .append("<button class=\"button\" onclick=\"checkPassword(")
                .append(password+",'"+"http://"+ipaddr+":"+port+"')\">确定</button>").append("\n")
                .append(" </div>").append("\n")
                .append(" </div>").append("\n")
                .append(" </body>").append("\n")
                .append(" </html>").append("\n");


        return sb.toString();

    }
           

三、擴充

繼續區域網路分享圖檔已經懂了,那麼像區域網路傳輸檔案,資訊共享等等,都是可以搞的。比如比較火的 WiFi 傳書,就是這個原理。多去折騰吧。

四、代碼位址

完整的文章代碼可以檢視Github位址:

https://github.com/LillteZheng/LanServer

原文釋出時間為:2018-0717

本文作者:LillteZheng

本文來自雲栖社群合作夥伴“

安卓巴士Android開發者門戶

”,了解相關資訊可以關注“

”。

繼續閱讀