久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码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
返回資訊列表
久久久啊啊啊| 亚洲男人天堂网| 黑人性暴力毛片| 男人天堂欧美| 在线色导航| 尤物网址| 狠狠操狠狠插| 久久精品视频28| 精吧天堂| 欧美综合天天| 国产曰批免费观看久久久| 国产精品视频白浆免费| 美女刺激久久国产欧美| 熟女高潮合集-永久久久-成人AV| 啪一啪免费视频| 亚洲午夜福利视频| 884t在线| 亚洲综合嫩| 精品无码一区二区三区| AV免费在线播放一区| 久青草影院| 欧美性爱一区| 亚洲清纯综合| 亚洲**2021在线观看| 无码国产精品久久久久| 无码91| 北京美女一区二区| 78操B| wwwxxx日本爽| 色婷婷五月天| 人妻熟女一区二区| 亚洲天堂男人天堂| 国产三级电影免费观看| 9 7超碰在线免费观看| 激情久久日韩精品中文字幕麻豆| 天天澡天天爽日日AV| 日韩在线欧美精品一区二区| 色综合九九| 9久久美女首页| 激情综合 婷婷五月 红杏| 秋霞网—男女啪啪亚洲免费体验区 | 美女刺激久久国产欧美| 亚洲天堂一区二区| 亚洲图片色图欧美另类| www四虎| 超碰综合97在线| 国产三级在线现体验区| 91爱综合| 26uuu久久| www.夜夜操| 中文字幕诱惑制服人妻丝袜美丝袜美 | 一本色道久久综合狠狠操| 精品无码一区二区三区色欲| 久久伊人网视频一区二区三区| 超碰97人人乐| 美女写真| 亚州 综合 色图| 男人天堂2030| 六九九九| 屌色在线97视频| 很狠操| 麻豆 欧美 日韩| 亚洲,欧美,综合网| 殴美大黄片| 91中文精品日韩欧美在线 | 人人 操人人 操人人| 国产视频一区二区在线| 美女91AV| 久久五月综合| 国产精品午夜福利| 女人双腿搬开让男人桶| 男人的天堂无码| 狠狠中文字幕| 91老熟女老女人国产老太| 天堂v无码免费视频| 婷婷五月天福利| 大色网久久| 夜夜影视四色| 韩国嫰模上门援交视频| 草草影院最新网址| 伊人网在线观看| 影音先锋乱伦资源| 综合av影片| 欧洲综合无码| 偷拍片久久| 国产成年精品高清在线观看91| 91伊人影视综合| 女人与公拘交酡2020视频| 91女网站| 91影库| 天堂射| 国产精品网址| 超碰97在线中文| 操逼视频免费日韩无码| 欧美春色| 色婷婷综合久久久久中文国产精品一区中文字幕,国产福利电影一区二区三区 | 国产女人成人精品视频| 96超碰网| 97视频在| av天堂手机版追回| 91天天综合日韩欧美| 嗯啊不要在线| 91被操| 丰满搜索结果 -第18页- 久久高清无码 | 亚洲人人夜夜澡人人爽| www.婷婷| 欧美性生活男人的天堂| 中文字幕第23区| 丁香六月东京热| 亚洲美腿丝袜香蕉影视欧美成人| 丁香五月av| 亚洲情色视频| 97干色天堂| 国产精品无码av| 少妇高潮喷水无套久久久久久| 操B在线观看| 尤物视频新赏网鲜网色诱网| 亚洲色图超碰在线| 免费福利视频中文字幕| 欧美大干日韩| 精品一区二区三区蜜桃臀赵总| 一级性爱网| 白丝少妇一区二区| 手机看片1025| 成人免费性爱视视| 亚洲图片 激情小说| 色欲天天综合网| 麻豆天美一区二区| 欧美亚洲高清不卡| 日韩精品一区二区三区四虎影视| 亚洲春色一区二区三区| 91亚洲丝袜| 欧美有码激情视频一区二区三区| 乱抡国产91| 日韩综合色网| 97操97色| 热九九精品| 在线a亚洲视频播放在线| 天堂精品小草| 五月丁香啪啪网| a级免费在线观看| 一级黄碟在线看| 欧美成人午夜免费福利785| 欧美色91| 艳尻美人妻| 91人妻Pr| 八戒无码国产午夜福利| 亚洲精品国语在线播放| 欧美色综合网| 四虎在线免费视频| 欧美亚洲激情小说| 岛国成人av在线播放网址| 天天肏天天干| 日韩有码回春沙龙第一页| 四虎影库国产精品免费| 丁香五月成人| 能在线播放的国产三级| 无码高清操逼网址| 98一区二区精品| 人妻日日干| 国产97亚洲| 日韩不卡网操逼中文字幕日韩| www.色五月| 亚洲成人免费中文字幕| 国产毛片片精品天天看视频| 欧美丝袜亚洲| 精品视频久久区| 久久精品老司| 精品夜夜澡人妻无码| 日韩乱伦影音先锋| 亚洲天堂五月天国产| 欧美日韩亚洲少妇寂寞影院正在播放 | 伊人四虎综合| www.99热在线只有精品| 免费农村成人少妇人妻Aa一区二区视频| 亚洲操人| av日韩在线观看电影| www熟女乱伦com| 欧洲精品一级二级精品综合视频综合 | 上床啊啊啊| 校园春色宗合网| 国产日本熟女顶级一区二区三区视频| 日本天天操| 日本性爱少妇| 影音先锋乱| 日韩AV无码网站| 女色综合| 熟女人妻精品一区二区视频 | 强奸乱伦资源| 自拍视频一区在线观看| 伊人久久综合精品欧美| 亚洲色图欧美色图日韩色图| 黑人美精品 A片| 日韩性爱小视频| 亚州男人天堂| 亚洲一二三四区| 亚洲干B| 欧美骚少妇| 91熟女.com| 91丝袜在线视频| 躁躁日曰躁2020| 激情图片亚洲色图| www.高清无码诱惑一区.com| 欧美日韩精品久久| 亚洲色图美腿丝袜| 加勒比av中文| 色偷偷超碰亚洲| 天天躁狠狠躁av| 中日亚韩免费视频| 国产小u女在线观看| aaaa少妇高潮大片| 天天插天天插| 青娱乐av在线| 欧美视频第二页| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 男人的天堂在线2| 亚州操操穴网| 欧美一二三区四五区| 成人综合网 欧美| 亚洲av总站| 一直超碰| 极品出轨视频网站| 久草加勒比一区在线| 欧美综合网站999| 色欲久久99国产精品久久久久久| 日韩一二三区| 人人操,人人插| 久久黄色视频一区二区三区| 久久久久亚洲熟妇熟女| 亚洲91在线播放影院| 日韩av一级黄片| 自拍鲍鱼一区在线高清观看免费| 色蜜AV| 亚洲精品男人的天堂| 老女人爆菊| 日韩中文字幕熟妇人妻| 97精品综合久久网| 97精品人妻一二三四| 成年在线视频日本亚洲在线视频区精品江靖宇公司 | 超碰激情808| 婷婷香网站| 中出人妻中文字幕91在线| 色69大色97香蕉| 亚洲97超碰| 肏逼视频日本| 国产亚洲日本精品在线| 熟妇在线视频一区二区| 欧美色九九九| 亚州中文字幕超碰97| 久久精品无码熟妇一区二区三区视频导航 | 欧美极品性爱天天射| 欧亚性爱视频免费看| 激情开心五月天| 天堂国产AV| 日韩精品一区,二区 九九...老司机| 亚洲乱熟女一区二区| 成年人黄色| 国产欧美精选自拍一区| 亚洲欧洲美腿丝袜| 碰人碰碰人人开房人肉| 97超碰超碰| 天天摸夜夜添无码小视频| 9999免费精彩视频| 日日黄色三级网站| 99热| 欧美强奸一区二区诱惑| xxx亚洲午夜天堂| 9997se| 国产乱伦视频污| 无码聚合| 插老姨肥穴| 中文字幕第7页| 热久久国产| 99热在线播放| 色哟哟av网址| 人妻天天爽天天爽三区| 天天躁日日躁AAA片李宗瑞| 九九视品黄色| 熟女高潮精品一区二区| 人妻一二三区| 任我爽视频在线观看| 久艹视频在线| 黄色大片免费在线| 久热色情精品| 99re视频在线播放青草| 操逼操逼逼操操逼91| 亚码激情| 中文字幕青青草| 亚一综合久久久久久久久久| 四虎视频在线观看| 啪啪视频免费在线观看| 天天做天天爱| 操老熟女AV| 色视频蜜乳| 婷婷五月天色| 97久久久精品| 强奸乱伦AV网址| 一区二区三区精品黑丝白丝酒店对鸡 | 狼人综合婷婷激情四射 | 人妻丰满熟妇一区二区三| 久久久久久久一级黄色打同平台| 国产天天噜一噜久久久| 免费人成在线观看网站品爱网| 无码免费一区二区三区啪啪| 歐美性天天| 欧美操人视频| 黄页大片在线观看| 亚洲欧美洲综合| 第一高清av中文字幕| 久久久久久久久久久久久久久久9| av影片在线观看不卡| 香蕉久久国产AV一区二区| 国产日韩人人| 亚洲97久久精品亚洲| 91中文精品日韩欧美在线 | 1240青青草一区二区三区视频天爱| 福利在线观看一区二区| 天堂涩涩| 性影在线视频| 日韩无码AB| 欧综合网| 激情六月天| 97se亚洲综合自| 大屁股xxxxx| 女上位精品在线| 人妻 丝袜美腿 中文字幕| 欧亚不卡| 免费少妇一区二区| 99RE在线视频精品,这里只有精品| 五十路熟女人妻一区二区三区四区五| 亚洲麻豆精品二区三区| 欧美色蜜桃97| 99色视频| 97亚洲在线| 亚洲中文字幕网| 黄色成年| 91干熟女| 农村少妇久久久久久久| 青青草日韩无码| 99精品综合久久久久五月天| 日韩乱中文 | 四虎影视永久在线免费| 69人妻精品丰满熟女区| 亚洲熟女精品| 嗯嗯啊啊的视频| 白嫩国模丰满一二三区| 少妇色欲综合网2| 五月丁香影院| 国产一级内射高清视频| av在线人气| 国产又黄又爽又刺激久久久久久| 亚州高清色综合| 精品人妻av在线播放| 九九九热精品| 噜噜吧,噜噜色,噜噜| 台湾佬大香蕉| 久久精品小视频| 天天综合91| 久久久久久久久久久久黄色| 国产www色在线观看| 视频在线观看青青99国产| 久久性视频| 欧美激情精品| 欧美老妇女内射网址| 三级AV入口| 中文字幕精品专区搜索结果91| 亚洲熟女中文字幕在线| 日韩成人人妻网站| 日本人体九九九九九九| 国内偷自视频区视频综合| 综合97久久| 亚洲五月天激情| 91久久青青草原精品| 欧美日韩一干二干| 亚洲各类熟们中文字幕| 日日爱99| 人人操人人射人人干| 涩五月婷婷| 日本中文字幕不卡视频| 男人的天堂三级| 日本有码影片下载| 欧美大香蕉同搞| 亚洲天堂另类| 另类av天堂| 国产亚洲精品第一最新| 亚洲 欧美 色图| 四虎884a| 正在播放:深夜激情大战,自带黑丝袜全力输出骚穴 | 国产精品3| 又黄又爽在线观看视频 | 中文字幕av亚洲在线| 亚洲情色视频| 啊啊啊不要嗯嗯在线观看| 99精彩视频| 高潮的A片激情扒开一区| 九九九九九九综合| 性性欧美| 亚洲不卡AV在线| 欧美操逼熟女| 久久久久久久久999| 久久人妻无码毛片A片麻豆| 丁香六月天| 亚洲啪啪视频一区二区| 在线不欧美| 97久久免费| 五月婷婷深深爱| 97人人操人人摸| 欧美成人一级麻豆| 97亚洲自在精品在线观看| 中文字幕 一区二区 亚洲无码| 91成人精品在线播放| 中英熟女操女| 91超碰丝袜制服| 久久99999| 狠狠狠狠狠干| 欧美成人一区二区三区在线播放 | 久久AV色| 五月天久久婷婷亚洲| 亚欧精品久久久久久久久久久| 亚洲成?V人片在线观看福利| 极品综合| 亚洲天堂久久久久久粉红视频| 亚洲图片偷拍欧美| 国产和美国毛片| 亚洲av热热色| 欧美综合97www| 亚洲五月婷婷| 午夜乱轮操逼视频免费看| 国产精品视屏| 青青青在线高清视频在线一二三四区| 99黄页网站| 97se综合网| 丁香五月激情综合| 久久亚洲av成人无码国产| 亚洲一区二区三区播放在线| 亚洲日韩国产精品| 密臀视频三区免费网站| 成人一级二级| 十八禁电影伊人网| 色偷综合| 91精品免费| 97精品综合久久网| 中国小夫妻勾搭露脸淫荡对白| 中文字幕 一区二区 亚洲无码| 日韩精品99999| 午夜男人一级A片7777| 亚洲av影院在线观看| 久久一区二区高清免费| 国产亚洲精品美女久久久久久2021| 爱妃国产亚洲视频中文字幕| 色香av| 91精品国产91熟女| 青青青在线高清视频在线一二三四区 | 久久婷婷一区| 校园春色美腿丝袜| 校园春色AV天堂| 91无码人妻精品一区二区三区蜜桃| 欧美综合色综合| 91处女在线视频| 色五月AV在线| 18精品一二区| 超碰地址久久| 97综合在线| 在线不欧美| 亚洲色电影在线| 国产精品视频在线观看| 久久久久久性爱免费视频| 91美女视频在线观看| 96精品久久久久久久久| 大香蕉中文网| 久久久96| 97在线视频观看| 精品久| 人妻天天爽天天爽三区| 中文字幕AV乱伦| 自怕偷自怕亚洲精品| 岛国大片在线观看网站入口| 一本一道vs波多野结衣| 最新国产精品久久精品| 丁香五月av| 蜜桃久久久久久久| 人妻内射一区二区在线视频| 亚洲天堂久| 少妇高潮九九九九九九九| 天堂亚洲精品| 国产精品com| 美国精品国产精品| 日韩性爱1级片视频| 强奸乱伦中文字幕AV| 久久亚洲av成人无码国产| 九九综合| 亚洲激情色片| 91天天爽| 在线日韩精品一区二区三区| 午夜福利精品| 99在线精品视频| 中文字幕亚洲欧美在线不卡| 97色论| 国产97综合| 91网站18禁| 日韩无码视频黄色| 中文字幕免费看大片| 伊人久久88国产女| 精品九九九九九九九| 少妇蹲下买菜露大唇0| 春色综合网| 飘花国产午夜精品不卡| 国内三级自拍小视频在线观看| 伊色综合天堂色97| 91国精产品| 色噜噜狠狠色综无码久久合欧美| 97精品一区二区视频| 国产 日韩 欧美高清| 亚洲中文字幕网| 久久久久久91香蕉国产| 91无码人妻精品一区二区三区蜜桃| 日韩免费a级毛片无码a∨| 色婷婷激一区二区三区| 九九热男人天堂| 亚洲青青草| 中国91AV| 国产美女口爆吞精视频| 丁香五月综合| 十八禁一区二区无码观看| 欧美亚洲清纯| 26uuu成人影片| 玖玖色综合| 好舒服视频| 大香蕉中文| 丁香五月激情综合国产| 玖玖资源中文字幕制服丝袜| 人妻熟女一区二区在线视频| 91精品国产91久久福利| 亚洲AV秘 精品久久老牛影视| 美女露胸露奶头| 日本二区不卡| 亚洲制服aⅴ中文字幕| 欧美淫穴| 天天夜夜rb| 国产一区免费午夜视频| 久久HD| 加勒比人妻综合| 日韩成人高清一区二区| 成人午夜小视频手机在线看| av亚洲天堂资源网站| 99在线精品视频| 中文字幕亚洲永久精品| 精品国产污一区二区三区| 国产精品欧美在线观看| 婷婷亚洲五月***久久| 日韩精品怡红院| 九九九精品成人免费视频小说| 国产激情av女片自拍| 欧美A√综合网| 国产高清成人免费视频| 精品性爱无码在线播放| 欧美综合网1| 欧美一区二区福利在线| 欧美天天谢综合网| 大香蕉欧美| 成人情色一区二区| 日本精品加勒比海一区| 99re公开精品免费视频| 亚洲情色在线| 欧美牲| 99ri在线视频| 伊人在线大香蕉视频久久| 国产性久久久| 97 九色| 日韩无码三级影院| 综合网欧| 老司机天天操| www.AV有限公司一区| 日韩激情无码影院| 东京热一区二区三区四区五区六区| 日本综合色图| 美国美女AV在线| 久久超碰网| 嗯啊免费视频| 久久久久久久九九九九| 秋霞视频一区二区 | 97av,com| 人人摸人人干人人拍97| 精品人妻视频一区二区在线播放| 国产中文字幕曰本毛片| 亚洲se电影| 黄色av一区二区在线| 人妻少妇精品无码专区二区密桃| 欧美性爱伊人| 日韩精品午夜操呦呦不卡影院| 国产情侣自拍在线播放| 久草色在线观看| 国产激情在线| 精人妻一区二区三区| 中文字幕成人理论在线| 懂色av中文字幕一区二区三区天美| 久热香蕉精品在线视频| 青青草字幕AV| 蜜桃av综合网发布| 亚洲中字慕不卡| www.激情| 日本色色色网站免费看不卡| 色综合91| 国产又色又粗又黄又爽| 日日A∨| 国产高清MV操逼视频| 东京热AV男人的天堂| 久久一级无码精品毛片6| 欧美丝袜中文字幕07在线| 色综合美国| 老熟女乱伦一区| 国产女主播视频在线观看| 人人操人人狠狠操| 91香蕉国产尤物视频| 日韩钢筋无码高清啾啾啾| 午夜福利激情在线视频| 激情视频图片| 天天综合精品| 久久精品国产亚洲AV清纯| 日日夜夜噜| 精品国产久热在线观看| 色图综合网| 国产一区二区久久| 免费一级视频特黄色大片| 午夜精品久久一区二区| silk lablo在线观看一区二区| 久久久国产成人一区二区三区在线| 不卡在线观看视频| 国产第25页在线观看| a一区二区三区乱码在线| 伊人五月天婷婷| 精品人妻一区二区三区不卡断| 精品制服美女中文一区二区三区| 日韩欧美蜜桃精品久久中文字幕久久| 色综合 加勒比| 亚洲激情欧美色图 | 国产毛片毛片4p懂色| 欧美人与动性人交a| 日本视频在线中文字幕| 国产精品嫩草影院午夜两性| 久久黄色视频一区二区三区 | 欧美双插| 午夜国产综合视频在线观看| 日韩av免费一级电影| 波多野结衣被操50分钟免费视频| 亚洲一级特黄大片在线播放91| 精品性爱一二三区| 久久久久9| 9+1视频网址| 99久久婷婷国产综合精品草原| 污啪啪啪视频| 国产白嫩精品久久| 国产精品丝袜久久亚洲不卡| 欧美另类丝袜熟女| 欧美一级A一级a爱片久久| 五码视频在线观看| 国产综合网站在线播放| 天天操天天插| 国产农村妇女精品一二区| 天堂涩涩| 97精品免费视频网站| 中文字幕人妻资源在线| 国产精品女久久久久av爽| 黄网在线播放| 2025亚洲男人天堂| 加勒比少妇AV婷婷六月天超碰超碰| 亚洲欧美97| 丰满美女一级毛片在线播放| 自拍偷拍 日韩无码| 婷婷成人五月天| 精品无码一二三四区| 大干人妻| J?P?NESEHD熟女熟妇伦| 一区三区啪啪| 日韩99神马视频播放片在线播放| 伊人991| 久久欧美激情| 日本一区视频在线观看| 亚洲日韩精品在线播放| 欧美日韩一干二干| 日本熟妇人妻一区二区三区| 日韩黄片影院| 日韩精品视频在线观看一卡二卡| 毛片视频白嫩| 精品人妻视频一区二区在线播放 | 男人的天堂啪啪啪啪啪蜜桃不卡| 亚洲大色堂| 一区二区视频在看| 三级特黄60分钟播放| 日韩三级视频一区二区三区| www.男人天堂| 亚洲欧美第一页| 国产精品探花在线| 亚 欧 美 综合| 欧亚韩国999| 欧美日韩在线视频网站| 91久久久久久久久18| 久久超碰大香蕉| 亚洲天堂加勒比| 性在久久久久久| 开心六月色| a啊啊啊啊啊啊啊啊一区二区| 无码高清操逼网址| 久久久com| 亚洲,欧美,综合网| 亚洲成aⅴ人片不卡无码| 人妻啊啊人妻啊啊| 亚洲综合另类色图| 日日插夜夜| 日本三级日本三级三级人妇四虎| 97日韩欧美亚洲| 欧美国产精品| 欧美另类色图片| 伊人宅男大香蕉| 人干人人人操人人摸| 日产狠狠干| 美女天天干| 福利操逼| 亚洲乱色视频一区、二区在线| 久久99国产精品| 亚洲精品a人片在线观看视| 91精品成人| 国内毛片欧美香蕉精品| 久久丁香五月天| 东方亚洲在线操逼天堂| 99在线免费公开视频| 一区二区三区 丝袜 高跟 美腿| 97视频在线免费| 国产精品久久久久久久黄无码| 中文乱码99| 91综合中文字幕| 天天干一干| 久草毛片| 亚洲国产成人精品无码专区| 91激情综合| 亚洲国产欧美一区二区潘金莲| 天天操av懂色| 大香蕉欧美| 五月婷婷五月天| 欧美97av| 翔田千里av一区二区三区| 精品视频久久区| 国产精品一区二区校花| 天天看高清麻豆| 欧美性爱第一页久久| 97色插| 久久性爱视频免费看| 亚洲色图91欧美日韩| 97国产|免费| 大香蕉AV在线| 欧美情色亚洲| 日本3级一区二区免费| 香港久久久| www…国产操逼| 四虎影视永久在线观看精品免费网站| 久久久久九九九| 九九热午夜欧亚国产视频| 国产专区第一页| 超碰到97情色| 婷婷五月天激情网| 九草九九九| 天美麻花大全视频| 色噜噜人妻av中文字幕| 国产精品视频白浆免费| 精品熟妇视频一区二区| 亚洲偷拍自拍在线视频| 亚洲交性| 屌逼麻豆| 伊人加勒比| 大香蕉十区| 国产精品黑人一区二区三区| 亚洲欧洲精品成人| 国产91啪| 91无摭挡| 无码少妇精品一区二区60岁老人| 国内一级精品| 极品五月天噜噜| 国产在线播放成人免费| 欧美性爱一区| 久草免费福利在线播放| 爱妻综合网| 综合色播| 五十路熟女人妻一区二区在线观看| 防屏蔽在线视频| jizz啪啪| 日韩欧亚中文在线| 人妻 丝袜美腿 中文字幕| 热久久无毒不卡| 丁香色色网| 国产真实子伦对白| 色欲人妻一区二区在线| 亚洲成人免费中文字幕| 亚洲情色 自拍| 91无人区卡一卡二卡三乱码入口最新版:能让用户有更多选择的选择-经典说说-爱 | 亚洲性猛| 无码日韩网站| 蜜臀久久99精品久久久久久婷婷| 伊人国产av| 无码最新| 中文字幕国产| 97干在线看| 久久久久人妻二区精品叶可怜| 超碰天天久久79| 探花熟女,姿勢到位,體驗感也到位| 日韩在线观看AV| 蜜桃色色网站视频三区| 亚洲春色欧美激情自拍| 校园春色欧美| 欧美日韩情色一区二区| 国产a片操逼| 天欧美在线| 91九久| 人人看欧美性爱| 青青草依人大香蕉| 国产精品 亚洲情色| 天天做日日做天天欢。| 国产精品欧美在线观看| 欧美成人综合| 久热九九| 欧美福利视频啊啊啊啊 | 亚洲字幕一区二区| 国产精品久久久亚洲第一牛牛_在线观看| 老色69| 国产亚洲精品农村妇女| 亚洲在饯| 熟女网站最新| 电影69乱码96| 一类无码操逼视频| 超碰在线免费一区二区三区| 亚洲激情色片| 婷婷丁香五月激情啪啪| 国产美女在线精品免费看| 骚日日av| 和协无码影院| 亚洲AV无码国产成人| 乱欲视频| 日韩精品怡红院| 97天天爽| 国产精品自拍欧美在线| 成人五级久久| 久久老熟女| 精品一区二区三区四区女| 男人夜色天堂ss| 一区二区三区探花在线观看| 国产色产精品在线观看| 美女网站黄页| 国产污视频麻豆传媒一区二区| 97自拍视频在线| 天堂а√在线最新版在线| 超碰久超碰久| 东京热大香焦| 一区二区三区国产精产| 丁香六月激情| 欧美日韩性爱无码| 97无码视频在线播放| 日日躁夜夜躁狠狠躁超爽| 日韩中文字幕2020| 无码heyzo高清一区| 日韩黄色一区二区三区| 日本操逼aaaaa| 亚洲男人的天堂va亚洲男人社| 蘋果手機免費看成人Av| 人妻熟女午夜精品在线| 国产亚洲日本精品在线| 国产精品爱欲| 免费AV中文网在线观看| 久久大香蕉97| 天综合网欧美| 国产肏屁眼视频| 殴美,日韩国产伦精品| 91啪啪视频| 中文字幕精品一区二区精| 伊人天天久久动态图| 另类欧美色| 精品女同一区| 欧美丝袜美女电影一二三四区| 久久久久久大| 99无码| www.zbzhongsen.com| 91成人久久| 淫荡熟女乱伦网| 91精品人妻偷情| 骚女天天综合网| 欧美综合中文| 人妻少妇久久| 久久九操在线观看| 歐美一級亂黃99在綫精品| 中文字幕在线观看丝袜| 国产小u女在线观看| 亚洲一级性爱视频免费看| 高清国产无码av| 9久在线视频只有精品| 东京热大香蕉| 人人妻人人爽| 成人小电影网站tex| 33044男人的天堂深夜备| 午夜精品久久久久久久| 亚洲性猛| 香一区二区三区| 澳门人妻久久| 日本有码影片下载 | 日韩乱码av| 五月天综合在线| 天天干天天干天天| 五月天色综合| 6080yy午夜理论三级一区二区三区无码 | 天天综合网1| 日韩情色AV| 夜精品久无码| 夜夜人妻爽| 国产精品丝袜久久亚洲不卡| 久久97资源 网| 中文字暮97| 欧美 亚洲 综合 制服| 国产亚洲一黄| 97免费在线视频在线观看| 亚洲最大91网| 夜夜高潮夜夜爽高清视频一 | 天操天操夜操夜月操月年年操操| 亚洲人精品午夜不卡| 超碰97在线中文| 福利天天都操| 青青草五月份天| 天天干夜夜鈤| 精品午夜福利| 亚洲男人电影天堂| 极品销魂美女一区二区| 国产美女口爆吞精视频| 天天弄天天操| 91高清无码下载| 国产精品老师| 亚洲综合五月天| 色色色网站| oumeisetu综合| 天美国产精品| 夜夜狼人妻| 久视频在线观看| 亚洲美女色图| 1.igao73.com 加入收藏 免费专区 国产精品 中文字幕 日韩精品 欧美精品 精彩 | 亚洲欧洲日韩天堂av| 日本欧美一区二区三区免费| 一区二区三区 日韩欧美| 亚洲1区| 情色AV电影| 高潮内射在线| 九九九九日本 | 丁香五月综合| 日韩丝袜人妻AV| 久久欧洲| 欧美综合自拍亚洲综合图| 亚州欧美在线| 热思思免费视频| 日韩综合无码色欲vv| 日本亚洲熟女视频| 亚洲欧美精品一区天堂久久| 超AV色女| 久久一二三四不卡 | 神马久久久久眼| 噜噜噜久久亚洲精品色情| 精品欧美日韩在线观看| 国产精品天堂| 久久久精品电影| 色牛牛AV| 熟女啪啪视频| 91偷拍欧美亚洲| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 国产精品日韩在线一区| 亞洲久久直播| 91N欧美| 手机久操欧美综合色码| 黄色成年| 国产无马在线| 偷看洗澡一二三区美女| 69精品少妇一区二区三区蜜桃| 91九色丨国产丨爆乳| 久久夜精品一区二区三区| 哈哈操 大香蕉| 一级二级三级黑人无码| 久精品无码av一区二免费国产在线观看 | 亚洲午夜精品久久久中文影院| 操国产逼| 亚洲欧美在线观看2021| 丁香五月天堂| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 午夜人人操| 最近的最新的中文字幕视频| 久久久久精| 久久久熟妇熟女国产| 农村少妇久久久久久久| 国产精品一二三区18| 欧美做爰无码A片视频| 欧美精品在线观看| 好一吊区二区| 热思思免费视频| 伊人久久婷婷| 亚洲免费97免费| 天天久久久久久| 一级人妻性爱视频| 色情五月综合婷婷| 97天天弄| 老熟妇91| 色欲日韩欧美在线一区| 97视频在线观看播放与子乱对白在线……| 亚洲AV在线资源| 亚洲 暴爽 AV人人爽日日碰| 黄色视频特级毛片| 少妇蜜汁| 在线视频资源| 久久黄色视频一区二区三区| 色情婷婷| 啊啊啊啊啊啊啊在线| 91美女在线| 日本性爱少妇| 男人干美女| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 国产精品一二三| 久久专区| 狠狠色婷婷| 在线情色电影 91大| 久久久久久久免费A片国产成a人亚洲精∨品无码| 最新中文字幕在线亚洲| 午夜啊啊啊| 97狠狠| 综合久久中文字幕综合日韩精品| 国产精品suv一区| 精品无码秘 人妻一区二区| 无遮挡h肉动漫在线观看| 熟女网站最新| 亚洲AV成人精品网站在AV| 男人天堂2019亚洲| 死我十八禁| 日韩国产乱子伦App| 91久久午夜无码鲁丝片久久人妻| 蜜桃午夜视频一区二区| 国产久久av| 一区二区三区蜜桃成人撸久久东京热| 亚洲男人电影天堂| www.超碰在线| 精品一区二区2| 久久91精品国产9丨久久分亭| 超碰97色色| 九九九热| 亚洲有码 视频一区| 亚洲图片 欧美电影| 最新国产亚洲精品精品国产亚洲综合| 亚洲美女色图| 超碰国产精品无码| 人妻精品综合中文字幕在线| 男人天堂欧美| 丁香五月婷婷啪啪| 精品国产乱码久久久久久久| 顶级丝袜熟女一区二区三区 | 蜜臀国产AV中文字幕| 中文字幕免费在线观看| 久精品无码av一区二免费国产在线观看| 欧美A√综合网| 人人操人人摸人人看人人插| 久视频在线观看| 国内偷拍精品一区二区| 看看小穴| 精品人妻一区二区三区日产乱码| 激情综合五月| 久久中文字幕在线观看| 综合色久| 青草成人免费视频一COm| 91亚洲电影| 99色| 亚洲欧美骚| 中文字幕在线24| 78精品| 超碰亚洲97| 99re免费| 蜜臀亚洲中文| 91美女网站| 在线天堂999| 不卡日本一区二区| 91美腿丝袜在线观看| 日日骚一区二区三区| 色99视频| 五月天精品| www.天天干| 夜色91| 国产最新AV| 免费国产电影一区二区| 久草色悠悠在线视频| 天天色天天干天天爱| 亚州春色| 国产精品自在自拍视频| 舔舔啊| 91啪啪视频| 91亚洲欧美激情| 欧美大码在线视频| 久久的免费性爱视频| 99www.bibizy香蕉资源国产一区二区三区高清 | 翔田千里av一区二区三区| 啊灬啊灬啊灬啊灬高潮奶出了免费视 | 99精品无码| 欧美日韩97| 啊啊啊啊啊在线视频| 欧美97在线观看| 91精品免费| 亚洲 欧美 手机在线观看| 九久久精| 99热综合| 中文字幕天堂在线| 亚洲第一色页夜| 婷婷中文网| 91色欧美| 国产人伦精品一区二区三区| 国产精品一区二区久久精品| 成人精品视频| 久久精品国产亚洲AV成人直播| 91综合网在线| 超碰国产情侣自拍网| 国产网红精品| 少妇人妻在线| 国产日本熟女顶级一区二区三区视频 | 国产高清视频无码在线| 中文久久96| 亚洲欧美国产日本一区二区三区| 欧美少妇人妻| 国产精品 亚洲情色| 亚洲制服aⅴ中文字幕| 天天摸天天操视频| 久久久com| 国内偷自视频区视频综合| 欧美亚洲韩国视频十五区| 91狠狠综合久久| 黑人精品XXX一区一二区| 茄子社区国产精品| 天天日天天插| 一级片在线观看高清无码| 欧美女同在线| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 亚洲丝袜二区在线| 亚洲中文字幕妇伦久久| 日逼逼免费看| sewuyueav| 国产超碰在线一区| 五月婷婷久久综合| 欧美亚洲自拍另类人妻| 蜜桃臀一区二区三区久久| 男人亚洲91首页在线| 日韩 欧美 另类 人妻| 午夜操一视频一区| 不卡人妻少妇精品毛片一区23区视频 | 欧美不卡二区| 91爱啪| 色天堂在线观看| 五月丁香啪啪| 亚洲激情在线观看一区| 欧美激情内射| 欧美熟妇视频| www网站黄| 在线观看一级α片刺激高潮视频| 嫩草 我啊~嗯~在线| 亚洲最大的黄色电影网站。| 亚洲五码一区二区三区| 韩国免费播放一级毛片| 国产亚热在线久久|