色五月色开心色婷婷色丁香,五月婷婷丁香花综合网,婷婷丁香五月激情综合在线,五月婷婷六月丁香动漫,婷婷丁香五月激情综合在线,丁香花中文字幕在线观看,播五月色五月开心五月网,开心激情综合网,狠狠色丁香婷婷综合最新地址,丁香视频在线观看,狠狠做六月爱婷婷综合av,久久激情五月丁香伊人

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

Android WiFi二維碼掃碼連接:WIFI串解析與CameraX識別適配

Android WiFi二維碼掃碼連接:WIFI串解析與CameraX識別適配 簡介面向 Android 開發(fā)者的「掃描 WiFi 二維碼自動連接」實戰(zhàn)項目聚焦掃碼解析網(wǎng)絡(luò)信息并完成配網(wǎng)的需求適合具備基礎(chǔ)組件與權(quán)限知識、希望理解 WifiManager 連接流程的開發(fā)者參考。壓縮包共 141 個文件約 2.16MB以 41 個 class、20 個 java 源碼和 13 個 xml 配置為主另含 png 界面素材、jar 依賴及可運行 apk 等兼顧源碼、資源與演示產(chǎn)物。已有 2015 人學(xué)習(xí)下載。內(nèi)容圍繞二維碼掃描、SSID 與密碼及加密類型解析、WifiConfiguration 構(gòu)建、addNetwork 與 connect 調(diào)用以及 WiFi 狀態(tài)與修改權(quán)限處理展開并涉及連接結(jié)果提示和失敗場景反饋。借助現(xiàn)成工程可對照理解相機掃碼、配置保存和自動連接鏈路定位權(quán)限申請、網(wǎng)絡(luò)添加與兼容性排錯思路。1. 掃一掃就連上二維碼里裝的是什么誰在替你完成連接門店換了路由器墻上那張二維碼得重打客人問“掃這個能連嗎”你說能結(jié)果他掃出來只看到一段WIFI:S:Shop-5G;T:WPA;P:abc12345;;的純文本復(fù)制粘貼到設(shè)置里還提示“密碼錯誤”——這是最典型的一次翻車。掃碼連 WiFi 這件事真正的難點從來不在“掃碼”而在掃碼之后識別出的字符串怎么拆、拆出來的密碼怎么轉(zhuǎn)義還原、不同 Android 版本該走哪套連接 API。多數(shù)“掃了個寂寞”的案例都是這三步里至少斷了一環(huán)。這篇拆的是一份 Android 端的 WiFi 二維碼掃描自動連接實現(xiàn)。它的能力邊界很清楚相機取幀識別二維碼解析出 SSID 和密碼然后按系統(tǒng)版本降級到WifiConfiguration或升級到WifiNetworkSpecifier把用戶從“打開設(shè)置、找網(wǎng)絡(luò)、輸密碼”里解放出來。適合誰做門店/會議室/展臺的一線開發(fā)做設(shè)備配網(wǎng)的工具類 App 開發(fā)以及要給客戶演示“一貼即連”卻總被吐槽連不上的那些人。新手能照著步驟跑通熟手能在這里看到 Android 10 之后那些不寫在文檔首頁的限制。2.WIFI:串拆解六個字段、一次轉(zhuǎn)義和一段必須自己寫的狀態(tài)機二維碼里那串東西不是隨便定出來的它有一個被各家相機 App 和系統(tǒng)設(shè)置共同沿用的約定格式以WIFI:開頭后面是一串用分號分隔的鍵:值對結(jié)尾再用一個分號收掉??雌饋硐?key-value實際上它比 key-value 難纏——因為值里可以合法地出現(xiàn)冒號、分號、逗號和雙引號靠split(;)硬切必然出事。這一章先把格式吃透再寫解析器最后反過來講生成端最容易踩的轉(zhuǎn)義坑。2.1 六個字段與一張反斜杠轉(zhuǎn)義表字段名都是單字母最常用的只有四個鍵含義示例備注T認證類型WPA/WEP/nopass/SAE/WPA2-EAP省略時按nopass兜底SSSIDShop-5G中文 SSID 走 UTF-8別用 GBKP密碼abc12345nopass時不存在該字段H是否隱藏網(wǎng)絡(luò)true不寫就是falseE/I/A/PH2企業(yè)級認證相關(guān)PEAP/user/anon/MSCHAPV2個人場景基本用不到轉(zhuǎn)義規(guī)則只有一條但很多人不寫\、;、,、:、這五個字符出現(xiàn)在值里時前面必須加一個反斜杠。比如 SSID 叫Coffee;Bar寫成二維碼就是WIFI:S:Coffee\;Bar;T:WPA;P:12345678;;。如果生成端漏了這一步解析端就會在分號處截斷SSID 變成Coffee剩下Bar被當成一個沒有冒號的野字段丟掉——現(xiàn)象就是“掃出來連上了但連的是隔壁那個叫 Coffee 的網(wǎng)絡(luò)”。還有一個容易忽略的點T的值大小寫不敏感但S和P是大小寫敏感的密碼里的大寫字母不能被任何環(huán)節(jié)規(guī)范化。我見過一個實現(xiàn)為了“容錯”把整串轉(zhuǎn)成小寫再解析結(jié)果所有含大寫字母的密碼全線崩盤排查了一下午才發(fā)現(xiàn)是lowercase()寫在了parse的第一行。2.2 解析器不要用 split寫個四十行的狀態(tài)機先把最容易翻車的寫法貼出來不是讓你抄是讓你認出來自己代碼里有沒有它// 反例看起來簡潔實際把轉(zhuǎn)義吃掉了 val parts raw.substring(5).split(;) val ssid parts.first { it.startsWith(S:) }.substring(2)問題有兩個。第一S:Coffee\;Bar會被切成S:Coffee\和Bar第二P值里如果出現(xiàn):雖然少見但合法substring(2)之后的處理會帶上前綴判斷的歧義。正確做法是掃描一遍字符流遇到\就吞掉它并把下一個字符原樣收進當前字段遇到;才斷字段。斷完字段后再取第一個字符當鍵、校驗第二個字符是:剩下的一整段做反轉(zhuǎn)義。data class WifiQr( val ssid: String, val password: String?, val type: AuthType, val hidden: Boolean ) enum class AuthType { WPA, WEP, NOPASS, SAE, EAP } object WifiQrParser { private const val PREFIX WIFI: fun parse(raw: String): ResultWifiQr { val text raw.trim() if (!text.startsWith(PREFIX, ignoreCase true)) { return Result.failure(IllegalArgumentException(缺少 WIFI: 前綴)) } val map HashMapChar, String() for (field in splitFields(text.substring(PREFIX.length))) { // 字段形如 S:xxx第一個字符是鍵第二個必須是冒號 if (field.length 2 || field[1] ! :) continue map[field[0].uppercaseChar()] unescape(field.substring(2)) } val ssid map[S] if (ssid.isNullOrEmpty()) return Result.failure(IllegalArgumentException(缺少 SSID)) val type when (map[T]?.uppercase()) { null, , NOPASS - AuthType.NOPASS WEP - AuthType.WEP SAE - AuthType.SAE WPA2-EAP, WPA-EAP - AuthType.EAP else - AuthType.WPA } val pwd map[P] if (type ! AuthType.NOPASS pwd.isNullOrEmpty()) { return Result.failure(IllegalArgumentException(加密網(wǎng)絡(luò)缺少密碼)) } return Result.success( WifiQr(ssid, pwd, type, map[H]?.equals(true, true) true) ) } /** 只按未轉(zhuǎn)義的 ; 切分轉(zhuǎn)義序列原樣保留交給 unescape 處理 */ private fun splitFields(body: String): ListString { val out ArrayListString() val sb StringBuilder() var i 0 while (i body.length) { val c body[i] when { c \\ i 1 body.length - { sb.append(c).append(body[i 1]); i 2 } c ; - { out.add(sb.toString()); sb.clear(); i } else - { sb.append(c); i } } } if (sb.isNotEmpty()) out.add(sb.toString()) return out } private fun unescape(s: String): String { val sb StringBuilder(s.length) var i 0 while (i s.length) { if (s[i] \\ i 1 s.length) { sb.append(s[i 1]); i 2 } else { sb.append(s[i]); i } } return sb.toString() } }邏輯上的關(guān)鍵決策是“切分階段不反轉(zhuǎn)義”。如果先 unescape 再 split\;會退化成;后面的切分就再也分不清哪些分號是結(jié)構(gòu)分隔、哪些是內(nèi)容。同理取鍵值也不能用indexOf(:)因為值里的:雖然被轉(zhuǎn)義了但已經(jīng)混在字符串里按位置取前兩個字符才是唯一穩(wěn)的做法。splitFields里遇到\時同時把反斜杠和下一個字符一起塞進緩沖區(qū)就是為了讓轉(zhuǎn)義信息多活一會兒。參數(shù)上只有兩處可調(diào)PREFIX的大小寫判斷我用了ignoreCase true因為確實有生成工具寫成wifi:T的映射表里把不認識的值一律兜底為WPA這比報錯友好——很多老路由出的碼T是空的但實際就是 WPA2。真正該報錯的只有 SSID 缺失和加密網(wǎng)絡(luò)密碼缺失這兩種其余都該容錯。2.3 反向生成密碼少一位多半是轉(zhuǎn)義順序?qū)懛戳松啥说目颖冉馕龆烁[蔽因為它是“寫錯了也能出圖只是掃出來不對”。最典型的錯誤是轉(zhuǎn)義順序必須先把\換成\\再處理其他四個字符。反過來的話你把;變成\;緊接著又把那個剛加進去的\再轉(zhuǎn)義一次變成\\;解析端還原出來就是\;而不是;。密碼里帶反斜杠的人不多但 SSID 里帶分號的咖啡店、帶逗號的餐廳太多了。# 生成端轉(zhuǎn)義順序不能反反斜杠必須第一個處理 SPECIAL [\\, ;, ,, :, ] def escape(value: str) - str: out value for ch in SPECIAL: out out.replace(ch, \\ ch) return out def build_wifi_qr(ssid: str, password: str , auth: str WPA, hidden: bool False) - str: parts [fT:{auth}, fS:{escape(ssid)}] if auth.upper() ! NOPASS: parts.append(fP:{escape(password)}) if hidden: parts.append(H:true) return WIFI: ;.join(parts) ;;注意SPECIAL里\\排第一這不是隨便排的——str.replace是順序執(zhí)行的先處理反斜杠能保證后續(xù)插入的轉(zhuǎn)義符不會被二次轉(zhuǎn)義。最后的;;是格式約定每個字段自帶一個分號末尾再補一個收尾缺了它有些老設(shè)備的解析器會認為串沒結(jié)束。auth傳nopass時直接不寫P字段而不是寫P:空值這兩種在部分系統(tǒng)實現(xiàn)里行為不同空值可能被當成空密碼去嘗試關(guān)聯(lián)結(jié)果是反復(fù)失敗。生成完別急著打印先自己解析一遍做閉環(huán)校驗把build_wifi_qr的輸出喂給你 Android 側(cè)那個parse斷言parse(build(...)).ssid 原 SSID。這條斷言能擋掉八成以上的轉(zhuǎn)義問題成本只有五行代碼。3. 掃碼鏈路CameraX 抓幀 ML Kit 出串把識別率從 60% 拉到 95%二維碼解析再漂亮識別不出來等于零。這一段的常見失敗不是“完全掃不到”而是“要舉著手機對準三秒才出結(jié)果”用戶體驗上跟壞了沒區(qū)別。原因是很多人用PreviewView截圖再去解碼或者把ImageAnalysis的分辨率設(shè)成默認的 640×480二維碼在畫面里只占幾十個像素解碼器自然吃力。3.1 依賴、權(quán)限與一個容易漏的 manifest 標記依賴就三塊相機、分析器、條碼識別。// build.gradle.kts版本號以你倉庫里能拉到的最新穩(wěn)定版為準 implementation(androidx.camera:camera-camera2:1.3.4) implementation(androidx.camera:camera-lifecycle:1.3.4) implementation(androidx.camera:camera-view:1.3.4) implementation(com.google.mlkit:barcode-scanning:17.2.0)權(quán)限這塊是 Android 版本差異最集中的地方建議一次性寫全靠maxSdkVersion讓系統(tǒng)自己裁剪uses-permission android:nameandroid.permission.CAMERA / uses-permission android:nameandroid.permission.ACCESS_WIFI_STATE / uses-permission android:nameandroid.permission.CHANGE_WIFI_STATE / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE / !-- Android 12 及以下WiFi 相關(guān)操作被視為可推斷位置必須給精確定位 -- uses-permission android:nameandroid.permission.ACCESS_FINE_LOCATION android:maxSdkVersion32 / !-- Android 13 起用獨立權(quán)限聲明 neverForLocation 可免掉定位授權(quán)彈窗 -- uses-permission android:nameandroid.permission.NEARBY_WIFI_DEVICES android:usesPermissionFlagsneverForLocation tools:targetApi33 /neverForLocation這個標記值得單獨說一句。它的語義是“我承諾不用 WiFi 掃描結(jié)果去推斷地理位置”加上之后 Android 13 不會再要求用戶額外授予定位權(quán)限彈窗從兩次變一次。但代價是一旦你聲明了它就不能再調(diào)用任何會被判定為位置推斷的 API比如主動掃描周圍 AP 列表并上報。只做“按 SSID 直連”的話完全夠用所以門店場景我一般都會加上。反之如果你的 App 還要展示附近可用網(wǎng)絡(luò)列表這個標記就得去掉老老實實申請定位。ACCESS_FINE_LOCATION的maxSdkVersion32也不是可選項。Android 12 及以下只要涉及 WiFi 連接系統(tǒng)就要求精確定位權(quán)限給ACCESS_COARSE_LOCATION不夠Android 13 起這個要求被NEARBY_WIFI_DEVICES接管舊的定位權(quán)限反而變成冗余。兩條并存、靠版本裁剪是唯一不用寫版本分支的寫法。3.2 用 ImageAnalysis 抓幀別用 Preview 截圖PreviewView的bitmap是給用戶看的經(jīng)過了縮放和裁切拿去解碼等于自己給自己降分辨率。正確路徑是ImageAnalysis拿到ImageProxy轉(zhuǎn)InputImage直接喂給識別器。分辨率選擇器我一般顯式設(shè)成 1280×720再高解碼耗時上去了再低小碼識別不了。private val cameraExecutor Executors.newSingleThreadExecutor() private var lastRaw: String? null private var lastTime 0L private fun startScanner(lifecycleOwner: LifecycleOwner, previewView: PreviewView) { val analyzer ImageAnalysis.Builder() .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .setResolutionSelector( ResolutionSelector.Builder() .setResolutionStrategy( ResolutionStrategy( Size(1280, 720), ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER ) ).build() ) .build() val scanner BarcodeScanning.getClient( BarcodeScannerOptions.Builder() .setBarcodeFormats(Barcode.FORMAT_QR_CODE) .build() ) analyzer.setAnalyzer(cameraExecutor) { proxy - val media proxy.image if (media null) { proxy.close(); returnsetAnalyzer } val input InputImage.fromMediaImage(media, proxy.imageInfo.rotationDegrees) scanner.process(input) .addOnSuccessListener { codes - val raw codes.firstOrNull()?.rawValue ?: returnaddOnSuccessListener val now SystemClock.elapsedRealtime() // 同一張碼 2 秒內(nèi)只處理一次避免連續(xù)回調(diào)把連接請求打爆 if (raw lastRaw now - lastTime 2000) returnaddOnSuccessListener lastRaw raw lastTime now onQrDecoded(raw) } .addOnCompleteListener { proxy.close() } } val provider ProcessCameraProvider.getInstance(previewView.context) provider.addListener({ val cameraProvider provider.get() val preview Preview.Builder().build() preview.setSurfaceProvider(previewView.surfaceProvider) cameraProvider.unbindAll() cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, preview, analyzer ) }, ContextCompat.getMainExecutor(previewView.context)) }幾個參數(shù)值得掰開說。STRATEGY_KEEP_ONLY_LATEST是必須的默認的KEEP_ONLY_LATEST在識別器處理不過來時會積壓幀表現(xiàn)為“畫面在動但結(jié)果延遲兩秒”設(shè)成只保留最新幀后識別永遠跟著當前畫面走。FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER表示優(yōu)先挑不低于 720p 的檔位挑不到再往下降比精確匹配穩(wěn)因為不同機型支持的預(yù)覽尺寸差異很大。proxy.close()的位置是另一個血淚點。ImageProxy是有數(shù)量上限的緩沖區(qū)你不關(guān)它幾幀之后分析器就再也不回調(diào)了現(xiàn)象是“第一次能掃之后就死了”。上面代碼把它放在addOnCompleteListener里保證成功失敗都會釋放。lastRaw那個去重也必要識別器一秒能回調(diào)十幾次不去重的話連接請求會被連續(xù)觸發(fā)WifiNetworkSpecifier那邊會直接拋“已有請求在進行中”。3.3 從 Barcode 到 WifiQr中間加一層容錯拿到rawValue之后不要直接扔給parse中間隔一層處理更穩(wěn)。真實場景里二維碼可能是從別的工具導(dǎo)出的前綴寫成WIFI:也可能寫成wifi:末尾可能少分號SSID 前后可能帶空格。我一般做三件事trim()去掉首尾空白、大小寫不敏感地校驗前綴、解析失敗時用寬松模式再試一次比如把沒有T字段的直接當 WPA 處理。private fun onQrDecoded(raw: String) { val result WifiQrParser.parse(raw) if (result.isSuccess) { val qr result.getOrThrow() // 交給下一章的連接分派邏輯 connect(qr) } else { // 明確告訴用戶是哪一步失敗而不是籠統(tǒng)的“二維碼無效” showError(result.exceptionOrNull()?.message ?: 無法識別的二維碼) } }這層的價值體現(xiàn)在錯誤提示上。解析失敗的原因就那么幾種前綴不對、沒有 SSID、加密網(wǎng)絡(luò)沒密碼。把它們分別提示出來用戶才知道是“掃錯碼了”還是“這張碼印壞了”?;\統(tǒng)地報“二維碼無效”用戶唯一能做的就是再掃一次然后你收到第二條同樣的日志。4. 連接鏈路Android 10 這道分水嶺兩套 API 與三條權(quán)限鏈到這一步SSID 和密碼都在手上了剩下的看起來只是“調(diào)個 API”。但 Android 10API 29把舊的WifiManager.addNetwork標記為廢棄并收緊了權(quán)限同一個功能從此分裂成兩條完全不同的實現(xiàn)路徑。更麻煩的是新路徑還分叉成兩個語義不同的 APIWifiNetworkSpecifier是臨時的、應(yīng)用級的、退到后臺可能斷WifiNetworkSuggestion是持久的、系統(tǒng)級的、需要用戶點一次通知同意。選錯了不是連不上是“連上了但過一會兒自己斷了”這種問題最難解釋。4.1 API 29 以下WifiConfiguration 直連注意引號老路徑繞不開WifiConfiguration它的字段賦值有幾個格式要求寫錯了addNetwork直接返回 -1。Suppress(DEPRECATION) fun connectLegacy(wifiManager: WifiManager, qr: WifiQr): Boolean { val config WifiConfiguration().apply { // SSID 與密碼必須帶雙引號包裹這是 WifiConfiguration 的格式要求 SSID \${qr.ssid}\ hiddenSSID qr.hidden when (qr.type) { AuthType.NOPASS - { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) } AuthType.WEP - { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN) allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED) wepKeys[0] \${qr.password}\ wepTxKeyIndex 0 } else - { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK) preSharedKey \${qr.password}\ } } } val netId wifiManager.addNetwork(config) if (netId -1) return false wifiManager.disconnect() val enabled wifiManager.enableNetwork(netId, true) return enabled wifiManager.reconnect() }三個參數(shù)細節(jié)。第一SSID和preSharedKey的雙引號是硬性要求少了的話系統(tǒng)會把它當成十六進制原始的寫法去解析返回 -1 且沒有任何錯誤信息這是最容易卡住新手的地方。第二enableNetwork(netId, true)第二個參數(shù)是attemptConnect必須傳true傳false只是把網(wǎng)絡(luò)標記為可用但不主動連。第三先disconnect()再enableNetwork再reconnect()這個順序不是玄學(xué)某些定制 ROM 上如果不先斷開新網(wǎng)絡(luò)會一直處于“已保存但未連接”的狀態(tài)。還需要注意addNetwork的返回值語義它返回的是系統(tǒng)分配的netId同一個 SSID 且密碼相同的情況下重復(fù)調(diào)用會返回同一個 ID冪等但密碼變了會新建一條配置舊的那條還留著。做門店應(yīng)用的話連上之后我一般會順手把除當前netId之外的舊配置removeNetwork掉否則配置文件越積越多用戶下次手動進設(shè)置會看到一堆重名網(wǎng)絡(luò)體驗很糟。4.2 API 29 及以上Specifier 管當下Suggestion 管長期新路徑的兩個 API 語義完全不同選錯就是線上事故。WifiNetworkSpecifier配合ConnectivityManager.requestNetwork使用特點是會彈出系統(tǒng)選擇框讓用戶確認、連接是應(yīng)用級的、App 進程退到后臺或銷毀時網(wǎng)絡(luò)會被回收、不需要用戶去系統(tǒng)設(shè)置里操作。它適合“掃完碼馬上要用一下”的場景比如掃碼后立刻打開一個局域網(wǎng)配置頁面。RequiresApi(Build.VERSION_CODES.Q) fun connectWithSpecifier(context: Context, qr: WifiQr) { val specifier WifiNetworkSpecifier.Builder() .setSsid(qr.ssid) .apply { when (qr.type) { AuthType.NOPASS - Unit AuthType.WEP - setWepKey(qr.password!!) AuthType.SAE - setWpa3Passphrase(qr.password!!) else - setWpa2Passphrase(qr.password!!) } } .build() val request NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // 關(guān)鍵移除 INTERNET 能力避免系統(tǒng)對這個網(wǎng)絡(luò)做連通性校驗 .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .setNetworkSpecifier(specifier) .build() val cm context.getSystemService(ConnectivityManager::class.java) cm.requestNetwork(request, object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { // 需要把業(yè)務(wù)流量綁到這個網(wǎng)絡(luò)上否則仍走默認網(wǎng)絡(luò) cm.bindProcessToNetwork(network) } override fun onUnavailable() { // 用戶點了取消或密碼錯誤 } override fun onLost(network: Network) { cm.bindProcessToNetwork(null) } }) }removeCapability(NET_CAPABILITY_INTERNET)這行是整個方法里最值得抄的一行。加上它系統(tǒng)不會對這個 WiFi 做“是否能訪問公網(wǎng)”的探測也就不會彈出那個“此網(wǎng)絡(luò)無法訪問互聯(lián)網(wǎng)是否保持連接”的二次確認。門店的 WiFi 很多是內(nèi)網(wǎng)、沒有外網(wǎng)出口不加這行的話用戶會被多問一次很多人就在這里點了“否”然后反饋“你們這個掃碼連不上”。bindProcessToNetwork也不能省。requestNetwork只是“建立”了連接你的 App 默認流量還是走原來的網(wǎng)絡(luò)可能是移動數(shù)據(jù)。不綁的話你以為連上了 WiFi實際請求還是從 4G 出去的訪問局域網(wǎng) IP 自然全超時。WifiNetworkSuggestion則是另一套邏輯RequiresApi(Build.VERSION_CODES.Q) fun suggestNetwork(context: Context, qr: WifiQr): Int { val suggestion WifiNetworkSuggestion.Builder() .setSsid(qr.ssid) .apply { when (qr.type) { AuthType.NOPASS - Unit AuthType.SAE - setWpa3Passphrase(qr.password!!) else - setWpa2Passphrase(qr.password!!) } } .setIsHiddenSsid(qr.hidden) .build() return context.getSystemService(WifiManager::class.java) .addNetworkSuggestions(listOf(suggestion)) }它不會立刻建立連接而是把這張網(wǎng)絡(luò)“推薦”給系統(tǒng)用戶會在通知欄收到一條“某應(yīng)用想要連接到 xxx”的提示同意之后系統(tǒng)就會像對待自己保存的網(wǎng)絡(luò)一樣自動連接。返回值是STATUS_NETWORK_SUGGESTIONS_SUCCESS之類的狀態(tài)碼注意它只代表“建議已提交”不代表“用戶已同意”真正的連接結(jié)果要靠監(jiān)聽ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION廣播。所以選型結(jié)論很清楚掃碼后馬上就要用網(wǎng)絡(luò)配網(wǎng)、局域網(wǎng)控制——用WifiNetworkSpecifier希望用戶下次來門店自動連上——用WifiNetworkSuggestion。兩個都要的話就都調(diào)先 specifier 保當下再 suggestion 保下次。4.3 權(quán)限與版本分派一張表把分支寫清楚運行時權(quán)限的申請順序也有講究。相機權(quán)限和 WiFi 權(quán)限不要一次性全申請用戶看到連著彈三個框會直接拒絕。我的做法是進頁面先要相機掃到碼之后再要 WiFi 相關(guān)權(quán)限這樣用戶的理解鏈路是連貫的——“我要掃碼” → “掃到了現(xiàn)在要連網(wǎng)”。版本分派寫成表更清楚系統(tǒng)版本連接 API必須權(quán)限用戶交互≤ API 28WifiConfigurationenableNetworkCHANGE_WIFI_STATE、ACCESS_FINE_LOCATION無彈窗直接連API 29–32WifiNetworkSpecifierACCESS_FINE_LOCATION、ACCESS_NETWORK_STATE系統(tǒng)選擇框 可能的“無互聯(lián)網(wǎng)”確認API 29–32WifiNetworkSuggestionACCESS_FINE_LOCATION、CHANGE_WIFI_STATE通知欄同意API 33同上兩者NEARBY_WIFI_DEVICES帶neverForLocation同上分派代碼本身很短但要用Build.VERSION.SDK_INT卡在 29而不是 30 或 31——WifiNetworkSpecifier是 29 引入的卡錯版本會在 Android 10 設(shè)備上走到廢棄分支然后靜默失敗。fun connect(qr: WifiQr) { if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) { connectWithSpecifier(appContext, qr) // 順手提交一條持久化建議下次進店免掃碼 if (qr.password ! null) suggestNetwork(appContext, qr) } else { val wm appContext.getSystemService(WifiManager::class.java) connectLegacy(wm, qr) } }一個額外提醒WifiNetworkSpecifier在同一時刻只能有一個活躍請求。用戶連掃兩張不同的碼第二個requestNetwork會拋IllegalStateException。所以調(diào)用前必須先unregisterNetworkCallback掉上一個或者用一個布爾量擋住重復(fù)點擊。這個異常在文檔里寫得很輕線上卻是高頻崩潰點。5. 避坑排查五類掃描后連不上的現(xiàn)場復(fù)盤前面四章講的是“應(yīng)該怎么寫”這一章講“寫完為什么還是不通”。下面五條都是我在真機上反復(fù)遇到過的按“現(xiàn)象 → 原因 → 解決”記每條都對應(yīng)一個具體的日志特征方便你對照自己的現(xiàn)場。5.1 現(xiàn)象掃出來了提示密碼錯誤但密碼肉眼看著沒錯原因基本鎖定在轉(zhuǎn)義還原。生成端把;、,、:、轉(zhuǎn)義了解析端卻沒還原導(dǎo)致傳給系統(tǒng)的密碼里還帶著反斜杠abc\;123被當成密碼去認證當然失敗。還有一種變體解析端做了一次unescape連接層又做了一次\\被還原成\之后又被當成轉(zhuǎn)義符吃掉一個字符密碼少一位。解決在parse返回之前打一條日志把最終password的長度和hashCode打出來跟生成端對比。長度對不上就是轉(zhuǎn)義問題長度對得上但連不上就是加密類型判斷錯了。我現(xiàn)在的習(xí)慣是parse方法里常駐一行Log.d(WifiQr, ssid${ssid.length} pwdLen${password?.length})不為別的就為了這種時候不用改代碼重打包。5.2 現(xiàn)象addNetwork一直返回 -1沒有任何報錯在 API 28 及以下的機型上addNetwork返回 -1 最常見的原因是 SSID 或密碼沒加雙引號。WifiConfiguration.SSID期望的是帶引號的字面量你直接塞Shop-5G系統(tǒng)會嘗試按十六進制解析解析失敗就返回 -1日志里連個 warning 都沒有堪稱黑匣子。解決SSID \${qr.ssid}\preSharedKey \${qr.password}\兩個都要。另外檢查allowedKeyManagement有沒有設(shè)置只填preSharedKey不設(shè)WPA_PSK同樣返回 -1。這兩條占了我早期踩坑記錄的絕大部分。5.3 現(xiàn)象Android 10 上彈窗點了“連接”然后什么也沒發(fā)生requestNetwork的回調(diào)有三個onAvailable、onUnavailable、onLost。很多人只處理了onAvailable用戶點取消走onUnavailable代碼里靜默無聲界面就卡在那里。更隱蔽的一種是onAvailable觸發(fā)了但業(yè)務(wù)請求還是超時——因為沒調(diào)bindProcessToNetwork流量仍然走默認網(wǎng)絡(luò)。解決三個回調(diào)全實現(xiàn)onUnavailable里給明確提示“已取消或密碼錯誤”onAvailable里立刻bindProcessToNetwork(network)onLost里置回null。驗證方法是連上之后訪問一個局域網(wǎng)內(nèi)的固定 IP能通才說明綁定生效。用公網(wǎng)地址驗證是無效的因為公網(wǎng)走哪條路都能通。5.4 現(xiàn)象連著連著網(wǎng)斷了尤其是切到后臺再回來WifiNetworkSpecifier建立的連接生命周期綁在發(fā)起請求的進程上。App 退到后臺被系統(tǒng)回收、或者用戶手動劃掉網(wǎng)絡(luò)就會被移除。這不是 bug是設(shè)計如此。把它當“臨時連接”用沒問題當“連上就一直在”用必然翻車。解決需要長期保持的場景改用WifiNetworkSuggestion讓系統(tǒng)接管這條網(wǎng)絡(luò)的生命周期。如果兩個都要就在 specifier 連上之后再提交一次 suggestion用戶同意之后下次就由系統(tǒng)自動連不再依賴你的進程。這里有個細節(jié)suggestion 提交后用戶沒點同意的話那條通知會一直掛著所以提交時機最好放在“用戶已經(jīng)成功連上一次”之后轉(zhuǎn)化率會高很多。5.5 現(xiàn)象部分機型掃得飛快部分機型死活掃不出來同一張碼某廠商 Android 13 的機器一秒出結(jié)果另一臺 Android 11 的機器舉十秒都沒反應(yīng)。原因通常是相機分辨率協(xié)商失敗——ResolutionSelector請求 1280×720但該機型不支持這個預(yù)覽尺寸組合回退到了 640×480二維碼在畫面里像素太少。另一種可能是該機型的ImageAnalysis默認走了 YUV_420_888 之外的格式InputImage.fromMediaImage轉(zhuǎn)換失敗process一直不回調(diào)。解決ImageAnalysis.Builder().setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)顯式指定格式兼容性最好。分辨率那邊把回退規(guī)則設(shè)成FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER之外再加一層兜底連續(xù) 5 秒沒有識別結(jié)果就主動unbindAll后用 1920×1080 重試一次。這個“重試一次”的邏輯聽著土但在中低端機型上救回過好幾個現(xiàn)場。6. 生成端與自檢自己造碼、批量回連把兼容性驗證做成流水線真機兼容性這件事靠手動一臺臺試是撐不住的。我的做法是把驗證拆成兩段先在生成端造一批“故意刁難”的碼再在連接端跑一遍自動化回連把兼容性問題在發(fā)版前逼出來。6.1 造一批邊界碼把轉(zhuǎn)義和長度全覆蓋正常碼誰都能過邊界碼才是照妖鏡。我一般固定造這么一組SSID 含分號、SSID 含中文、SSID 正好 32 字節(jié)、密碼含反斜杠和雙引號、密碼 8 位與 63 位各一、無密碼開放網(wǎng)絡(luò)、隱藏網(wǎng)絡(luò)。用第 2 章那個build_wifi_qr生成再配qrcode庫出圖。import qrcode from qr_builder import build_wifi_qr # 第 2 章的生成函數(shù) CASES [ (Normal-2G, 12345678, WPA, False), (Coffee;Bar, pa\\ss\word, WPA, False), # 分號、反斜杠、雙引號全覆蓋 (中文網(wǎng)絡(luò)-5G, 12345678, WPA, False), (Open-Guest, , nopass, False), (Hidden-Lab, 12345678, WPA, True), (A * 32, 1 * 63, WPA, False), # SSID 與密碼長度上限 ] for ssid, pwd, auth, hidden in CASES: payload build_wifi_qr(ssid, pwd, auth, hidden) img qrcode.make(payload) img.save(fqr_{abs(hash(ssid)) % 10000}.png) print(payload)跑完先別急著掃碼做一次閉環(huán)校驗把每一條payload喂給你 Kotlin 側(cè)的parse可以把解析邏輯抽成一個純 JVM 模塊跑單元測試斷言還原出的ssid和password跟輸入完全一致。這一步能擋掉絕大部分轉(zhuǎn)義錯誤而且跑一次只要幾百毫秒比真機試快兩個數(shù)量級。6.2 用 adb 把連接結(jié)果撈出來別靠肉眼看真機回連的時候界面提示“連接成功”并不可信因為onAvailable只代表鏈路建立不代表能通信。我會用幾條命令做交叉驗證# 看當前連的是哪個 SSID部分機型需要 root 或調(diào)試版本 adb shell dumpsys wifi | grep -i mWifiInfo | head -n 3 # 看系統(tǒng)里保存的網(wǎng)絡(luò)建議與其狀態(tài) adb shell dumpsys wifi | grep -i -A2 NetworkSuggestion # 確認進程綁定的網(wǎng)絡(luò)配合 App 內(nèi)日志一起看 adb shell dumpsys connectivity | grep -i Bound to第一條命令的輸出里能找到當前SSID:字段跟你要連的那個比對。如果顯示的還是舊網(wǎng)絡(luò)說明bindProcessToNetwork沒生效或者連接壓根沒建立。第二條用來確認 suggestion 是否真的被系統(tǒng)接受——addNetworkSuggestions返回成功只代表提交成功系統(tǒng)側(cè)可能因為重復(fù)提交或策略限制而丟棄。6.3 一個收尾習(xí)慣把“連不上”的日志字段固定下來排查這類問題最耗時間的不是修復(fù)是復(fù)現(xiàn)。所以我現(xiàn)在每接一個 WiFi 相關(guān)需求都會在連接失敗的分支里固定打這幾個字段sdkInt、ssid 長度、password 長度、authType、走的分支legacy/specifier/suggestion、回調(diào)名onUnavailable/onLost。這幾項加起來不到一百字節(jié)但基本能把問題定位到具體某一步不用再問用戶“你手機什么系統(tǒng)”。吃過一次虧某批門店的 Android 11 設(shè)備反饋“掃碼后彈窗閃一下就沒了”日志里只有一句籠統(tǒng)的失敗。后來補上分支標記才發(fā)現(xiàn)是WifiNetworkSpecifier拋了IllegalStateException——上一個請求沒注銷。加了“先unregisterNetworkCallback再發(fā)新請求”之后同類問題再沒出現(xiàn)過。從那以后我每次發(fā)版前都會強制走一遍這套邊界碼加 adb 交叉驗證的流程寧可多花半小時也不想再在群里被追著問“為什么我這臺連不上”。希望幫到你。本文還有配套的精品資源點擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
97视频www| 日本天天干天天操一区| 九九综合久久| 成人自拍三级在线观看| 亚洲精品97p| 极品粉嫩少妇视频| 熟妇人妻精品一区二区视频色欲| 日韩午夜国产| 色噜噜狠狠色综合日日| 新婚人妻扶着粗大强行坐下| 无遮挡又黄又刺激的视频| 快播电影网日韩新片| 美腿丝袜高跟网免费视频免费视频| 麻豆国产视频精品观看| 最新制服中文第一页| 淫骚熟女一区二区三区| 少妇69中文| 国产原创自拍| 国产一区二区精品久久99| 美女AV一区二区| 亚洲精品国产无码高清| 在线观看不卡一区二区三区| 欧美综合网A| 性欧美| 午夜天堂精品久久久久91| 日本人妻最新在线中| 人妻 欧美 中文| 亚洲色人妻综合| AV天黑人| 男人的天堂2019AV| 免费观看性欧美一级| 国产在线综合福利网站| 一本久道久久综合狠狠爱| 亚洲成人av色网| 国产区91柔拿会所技师| 日韩探花精品在线视频| 丝袜美腿操av| 超碰久超碰久| 岛国在线国产| av午夜影院在线播放| 日韩欧美午夜一区二区| 在线观看成人性爱免费小视频| 后入福利| 天天综合-91入口| 97超碰中文| 女人18精品一区二区三区| 亚洲AV免费在线观看| 操逼国产免费| 久久久九九网站| www.狠狠操| 五月天我淫我色av| a男人的天堂久久一级A毛片| 无码外流操逼视频| 欧洲一级性爱视频在线观看| 欧美一区二区三区日韩| 少妇99成人麻豆| 男女做爰猛烈动高潮A片免费应用| 成人无遮挡毛片免费看| 加勒比日本在线| 亚洲最大91网| 欧美一级A一级a爱片久久| 亚洲日韩电影| 国产精品久久久无码AV网站| 婷婷久久五月天| 婷婷久久综合| 日日夜夜噜| 青草成人免费视频一com| 丁香五月天视频| 青青草密桃在线播放| 亚洲欧美爆| 久久无码电影| 婷婷中文网| 婷婷丁香五月激情啪啪| 欧美性爱中文字幕无线码| 欧美亚洲第1页| 97欧美色综合| 日本韩国国产精品一区| 国产东北女人在线视频| 99在线精品视频| 不卡九肏| 美女91网| 99后入| 日逼97| 久久精品店| 夜夜天天噜狠狠爱2021| 999久久久久久久精| 熟女精品一区二区在线观看| 97干在线| 五月婷婷六月天| 丝袜视频一区二区在线播放国产中文| 久热99999| 亚洲九九视频| 亚洲国产综合视频| 欧洲熟妇xxXx欧美老妇裸体 | 操逼网站网站| 欧美一区二区三区日韩| 日本三级韩三级99久久| 国产亚卅97| 青草伊人网| 操逼片中文| 二区熟妇韩日| 一本久道在线综合视频| 日韩AV中文字幕电影| 欧美日韩97在线| 久久久性| 青青草五月天| 中日韩一区二区三区欧美| 亚洲无码久久久久久久| 久久国产99精品72福利| 亚洲天堂久久| 亚洲天堂热| 97这里只精品| 一级@啪啪视频| 强奸乱伦av电影| 中文字幕-区二区三区四区视频中国| 九九九九九九视频| 岛国网址国产| 久久精品国产99久久,亚洲日韩久久日本一区一区三区 | 日本影视久久免费| 亚洲无套久久嗯嗯| 久久丁香久草综合网| 丝袜美腿诱惑亚洲欧美视频在线观看| 久夜操| 久久99精品视频| 狠狠干妹子| 日韩精品人妻一| 99婷婷| 成人资源中文字幕在线观看| 久久婷婷影院| 大香蕉中文网| 五月天婷婷欧美三区| 91综合中文字幕| 在线观看AV不卡| 国产精品福利资源在线尤物| 欧美日韩另类字幕中文| 免费a在线播放v| 国产精品69久久久久孕妇欧美| 国产精品白领在线观看| 亚洲丝袜色| 综合 亚洲 欧美| 日本高清有码网址视频| 自拍视频大全亚洲专媒视频/一区二区三区 | 熟女熟妇伦久久影院毛片一区二区 | 人人模人人看| 亚洲的天堂网| 激情啪啪拍91| 久久系列| 狂操嫩妻视频一区二区三区| 久久精品国产精品一区 | 国产天美传媒精品| 日本亚洲熟女视频| 99re这里只有精品2| 日韩中文字幕视频| 91色人| 婷婷在线视频| 少妇啪啪自拍| 亚洲欧美首页| 嫩草黄页| 亚洲熟妇熟在线电影视频| 欧美最婬乱婬爆婬性视频 | 久久久久久久久久va| 狠插 制服 自拍| 久久东京热成人| 亚州成人a∨| 日韩操逼HD| 999久久久久久久久| 精品一区二区三区最新| 天天做天天爽| 粉嫩不卡一区二区性爱| 性夜影院爽黄A爽免费动漫| 先锋音影AV| 五月激情小说| 久久男女激情视频网站| 1人人看人人摸人人操| 欧美狠狠弄| 一区二区三区国产在线播放 | 91视频综合网| 青青草国产一区二区三区| 男人兔费天堂| 欧亚乱色熟女一区二区| 另类图片五月天| 欧美激情欧美精品| 久久久久13| 20cm女自慰在线日韩欧美| 97超碰公开| 欧美日韩一干二干| 久久手机视直播| 激情看片网站| 男女激烈网站最新| 蜜臀在线视频| 亚欧免费观看视频| 一二三区操逼国产91| 综合欧美色图| 久久久久久综合久久伊人蜜月| 亚州精人品大香蕉| 国产无码三级视频在线观看| 人妻久久一区二区三区 | 亚洲天堂日本| 亚洲drav色图| 少妇高潮九九九九| 国产精品无套内谢| 亚洲最大的综合性av| 日韩簧片免费看| 小骚逼被操的爽不爽| 青青青国产| 亚洲精品 大香蕉| 1024人妻| 亚州情色j区| 色丁香五月婷婷| 爱爱60秒免费视频| 国产久久一区二区午夜| 国产在线视视频有精品| 亚洲欧美日韩免费电影| 可免费观看的av毛片中日美韩| 欧美日动态视频| 99热免费| 婷婷五月天综合网| 欧美性爱一内片一区二区三区| 久久香蕉综合一本到3atv| 亚洲精品国产日韩无码AV永久免| 欧亚三区动漫| www.男人的天堂| 欧美色网络| 欧美亚洲图片| 国产精品点击进入在线影院| 欧美成人黄网色网站| 久久一区二区三区入口| 久久天堂婷婷网| 亚洲成人碰碰| 操逼操操操91| 美女刺激久久国产欧美| 78综合网| A一级色女| 亚洲熟女一区二区| 欧美18老人禁| 久久婷婷综合国际产色怕| 99少妇| 日本布卡一区二三区| 国产97免费视频| 一本色道无码DVD中文字幕| 日本精品网站在线中文| 蜜乳AV色欲AVAV无码| 欧美人与性动交a美精品| 一区二区三区激情在线观看| 男人天堂.AB| 97在线观看免费视频l| 国产精品3| 欧美亚洲特P| 国产 日韩,欧美 自拍| 亚洲做性| 在线视频97| 97超碰精品图片| 久久久九九| 九色黄站| 亚洲一区中文字幕一区| 吉川爱美98堂在线| 91中出视频| 国产a片操逼| 日韩一区二区精品视频| 60秒免费视频| 日本爽爽爽爽爽爽免费视频| 午夜精品视频777| 人妻插插人妻人| 亚洲精品国产熟女久久久| 日韩一二三区| aaa一级黄片| 综合久久99亚洲人妻中文在线| 人妻免费观看| 久久一区二区三区四区五区| 欧亚免费视频| 亚洲情色一区二区三区| 亚洲一区二区三区不卡国产欧美| 亚洲国产成人福利在线观看| 800zy一区二区| 舔人妻中文免费视频| 91爱网| 欧日a| 欧美视频边做饭边橾| 国产天天骚| 99精品九九九九九九| 在线观看中文字幕| 六六久久日韩不卡| 91nbbbbbb| 国产又黄又爽| 国产精品久久发布| 婷婷超| 天天色综合图片| 天堂av最新电影网| 色激情五月天| 啊啊啊水好多| 婷婷色婷婷| 精品丰满熟妇人妻一区| 成人性爱电影网| 大香蕉日亚洲日本亚大| 无码聚合| 亚洲少妇综合| 91久操| 97K超碰在线| 国产精品一区二区黄片| 九九九999久久久网站| 久久亚洲av成人无码国产| 国产日韩中文字幕欧美| 人人搞人人插人人操| 先锋精品av色鲁| 97手机日韩| 青青草视频久久| 91老熟女| 无码视频一区二区| 亚欧性爱ab| 少妇高潮九九九九九九九| 色婷婷亚洲婷婷| 久久香蕉国产线看观看亚洲女人 | 欧美大片91| 欧美美女啪啪视频| 超碰成人公开| 亚州性色| 91久久国外网| 少妇无码av专区线| 熟女91网| 狠狠色伊人亚洲综合网站色| 麻豆AV96熟妇人妻| 成年人一级黄色毛片大全在线观看| 日韩亚洲美州欧洲综三区一品在线| 福利五区| 老色69| 中日亚韩免费视频| www.91视频网| 中文字幕人妻色偷偷久久皮 | 中文字幕免费看| 精品一区二区成人动漫| 97国产综合欧美| 精品国产肉丝袜在线拍国语| 久久无码一区二区二三区性色| 欧美久久草熟女| 婷婷丁香九月| 啊啊啊爽爽| 欧美国产操逼| 欧美黄色图片| 婷婷五月天激情网| 国产精品自在自拍视频| 亚欧无码线免费观看视频| 久久久久久性爱片| 亚洲色图殴美色图激情乱伦| 天天舔日美女视频| 中文97国产| 人妻中文在线| 女人被男人桶爽视频网站| 97超级久久| 丁香五月偷拍| 国产欧美精品日韩区二区麻豆天美| 亚洲成人性爱在线观看| 久久超碰com| 亚洲精品1区| 日韩伦理久 久久 清纯| 婷婷久久大香蕉| 最新国内自拍av免费| 欧美偷拍| 久久精品国产99久久,亚洲日韩久久日本一区一区三区 | 国产成人精品亚洲日本| 亚洲激情综合另类男同| 牛牛AV人人夜夜澡人人爽| 天天搞欧美| 黄色不卡视频| 狠狠色综合网| 婷婷AV一区二区三区| 国产日韩在线播放av| 清纯唯美亚洲综合| 亚洲欧美在线丝袜| 日韩电影中文字幕| 极品色电影院| 91丝袜激情在线| 国产精品国产自产拍高清AV| 激情四射婷婷四五月天| 日韩另类色图| 国语国产操逼伊人AV网| 草草影院最新网址| 黄色激情电影在线观看| 免费无码国产精品v片在线观看| 97网站在线观看 | a啊啊啊啊啊啊啊啊一区二区| 亚洲精品一区二区三区新线路| 2017人人操,人人摸| 中文字幕免费在线观看| 日韩欧美久久婷婷网站| 一区二区不卡| 欧美91精彩| 丝袜美腿欧美| 精品无码一区二区| 人妻天天爽夜夜爽精品2| 久久手机视直播| 翘臀vidoes| 亚洲国产综合久久久性感熟妇| 国产精品久久成人免费| 岛国精品视频在线观看| 激情久久久| 爱爱动态120秒| 日韩AV无码中文一区二区| 99久久无码| 亚洲精品一区二区精华| 日本精品网站在线中文| 日韩欧美字幕亚洲一区二区| 黄aaaaaaaaaaaaaaaaaa色网站| 丁香九月 婷婷| 国产高清在线观看欧美| 婷婷丁香成人| 九九热精品在线| 日韩精品99久久久久久中文字幕| 手机不卡视频不卡在线一二三区| 婷婷色色网| 国产精品老熟女一区二区| 不卡码视频| 中文字幕诱惑制服人妻丝袜美丝袜美| 久久鲁夜| 色九九九九| 一二三四区操操Av| 91福利网在线观看| 69精品久久久久中文字幕| 操人91| 狠狠综合网| 狠狠色五月亚洲91| 思思久热在线精品66| ..日韩av毛片精品久久久| 立川理惠无码一区二区| 嗯啊啊啊轻点视频| 情色五月天就去干| 国产精品点击进入在线影院| 超碰国产在线| 九一综合网| 日韩啪啪视频| 亚欧性爱ab| 欧美日韩在线视频网站| 亚洲国产尤物yw在线观看| 999岛国大片| 天堂8在线新版官网| 人人扣人人操| 熟妇人妻一区二区三在线| 98超碰欧美| 日韩精品一区二区日韩| 亚洲综合码| 亚洲骚逼少妇| 日本色色色视频| 人妻一区久久二区三区色播| 国产自产91区13区| 久久一区二区三区入口| 亚洲精品xxx| 综合久久婷婷| 欧美激情亚洲情色| 91男同| 91老熟女视频| 激情综合网激情五月天| 日韩电影免费网站麻豆视频| 中文字幕久热视频在线| 欧中日成人免费影视| 少妇天堂| 99色视频| 桑老女人九区| 欧美很很操视频| 白丝在线一区| 久久一区二区高清免费| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 麻豆国产尤物AV| 欧美天天综| 狠狠91| 久久久久久午夜男人的天堂| 欧美亚洲系列| 日日夜夜天天| 九一性生活免费视频| 久久透逼视频| 一本久久精品中文字| av天堂精品久久| 曰本91情色| 国产精品久久久久亚洲av| 欧美青青视频| 亚洲AV无码国产精品久久久久| 福利风月五月天影院| 九七超碰| 禁十八久久| 亚洲va有码在线天堂| 9久精品视频在线观看| 国产一级特黄大片处女| 性爱AV天堂| 97精品视频| 欧美日韩222| 亚洲男人久久综合天堂| 国产中午字一暮区| 亚洲欧美精品一区天堂久久| 激情五月天中文字幕色| 国产成人主播| 亚洲中文字幕熟女| 视频二区美腿丝袜制服人妻欧美 | 在线免费观看日韩一区| AV色五月| 欧美综合骚| 黑白配性爱AV成| 99免费视频| 无遮挡男女激烈动态图| 国产偷人妻精品一区二区在线| av三级电影在线播放| 欧美另类自拍| 久操热线| 性爱网站一区二区| 不卡六六在线91| 在线啊啊啊啊| 男女激情黄色网址| 大JI巴好深好爽又大又粗视频| 色色五月婷| 国产91福利小视频在线观看| 欧美最大综合网| 蜜桃久久综合视频| 超碰成人公开| 久久大| 操老熟女AV| 色女网日韩| 久久高清欧美国产| 中文字幕一区二区三区四五区| 黄色一级视| 亚洲色婷婷久久91| 免费视频观看60秒| 亚洲一区二区三区久久 亚洲一区二区| 美欧色综合| 欧美青青视频| 亚洲综合激情五月久久| 国产操操日韩三级黄| 成人国产二区三区在线,男女精品。| 日本中文字幕在线视频| 91bbbbbb| 超碰97导航| AV高清一区| 67194国产| 日本Xx性爱| 欧美片第一页| 亚洲有码视频二区| 亚洲天堂另类| 亚洲色天堂九9| 麻豆国产成人精品| 97色97好| www.色婷婷色综合| 大色综合网| 亚洲va有码在线天堂| 亚洲美女AV无码| 久久国产精品m码| 疯操AV| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 国产精品一级特黄aaa大片在线观看| 加勒比久久av| 无码操逼天堂| 国产性爱欧美性爱在线| 日日A∨| 99综合自拍| 天堂麻豆天美| 网站A V在线| 偷偷人人精品女女久久| 亚洲精品国产熟女久久久| 亚洲熟女乱综合一区二区三区| 国产久久av| 三级色影综合网| 精品人妻15区| 青青青青操国内视频在线| 天堂亚洲精品| 男人天堂新| 亚洲小说视频| 97超碰欧美手机在线| 男人天堂网手机版婷婷| 久久女女| 国产区在线| 色爱亚洲| 青春草莓视频在线观看网址| 中文字幕av亚洲精品| 很很操在线| 日韩在线欧美精品一区二区| 人妻中文字幕精品无码| 操逼逼无码| 深爱五月婷婷| 日本精品88888888| 国产亚洲精品美女| 国产精品久久久午夜夜伦鲁鲁| 久久亚洲不卡一区二区三区 | 亚洲人在线| 精品999日本| 蜜桃中文字日产乱幕4区| 九九热超碰97亚洲最新香蕉| 超碰免费欧美7| 欧美同性恋 的搜索结果 - 91n| 日韩精品三级片长长久久| 福利大香蕉| 91色婷婷综合久久中文字幕二区| 99re99在线视频| 天天内射| 综合97亚洲| 91精品国产长腿丝袜美女| 欧美色另类| 亚洲国产91精品一区二区久久| 97免费在线| 欧美日日操| 丁香五月偷拍| 久久婷婷欧美| 亚洲欧美999| 日韩精品人妻一| www.久久最新地址| 久久男人的天堂国产| 夜夜狠狠躁日日躁色视频| 日本一二三免费久久| 国产美女自拍AV| 色婷亚洲五月在线观看| 特级大荫道BBwBBwBBW| 四虎免费视频| 天堂亚洲欧美| 黄片色区软件| 人妻出轨一区二区三区| 丝袜 中出 制服 人妻 美腿 中文字幕| 9久9久| 亚洲A曰本VA欧美VA视频| 69天堂| 免费观看一区| 久久久久人| 91熟女在线| 五十路一区无码| 97色亚洲| 麻花传媒免费网站在线观看| 天天干天天狼在线视频| 99黄页网站| 免费97视频| 中文字幕一区二区三区四五区| 97日亚洲欧美| 欧美亚洲日韩16色| 78久久久| 久久久一二三四区| 亚洲中文国际强奸字幕| 国产精品一区二区三区在线| 极品国产内射| 国产综合网站在线播放 | 亚洲高潮少妇| 超碰97色色| 丝袜高跟澳门91视频| 啊啊啊慢点| 美女午夜福利免费视频| 丁香婷婷啪啪| 亚洲综合有玛| 风骚少妇视频中文字幕| 亚洲色91| 这里都是精品在线观看| 天天欧美色| 麻豆区久久久久亚| 青青草国产欧美非洲黑人| 18禁免费视频| 后入 亚洲 美女 射| 亚洲天堂人妻一区二区| 美腿丝袜高跟网免费视频免费视频| 黑人中出21连凳花野真衣| 久热伊人| 99热精品免费| 亚洲综合伊人无码久久| 丰满少妇乱子伦精品无| 中文字幕97色| 亲子敌伦对白在线播放| 人妻激情偷乱视频一区二区三区 | 操逼网站网站| 视频二区美腿丝袜制服人妻欧美 | 69人妻精品丰满熟女区| 2017av无码免费无线播| 欧美亚洲色图另类国产| 国产第25页在线观看| 天天插天天操| 91美女高潮| 欧美三级中文字幕hd| 成人三一级一片aaa| 操b网站亚洲无码| 精品人成视频在线观看| 91 丝袜在线| 久久久亚洲Av| 蜜桃精品视频一区二区三区| 91粉嫩萝控精品福利网站_精品影音先锋国 | 午夜舔阴达高潮视频免费看| 在线观看十八禁| 国产91 丝袜在线播放00-百度| 91在线秘 男同| 熟妇熟女一区二三区| 日韩国产在线观看av| 人妻无码视频一区二区三区久久| 日韩av性爱在线播放| 蜜桃臀 后入 一区 二区 三区 在线| 五十路人妻在线| 国产自偷自拍一区| 青青草原av| 中文字幕片| 日本日皮视频逼| 国产白丝精品在线观看| 精品十三区| 五月婷婷激情网| 无码人妻一区二区三区色欲aⅴ| 欧美v亚洲v日韩v最新在线二区| 久久久久密臀一区二区| 中文字幕亚韩| 亚洲AV色图一区| 青娱乐av在线| 五月丁香社区婷婷日韩欧美精品影院| 大香蕉 222| 一块操欧美性爱| 人人操人人搞人人草| 超碰成人人人爽人人爽| 97精品一区二区视频在线观看| 乱伦av麻豆| 老外又粗又长一晚做五次| 欧美亚男人的天堂| 黄污污污污| 亚洲性爱无码乱伦av| 精品免费1| 亚洲不卡AV在线| 亚洲蜜臀精品视频久久| 神马久久中文字幕| 五月婷婷六月色| 久久婷婷五月综合| 五月婷久久| 在线观看黄色电话| 91综合网站| 嗯嗯啊啊用力视频免费| 日韩卡一卡二卡三在线| 国产操操日韩三级黄| 一本久道在线综合视频| 亚洲无码?第一页| 国产美女mm131爽爽爽爽| 欧美操逼熟女| 在线看片国产精品每日更新| 伊人九九九| 国产视频第2页| 日韩精品电影| 亚洲综合草草| 大香蕉99999| 综合伊人网12色| 日本十八禁免费看污网站| 国产无码精品高清| 夜嗨影院| 狠狠操使劲操| 五码视频在线观看| 黄色在线网站| 新版天堂中文资源8在线| www熟女乱伦com| 日韩一性一交一A片俄罗斯| 久久AV无码AV| 亚洲乱伦图片视频| 久久99视频| 大香蕉免| 精人妻无码一区二区三区伊人直播 | WWW4虎| 欧美亚洲厕所精品偷拍91| 亚洲风情在线观看| 日韩免费在线视频观看| 国产精品一二三免费网站| 97色色色综合网站| 人妻91少妇| 亚洲AV无码AV吞精久久久久| 九九玖玖精品| 69久久| 自拍偷拍 高清无码| 欧美亚洲中文字幕| 天天看,天天做| 操死我了嗯嗯嗯| 乱伦熟女论坛| 99这里只有精品| 亚洲 欧美 综合 91| 欧美AAAA黄片| 婷婷伊人綜合中文字幕小说| 伊人精品视频| 日韩无码视频黄色| 亚洲成人av色网| 美女9118禁| 久久五月天婷婷| 久久欧美激情| 长长久久曰曰夜夜成人网| 色97欧美| 色婷婷丁香五月| 日韩日韩日韩-国产乱码精品一区二区| 久久婷婷一区| 99久re热视频精品98| 九久久九九久视频| 日日操天天操| 操国产高清| 日韩精彩免费| 影音先锋每日最新资源在线观看| 婷婷亚洲五月***久久| 国产2.3.4区| 男人天堂免费| 五月丁香影视| 强奸乱伦 亚洲一区| 免费成人在线熟妇网| 翔田千里av一区二区三区| 黄色交缠性感爆操91国产精品免费一区二区三区 | 综合久久9| 国产精品视频电影| 99久久久无码精品国产人| 亚洲综合骚逼| 中文字幕一区日韩精| 亚洲天堂2020| 色五月综合| 伊人五月天婷婷| 亚洲日韩肥臀视频在线观看| 91女日逼| 国产最新小视频在线播放下载| 伊人久久大香线综合无码| 夜夜嗨一区二区三区三州加勒比| 夜夜爽夜夜操| 中日高清无码操逼视频| 97超碰色屌| 97资源免费视频| 中韩中文字幕在线观看| 国产一区在线免费播放| 欧洲亚洲人人爽爽视频| 久久av一级av少妇av高潮| 四虎在线视频| 大香蕉综合网| 日本午夜福利影院| 97看操| 97se亚洲综合自| 欧美强奸一区二区诱惑| 日本999精品| 国产无码久久高清| 少妇二级| 成人在线永久| 国内亚洲高清无码| 91n美女视频| 2017天天插| 欧美精品久久久久久久丰满| 99热精品在线观看| 国产精品69久久久久孕妇欧美| 亚洲 在线| 高清在线偷拍自拍视频| 学生妹天天看| 操逼操逼逼操操逼91 | 欧美日韩国产三级黄色| 日本天堂网| 黑人娇小av在线播放| 蜜臀久久久久久999| 精品少妇高潮久久| 国产欧美亚洲精品a第2页| ′ !γ}丶。。久久精品欧美一区二区三区| 嗯嗯嗯,草死我| 极品另类| 九九九网页| 百度百度日本操逼| 伊人97色天使| 亚欧高清| 婷婷五月天基地| 蜜臀99久| 天天欧美色| 亚洲国产另类在线中文| 精品无吗久久| 免费的很黄很污的全部视频| 欧美亚洲高清不卡| 日本一区二区不卡精品| 色香综合天天影视综合| 97最新在线播放视频| 青娱乐蜜桃臀AV色婷| 日韩精品国产一区二区| 日韩无码嘿咻黑热久| aa片毛片| 99热精品在线观看| 国内外内射高清视频| 国产白领连续中出在线观看| 国产美女口爆吞精视频| 亚洲欧美国产va在线| 亚欧高清v| 亚洲久久久| 欧美 青青草| 亚洲 国产 精品一区| 日日躁天天躁狠狠躁| 狠狠中文字幕| 国产精品亚洲无码| 亚州色站 日韩电影| 九色精品视频导航1| 日韩在线人妻网站| 天天做日日做天天欢。| 中国黄色特级精品一区二区三区片| 黄片免费视频2019| 不卡六六在线91| 女同亚洲欧美一二三区久久电影| 男人天堂新在线| oumeisetupian| 亚洲 欧美 手机在线观看| 亚洲一区二区三区婷婷| 国产25页| 青青草视频久久| 成人a大片在线观看| 蜜臀AV一区二区三区| 九九伊人网| 亚洲无码成人精品| 麻豆一区二区AV天美| 自拍丝袜美腿人妻| 狠狠综合网| 欧美精品日韩久久久九| 超碰人妻久久| 少妇精品久久久| 极品丝袜无码| 午夜精品探花| 国产综合在线视频网站| 亚洲自拍97| 91AV天美在线视频| 欧美色997| 偷拍伦理视频| 欧美精品1区2区3区| 人妻精品一区二区三区| 亚洲情色一区二区三区| 亚洲精品一区二区三区新线路| 国内毛片热久久思思热| 97自拍一区| 超碰亚洲97| 国产精品 久久久精品一牛| 一二三四视频在线社区中文字幕| A片三级无码| 国产精品一区二区手机看片| 99re视频在线播放青草| 亚洲欧美91√| 三级网站超变态精品| 91蜜臀熟女| 激情色播| 亚洲激情在线一区二区| 国模不卡| 26uuu偷拍亚洲欧洲综合| 国产高清自拍视频| 久久人人爽av亚洲精品天堂桃色 | 呻吟 欧美 日本 中出| 五月丁香啪啪啪| 国产三区免费在线观看| 大黄片做爱的大的| 久思思热视频在线观看| 免费看黄片现成| 美国日韩黄片| 爱丝福利| 精品人妻伦一区二区三区久久| 亚洲夜色在线| caorenqi shipin| 亚洲成人久久美女| 欧美日韩操逼嗦吊| 日韩字幕一区| 久久亚州精品成人Av无| 99久久精品欧美国产| 强奸乱伦 亚洲一区| 丰满欧美放荡少妇在线| 美熟女逼导航AV操逼| 亚洲日韩东京热一区| 日韩欧美中文字| 厕所偷拍在线| 色婷婷蜜臀av| 日韩78m视频| 久湿久久 | 午夜视频好爽啊| 性猛交| 人妻铁牛TV| 欧美狠狠干| 日产欧美电影一区二区三区| 国产日韩怡红院| 偷拍盗拍亚洲色图图片| 不卡日本一区二区| 香港澳门日本三级网站| 欧美精品一区二区少妇免费A片| 亚洲在线欧美| 操逼网站网站| 欧美亚洲色图另类国产| 国产亚洲精品一区二区三区| 日韩中文字幕国产| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师黑人潮喷一 | 蜜乳视频网站| 国产精品久久99日日| 国产精品黑人一区二区三区| 欧美午夜视频免费观看| 日韩一区二区三区四区五区| 久久老子无码午夜伦不卡| 老熟女乱子伦中文字幕一区二区 | 欧美色图天堂网m| 天天看综合网| 操操操操网黑人| …中文字幕亚洲乱,97人妻无码费视… | 97久操| 亚洲玖玖爱| 视频不卡中文字幕| 18禁中文字幕| 国产精品一区二区校花| 亚洲h片在线免费观看| 国产福利精品最新在线| 青青青国产| 亚洲女人毛茸茸91| 91操操操操| 福利色色| 殴美日韩m| 99蜜月精品久久| 婷婷超| 国产精品99久久久www| 青青草吊丝| 久久久久久久久久久久黄色 | 怡红院怡春院| 亚洲欧美另类少妇精品| 欧美黑人168页欧美黑人167| 亚洲福利影院一区久久| 国产高清MV操逼视频| 国产AV无码AV| 色九月综合| 色爱亚洲| 在线无码操| 99热官网| 日韩熟女视频二区| 91被操| 色噜噜精品一区二区三| 韩国轻伦国内自拍一区| 97久久超碰亚洲| 波多野结衣先锋影音| 大香蕉伊人网WWWn0n| 日韩传媒在线| 男人天堂东京热| 欧美劲爆视频一区二区| 精品无吗久久| 丁香九月婷婷| 色五月首页| 91激情国产| 五月丁香激情四射| 五月色网| 黄色av播放免不| 久久综合亚洲色1080p| 婷婷综合在线观看| 天天综合网~91| 午夜色婷婷| 亚洲交换| 日本视频在线观看污污污| 极品内射| 欧美A片中文字幕| 欧美综合区| 蜜桃网熟妇| 日本一级二级三级网站| 91欧美另类| 强奸国产精品视频| 九九亚洲精品| 亚洲天堂一区二区久久| 91久久18禁| 8x福利精品第一福利视频导航| 99热9| 熟女少妇一区二区三区| 久久婷婷色| 97鸡把在线视频| 人人艹亚洲| 夜精品久无码| 97人人操人人摸人人爱| 色噜噜人妻av 中文字幕| 91亚洲高清| 九九久久一区二区三区| 一起草三级AV电影在线观看| 伊色综合天堂色97| 张柏芝国产一区在线观看| 狼人综合婷婷激情四射 | 日本东京热久久久电影| 亚洲不卡av在线| 性久久久| 高凊专区人人操| 亚洲精品一二牛牛| 97 视频在线| 370p日韩欧美亚洲精品| 成人影 天天操 亚洲| 国产精品白丝www| 国产免费一区二区三区最新不卡| 90后后入| 亚洲 欧美 天天| 国产丝袜美女在线一区| 综合97亚洲| 国产精品国产拍高清AV| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 成人免费在线网站| 亚洲综合99999| 一区二区三区探花在线观看| 97欧美久久久久久久| 极品极品色影院| 加勒比伊人| 综合天天网| 亚洲五月婷| 欧美黄色手机在线观看| 日本中文字幕一区| 欧美日韩91| 综合av社区| 久久久国产精品人妻丝袜| 操逼啊啊啊91| 91亚洲人| 欧美91精彩| 国产操偷| 97免费视频在线| 中文字幕日韩综合| 大黄片做爱的大的| 风韵犹存大大大大香蕉| 成人色女网| 成人日本视频人妻在线| 九九综合九九综合| 99在线啪| 啊好大好舒服| 国产剧情AV不卡在线观看| 91啪啪| 亚洲AV色图一区| 欧美性战999| 精品少妇一区二区三区在线视频| 少妇熟女视频一区二区三区| 97舔舔| 手机看片1025| 深夜视频| 人妻丝袜肏逼| 泰国AV在线观看| 激情看片网站| 亚洲精品性爱片| av影片在线观看不卡| 欧美精品,四区。五区| 亚洲影院小综合| 天天爽天天爽| 午夜欧美女人操逼| 国产在线强奸视频| 国产97在线 | 亚洲| 人妻大香蕉| www.91色综合| 天堂69亚洲精品中文字| 欧美大的香蕉有线电视视频| 亚洲人久久久网| 白丝AV网站| 国产精品青青草| 亚洲AV无码乱码在线观看性色| 欧美97在线欧| 丝袜美腿91| 色偷综合| 麻豆国产第一| 欧美色997| 热天堂一区二区| 中文字幕aⅴ在线视频| 久久久精品91八戒| dy888午夜老子影视达达兔 | 国产真实子伦对白| 人人妻人人爽| 成人夜夜| 物业黑人 AV一区| 人妻无码久久一区二区三区免费| 综合久久中文字幕综合日韩精品| 亚洲精品97| 亚州男人天堂| 诱惑网综合| 快灬快灬 一下爽蜜桃在线观看 | 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 伊人大香蕉在线| 久久久久无码| 91青视频| 国产精品小视频一区二区三区| 老色鬼成人精品视频下载大在线观看| 久久久久9999精品九九九| 亚洲午夜福利视频| 精品免费视频国产一区| 97超碰碰| 一区二区高清视频| 99re9| 国产资源中文字幕在线| 亚洲成人激情小说视频| 激情婷婷黑人91| 91天美免费| 欧美色图电影| yiqicaoav| 18禁在线视频| 正在播放国产精品一区| 丰满人妻无码一区二区三区| 久久社区一区二区三区| 全免费a敌肛交毛片免费| 国产精品盗摄 偷窥盗摄| 国产97免费视频|