發(fā)到微信:ADB+PushPlus保姆級教程)
這臺中興F50放在車?yán)锂?dāng)熱點已經(jīng)用了很久說實話我一開始完全沒把它的“短信功能”當(dāng)回事。直到有一次搶票手機里死活收不到銀行驗證碼我才意識到一臺常年插電、塞在角落里的隨身WiFi短信是最容易被忽略的盲區(qū)。既然F50本身跑的是安卓底層又支持ADB調(diào)試那完全可以自己動手做一條“收到短信→實時轉(zhuǎn)發(fā)到微信”的鏈路而且門檻沒有想象中那么高。這篇保姆級教程就是干這個的從ADB開關(guān)開始到PushPlus配置再到一個能長期掛著跑的轉(zhuǎn)發(fā)腳本我會把每一步怎么操作、為什么這么操作、踩過哪些坑都寫清楚。適合完全沒接觸過ADB的新手也適合想把手頭安卓設(shè)備短信能力盤活的朋友。1. 先說清楚這條鏈路到底怎么工作的1.1 F50值得折騰短信轉(zhuǎn)發(fā)的幾類場景中興F50這類隨身WiFi本質(zhì)是一臺帶蜂窩網(wǎng)絡(luò)的安卓設(shè)備。它插上SIM卡之后能發(fā)WiFi、能上網(wǎng)但大多數(shù)人都忽略了它其實也能收短信。放在車?yán)?、工位上、甚至老家?dāng)“固定熱點”長期插電使用時短信就成了一個沒人看的盲區(qū)。我見過最典型的幾個場景一是車載WiFi車停在地庫SIM卡收的驗證碼、通知全堆在設(shè)備里二是雙卡用戶把副卡塞進(jìn)F50副卡綁定的銀行、App驗證碼根本收不到三是把F50當(dāng)“公網(wǎng)IP代理工具”用的朋友更需要第一時間知道SIM卡是否欠費、是否被運營商限制。這些場景下一個能自動把短信推到微信的方案價值就體現(xiàn)出來了。1.2 整條鏈路的技術(shù)原理拆解這條鏈路不復(fù)雜核心就三段F50系統(tǒng)收到短信之后短信會寫入系統(tǒng)自帶的短信數(shù)據(jù)庫電腦或小主機通過ADBAndroid Debug Bridge連接F50定期查詢短信數(shù)據(jù)庫腳本把新增短信提取出來調(diào)用PushPlus的HTTP接口推送到你的微信。很多人一聽“ADB”就覺得是搞機黨才碰的東西其實ADB就是一個調(diào)試通道安卓系統(tǒng)都內(nèi)置支持。你要做的無非是把設(shè)備上的調(diào)試開關(guān)打開讓電腦能通過命令行訪問它然后執(zhí)行一條查詢短信的命令。PushPlus更簡單它是一個微信公眾號推送服務(wù)注冊之后拿到一個token往它的接口發(fā)一個請求微信就能收到消息。整體思路和“用爬蟲監(jiān)控網(wǎng)頁變化”是同一個套路只是把監(jiān)控對象換成了F50的短信數(shù)據(jù)庫。之所以選ADB而不是在F50上裝App主要原因是F50這類設(shè)備的系統(tǒng)是精簡過的想裝一個安卓App反而麻煩而且官方固件也不一定開放安裝入口。ADB是系統(tǒng)級能力不需要在設(shè)備上裝任何東西穩(wěn)定性更高也更符合“長期無人值守”的需求。整個方案的維護成本基本只有那一臺負(fù)責(zé)跑腳本的電腦或NAS。2. 環(huán)境準(zhǔn)備與ADB工具安裝2.1 下載ADB Platform-ToolsADB不是Windows自帶的需要單獨下載Google官方的Platform-Tools。打開Android開發(fā)者官網(wǎng)的Platform-Tools下載頁面developer.android.com/tools/releases/platform-tools選Windows版本解壓到一個路徑比如D:\platform-tools。解壓之后你會看到一堆exe和dll文件其中adb.exe就是核心程序??梢韵冗M(jìn)目錄打開命令行輸入adb version驗證一下能不能跑。這一步不需要安裝任何東西解壓即用但要注意路徑里別帶中文和空格后續(xù)寫腳本調(diào)用時省心很多。2.2 配置環(huán)境變量讓系統(tǒng)全局認(rèn)識adb如果不配環(huán)境變量每次使用ADB都得cd到解壓目錄或者寫全路徑很容易出問題。配環(huán)境變量是為了讓W(xué)indows在任何目錄下都能直接執(zhí)行adb命令。操作步驟是右鍵“此電腦”選“屬性”點“高級系統(tǒng)設(shè)置”在“高級”標(biāo)簽頁里點“環(huán)境變量”在下方的“系統(tǒng)變量”里找到Path雙擊編輯新建一行填D:\platform-tools確定保存。然后重新打開一個cmd窗口執(zhí)行adb version如果能看到版本號就說明配置成功。這里有個小坑環(huán)境變量改完之后之前已經(jīng)打開的cmd窗口不會生效必須新開窗口。2.3 安裝Python用什么跑腳本后面的轉(zhuǎn)發(fā)腳本我會用Python寫因為語法簡單、輪詢和HTTP調(diào)用都很方便Windows、Linux都能跑。去python.org下載Python 3.x版本安裝時務(wù)必勾選“Add Python to PATH”不然命令行里python會提示找不到命令。裝完后新開cmd執(zhí)行python --version確認(rèn)。如果你手頭已經(jīng)有Node.js或者其他語言環(huán)境腳本邏輯也可以移植但沒必要折騰。教程里的腳本是完整可跑的直接用Python最穩(wěn)妥。跑腳本的機器可以是普通電腦、舊筆記本、軟路由、NAS只要能和F50處在同一個局域網(wǎng)、能訪問外網(wǎng)就行。3. 中興F50開啟ADB調(diào)試的完整操作3.1 進(jìn)入開發(fā)者選項找到ADB開關(guān)中興F50的ADB開關(guān)不在默認(rèn)菜單里一般藏在開發(fā)者選項里。先把電腦或手機連上F50的WiFi瀏覽器打開它的管理后臺常見地址是http://192.168.0.1部分固件版本是http://192.168.1.1以設(shè)備背面的標(biāo)簽為準(zhǔn)。后臺登錄進(jìn)去之后找“設(shè)置”或者“系統(tǒng)設(shè)置”菜單里面一般能看到“開發(fā)者選項”。如果找不到別急著放棄很多中興設(shè)備需要連續(xù)點擊“固件版本號”或者“關(guān)于本機”里的版本號5到7次才會解鎖開發(fā)者選項這招和手機解鎖開發(fā)者模式是一個邏輯。部分固件還會把“ADB調(diào)試”和“USB調(diào)試”分開命名本質(zhì)上都是同一個開關(guān)把它打開就行。如果后臺實在找不到也可以試一下中興官方的“中興智聯(lián)”App工具箱里偶爾會有調(diào)試相關(guān)入口但不同固件差異較大以你手頭那臺的界面為準(zhǔn)。3.2 USB連接電腦與驅(qū)動處理開啟ADB開關(guān)之后用USB數(shù)據(jù)線把F50連到電腦上。這里強烈建議先試USB連接因為無線連接經(jīng)常因為F50沒配對碼而卡住USB是最直接的通道。連接后打開cmd執(zhí)行adb devices。如果列表里出現(xiàn)設(shè)備的序列號狀態(tài)是device那就是連接成功可以直接跳到下一節(jié)開無線ADB。如果提示adb不是內(nèi)部或外部命令是你環(huán)境變量沒配好如果設(shè)備列表為空優(yōu)先考慮換一根數(shù)據(jù)線——很多線只能充電不能傳數(shù)據(jù)。再不行就右鍵“此電腦”進(jìn)設(shè)備管理器看有沒有帶黃色感嘆號的未知設(shè)備有的話需要裝中興的USB驅(qū)動或者手動更新驅(qū)動指向你解壓的Platform-Tools目錄里的驅(qū)動文件。F50一般沒有屏幕所以插上USB后不會像手機那樣彈出“允許USB調(diào)試嗎”的對話框它會默認(rèn)允許這一點和手機不太一樣。3.3 用tcpip模式開啟無線ADBUSB能連上之后要長期跑腳本總不能每次都插著線。ADB支持通過WiFi連接也就是無線調(diào)試模式把設(shè)備轉(zhuǎn)到TCP/IP監(jiān)聽模式就行。USB連接狀態(tài)下先執(zhí)行adb tcpip 5555這條命令告訴F50在5555端口上監(jiān)聽ADB。然后拔掉USB數(shù)據(jù)線讓電腦連上F50的WiFi熱點或者路由器下同一局域網(wǎng)執(zhí)行adb connect 192.168.0.1:5555這里的IP是F50的局域網(wǎng)IP一般就是管理后臺那個地址。執(zhí)行完再adb devices能看到類似192.168.0.1:5555 device的輸出就說明無線ADB已經(jīng)通了。需要注意一點如果F50的系統(tǒng)版本是Android 11以上“無線調(diào)試”功能可能會有配對碼機制直接用adb connect可能報錯。但F50這類精簡設(shè)備通常用adb tcpip 5555的方式就能繞開配對限制這也是為什么建議先用USB連接。如果遇到cannot connect先確認(rèn)電腦和F50在同一個WiFi下再試試重啟ADB服務(wù)端adb kill-server然后adb start-server。4. 驗證ADB能讀到短信4.1 常用ADB命令速查連上ADB之后先用幾條常用命令確認(rèn)設(shè)備狀態(tài)和系統(tǒng)環(huán)境順便也能排查后續(xù)問題。這里整理了一個速查表都是整個方案里最常用的命令作用adb devices查看已連接的ADB設(shè)備列表adb connect 192.168.0.1:5555無線連接指定設(shè)備adb shell content query --uri content://sms/inbox查詢收件箱短信adb shell dumpsys telephony.registry查看SIM卡狀態(tài)、信號等adb logcat -d抓取系統(tǒng)日志排錯很常用adb shell uiautomator dump導(dǎo)出當(dāng)前界面UI層級后面權(quán)限受限時會用到dumpsys和logcat在正常運行時不需要但一旦遇到“讀不到短信”“設(shè)備連不上”這類問題它們就是排查利器。完整命令記不住也沒關(guān)系先把adb devices和content query這兩條記住就夠用了。4.2 核心讀取命令與輸出解析驗證能不能讀到短信直接執(zhí)行adb -s 192.168.0.1:5555 shell content query --uri content://sms/inbox --projection _id,address,body,date這條命令的意思是查詢系統(tǒng)短信數(shù)據(jù)庫的收件箱只取_id短信ID、address發(fā)件號碼、body短信內(nèi)容、date時間戳四個字段。如果F50里已經(jīng)收到了短信輸出會是類似這樣的格式row: 0 _id12, address10086, body您的驗證碼是123456, date1700000000000 row: 1 _id11, address95588, body消費提醒支出58元, date1699999999000每行是一條短信row: 0表示第0條后面的鍵值對就是字段內(nèi)容。注意date是毫秒級Unix時間戳需要除以1000才能轉(zhuǎn)換成正常時間。只要能看到這類輸出說明ADB權(quán)限沒問題可以進(jìn)入下一步。4.3 一個必須繞開的坑命令傳參與中文亂碼如果你是在Windows的cmd里直接手敲這條命令大概率會遇到兩個問題。第一個問題是--sort_order參數(shù)。很多人想用date DESC按時間倒序排列但直接在命令行里寫--sort_order date DESCadb會把date和DESC當(dāng)成兩個獨立參數(shù)傳給設(shè)備的shell查詢會直接報錯。正確姿勢是加反斜杠轉(zhuǎn)義空格--sort_order date\ DESC。但這里不建議用排序參數(shù)后面Python腳本里改成只按ID增量判斷新短信反而更簡單可靠。第二個問題是中文亂碼。F50的短信內(nèi)容默認(rèn)是UTF-8編碼Windows的cmd默認(rèn)是GBK編碼直接打印很容易顯示成亂碼。臨時解決辦法是在cmd里執(zhí)行chcp 65001切換到UTF-8代碼頁治本的辦法是用Python腳本讀取運行時指定UTF-8編碼。后面腳本部分會專門處理這個問題手敲命令時看到亂碼別慌不代表數(shù)據(jù)壞了。5. PushPlus配置與測試5.1 注冊獲取tokenPushPlus是一個微信公眾號消息推送服務(wù)它的邏輯是你掃碼關(guān)注它的公眾號然后它給你一個token你調(diào)用它的HTTP接口消息就會通過公眾號推送到你的微信。對個人來說這就是最簡單的“免費服務(wù)器推送通知”方案不需要自己搭公眾號也不需要考慮微信接口的簽名算法。打開PushPlus官網(wǎng)pushplus.plus用微信掃碼登錄登錄后控制臺首頁就能看到你的token一串字符復(fù)制保存好。整個教程只需要一對一推送功能也就是把消息推給你自己不需要建群組。其實PushPlus還支持一對多群組、微信模板消息等高級功能但對短信轉(zhuǎn)發(fā)場景來說一對一token就完全夠用了。5.2 用瀏覽器直接測試推送拿到token之后先不要急著寫腳本用瀏覽器手動測一次確認(rèn)推送鏈路通不通。把下面URL里的token換成你自己的直接粘貼到瀏覽器地址欄訪問https://www.pushplus.plus/send?token你的tokentitle測試短信contentHelloWorld如果一切正常頁面會返回一串JSON類似{code:200,msg:請求成功,data:發(fā)送成功}同時你的微信會收到一條來自PushPlus公眾號的消息。這一步的目的是把故障范圍縮小只要推送通后面腳本出問題就只可能是讀取短信或傳參環(huán)節(jié)。5.3 關(guān)于推送頻率和參數(shù)格式的提醒PushPlus免費版是有調(diào)用頻率限制的具體限流策略會動態(tài)調(diào)整但長期高頻請求確實有被限的風(fēng)險。短信轉(zhuǎn)發(fā)場景本身頻率很低一天撐死幾十條完全在合理范圍內(nèi)。但如果腳本邏輯有bug比如把同一批歷史短信反復(fù)推送就可能觸發(fā)限制。還有一點要注意content參數(shù)里如果有中文或換行在URL里直接拼接可能出問題需要做URL編碼。瀏覽器手動測試時內(nèi)容簡單無所謂Python腳本里會用urllib.parse.urlencode自動處理這屬于“代碼幫你避坑”的部分。另外每次調(diào)用后檢查返回的code字段是否等于200這是判斷推送是否成功的標(biāo)準(zhǔn)。6. 用Python腳本實現(xiàn)自動轉(zhuǎn)發(fā)6.1 腳本整體邏輯與輪詢策略腳本的思路很直接每隔幾秒用ADB查一次短信數(shù)據(jù)庫把新出現(xiàn)的短信ID和之前見過的ID做對比有變化就推送最后把最新ID保存下來。為什么用ID判斷而不是時間因為同一秒內(nèi)可能收到多條短信只用時間戳對比會漏掉短信數(shù)據(jù)庫的_id是單調(diào)遞增的用ID做增量判斷最可靠。輪詢間隔我建議設(shè)置成3到5秒。太短會頻繁喚醒ADB通道增加設(shè)備功耗和通道不穩(wěn)定風(fēng)險太長又會明顯延遲短信到達(dá)微信的時間驗證碼場景會急死人。3到5秒基本是“感受不到延遲”的平衡點。初次運行時的歷史短信處理也是個關(guān)鍵點。F50里可能已經(jīng)存了幾十條甚至上百條舊短信如果腳本啟動時一股腦全部推送微信會炸。這里用一個配置項SKIP_EXISTING控制第一次運行時自動把當(dāng)前數(shù)據(jù)庫里所有短信ID都標(biāo)記為“已讀”從下一次輪詢開始才推送新增短信。這個細(xì)節(jié)很重要第一次跑腳本之前一定要確認(rèn)開關(guān)是打開的狀態(tài)。6.2 完整可運行的轉(zhuǎn)發(fā)腳本下面這個腳本可以直接保存為sms_forward.py運行。我盡量把注釋寫詳細(xì)配置項都集中在最上面方便你根據(jù)自己的環(huán)境改。# -*- coding: utf-8 -*- import subprocess import time import re import json import os import urllib.request import urllib.parse from datetime import datetime # 配置區(qū) DEVICE_IP 192.168.0.1 # F50的局域網(wǎng)IP改成你實際的 ADB_PORT 5555 TOKEN 你的pushplus_token # pushplus.plus 后臺復(fù)制 POLL_INTERVAL 5 # 輪詢間隔單位秒 SKIP_EXISTING True # True啟動時跳過歷史短信只推新增 STATE_FILE seen_ids.txt # 已處理短信ID的存檔文件 # SEEN_IDS set() if os.path.exists(STATE_FILE): with open(STATE_FILE, r, encodingutf-8) as f: for line in f: line line.strip() if line.isdigit(): SEEN_IDS.add(int(line)) # 正則解析 content query 輸出 LINE_RE re.compile(r_id(\d),\s*address([^,]*),\s*body(.*),\s*date(\d)) def run_adb(args, timeout10): cmd [adb, -s, f{DEVICE_IP}:{ADB_PORT}] args try: res subprocess.run( cmd, capture_outputTrue, textTrue, encodingutf-8, errorsreplace, timeouttimeout, ) return res.stdout except subprocess.TimeoutExpired: return except FileNotFoundError: print([錯誤] 找不到 adb 命令請檢查環(huán)境變量) return def is_connected(): try: out subprocess.run( [adb, devices], capture_outputTrue, textTrue, timeout5 ).stdout except Exception: return False return f{DEVICE_IP}:{ADB_PORT} in out def query_sms(): out run_adb([ shell, content, query, --uri, content://sms/inbox, --projection, _id,address,body,date, ], timeout15) return out def parse_sms(text): events [] blocks re.split(rrow: \d , text) for block in blocks: m LINE_RE.search(block) if not m: continue sms_id int(m.group(1)) address m.group(2).strip() body m.group(3).strip() date_ms int(m.group(4)) events.append((sms_id, address, body, date_ms)) return events def send_pushplus(title, content): params urllib.parse.urlencode({ token: TOKEN, title: title, content: content, }) url https://www.pushplus.plus/send? params try: with urllib.request.urlopen(url, timeout10) as resp: data resp.read().decode(utf-8) obj json.loads(data) if obj.get(code) 200: return True, return False, data except Exception as e: return False, str(e) def save_state(): with open(STATE_FILE, w, encodingutf-8) as f: for sid in sorted(SEEN_IDS): f.write(str(sid) \n) def mark_existing_sms(): # 首次運行時把當(dāng)前所有短信ID都標(biāo)記為已讀不推送歷史記錄 out query_sms() for sms_id, _addr, _body, _date in parse_sms(out): SEEN_IDS.add(sms_id) save_state() print(f[初始化] 已標(biāo)記 {len(SEEN_IDS)} 條歷史短信為已讀) def poll_once(): out query_sms() if row: not in out: print(f[{datetime.now():%H:%M:%S}] 未讀短信為空或ADB連接異常) return False events parse_sms(out) new_events [e for e in events if e[0] not in SEEN_IDS] if not new_events: return True # 按ID升序推送避免同批次多條短信順序錯亂 for sms_id, address, body, date_ms in sorted(new_events, keylambda x: x[0]): title fF50短信 {address} content f來自 {address} 的短信\n{body} ok, err send_pushplus(title, content) if ok: print(f[{datetime.now():%H:%M:%S}] 已推送短信 {sms_id} 來自 {address}) else: print(f[{datetime.now():%H:%M:%S}] 推送失敗 {sms_id}: {err}) SEEN_IDS.add(sms_id) time.sleep(0.5) # 多條短信之間稍作間隔避免觸發(fā)限流 save_state() return True def main(): if SKIP_EXISTING and not os.path.exists(STATE_FILE): mark_existing_sms() print(開始監(jiān)控短信...) while True: try: if not is_connected(): print(設(shè)備不在線嘗試重連...) run_adb([connect, f{DEVICE_IP}:{ADB_PORT}]) time.sleep(3) continue poll_once() time.sleep(POLL_INTERVAL) except KeyboardInterrupt: print(\n手動退出) save_state() break except Exception as e: print(發(fā)生異常:, e) time.sleep(POLL_INTERVAL * 2) if __name__ __main__: main()直接運行之前先把你自己的DEVICE_IP和TOKEN替換進(jìn)去。在項目目錄執(zhí)行python sms_forward.py正常啟動后控制臺會先提示已標(biāo)記歷史短信然后每隔幾秒靜默輪詢。此時給F50里的SIM卡發(fā)一條短信幾秒鐘內(nèi)微信就會被推送。6.3 部署成后臺服務(wù)讓它長期掛著跑如果你只是想試一下開著cmd窗口跑就行。但長期用總不能讓電腦一直掛著窗口。這里給幾種簡單的部署思路。Windows用戶最簡單的做法是寫一個start.bat內(nèi)容只有兩行chcp 65001 python D:\sms_forward\sms_forward.py把這個bat放進(jìn)開機啟動文件夾shell:startup開機就自動跑。想更規(guī)范的話可以用nssm把Python注冊成Windows服務(wù)故障自動重啟但說實話對個人場景有點殺雞用牛刀了。家里有NAS或者軟路由的話把腳本和Python環(huán)境放到機器上用systemd管理就夠了示例單元文件和腳本同名即可路徑按自己環(huán)境改典型的守護配置是Restartalways。關(guān)鍵邏輯都一樣讓腳本進(jìn)程在后臺持續(xù)運行斷了能自動拉起。7. 常見問題與排錯實錄7.1 adb devices 為空或一直顯示 unauthorizedadb devices什么都沒輸出先想三件事線是不是數(shù)據(jù)線、驅(qū)動裝沒裝、F50的ADB開關(guān)是不是真的開了。線的問題我前面強調(diào)過很多Type-C線只能充電換根數(shù)據(jù)線瞬間就好。驅(qū)動的問題去設(shè)備管理器看有沒有未知設(shè)備有就裝官方ADB驅(qū)動。F50這類隨身WiFi沒有屏幕一般不會出現(xiàn)手機上那種需要點“允許調(diào)試”的彈窗但如果你的固件比較特殊連上USB后還是需要確認(rèn)那只能找一臺有顯示器的環(huán)境解決。unauthorized狀態(tài)是授權(quán)沒通過主要是設(shè)備端拒絕了調(diào)試請求。但F50精簡系統(tǒng)里授權(quán)彈窗可能被隱藏了這時候可以嘗試adb kill-server再adb start-server重啟ADB服務(wù)端或者關(guān)掉開發(fā)者選項里的ADB開關(guān)再重新打開。如果還是不行檢查一下F50系統(tǒng)時間是否準(zhǔn)確時間偏差過大會導(dǎo)致授權(quán)證書校驗失敗。7.2 無線連接被拒絕或掉線adb connect 192.168.0.1:5555返回cannot connect大概率是設(shè)備沒在監(jiān)聽5555端口。有些固件重啟之后會恢復(fù)成默認(rèn)狀態(tài)USB調(diào)試開關(guān)和tcpip監(jiān)聽都會失效需要重新插一次USB執(zhí)行adb tcpip 5555。所以腳本里我加了斷線自動重連邏輯但connect命令對“端口沒監(jiān)聽”的情況是無效的該插線重來還是得來一次。還有一種情況是F50開啟了休眠省電導(dǎo)致WiFi/ADB斷掉。隨身WiFi為了續(xù)航空閑時會進(jìn)入低功耗狀態(tài)ADB通道自然就斷了。解決思路是盡量保持充電狀態(tài)同時在后臺設(shè)置里把“自動休眠”關(guān)掉或者把省電模式關(guān)掉。這個坑在長時間掛機場景下很常見我一度以為腳本寫錯了后來才發(fā)現(xiàn)是設(shè)備自己睡著了。7.3 讀不到短信提示Permission Denial終端輸出類似SecurityException: Permission Denial的時候說明當(dāng)前shell用戶沒有訪問短信ContentProvider的權(quán)限。中興F50原廠固件我實測大多數(shù)能直接讀但個別定制固件確實鎖了這塊。如果遇到先檢查命令里的uri是不是content://sms/inbox有時精簡固件把收件箱uri改成了content://sms去掉/inbox再試一次。兜底方案就是之前提到的adb shell uiautomator dump。原理很簡單通過ADB把系統(tǒng)短信App當(dāng)前界面的UI層級導(dǎo)出來然后從XML文本里匹配短信內(nèi)容。前提是F50上有短信App界面而且你得先把界面切到短信列表頁操作起來相對笨重但面對權(quán)限鎖死的固件這可能是唯一不刷機的路子。我的建議是優(yōu)先折騰固件里的開發(fā)者選項權(quán)限兜底方案只作為備選。7.4 短信內(nèi)容解析亂碼或字段錯位腳本讀取短信時用encodingutf-8處理adb輸出Windows控制臺用chcp 65001這兩步做到位基本不會亂碼。如果短信body里本身包含逗號我的正則解析用的是貪婪匹配只要date字段在行尾body里的逗號不會影響結(jié)果。但萬一某條短信正文里也含有, date這種字符串就會截斷概率極低真遇到可以在正則上繼續(xù)加限制。字段錯位多半是因為某些短信的address為空比如一些運營商服務(wù)短信發(fā)送號碼顯示為null命令行輸出可能直接省略這個字段導(dǎo)致正則沒匹配上。所以腳本里如果看到某條短信沒推先打開ADB手動查一次原始輸出看看是哪一行字段缺失。7.5 PushPlus收不到消息或返回異常瀏覽器測試推送成功但腳本推送失敗最常見原因是你改了token之后腳本沒重啟還拿著舊token在跑。另一個坑是content參數(shù)沒編碼腳本里用urlencode已經(jīng)處理了但如果你手寫curl測試記得對中文內(nèi)容做URL編碼。返回400或429則表示請求參數(shù)錯誤或觸發(fā)頻率限制先看返回的msg字段具體內(nèi)容再針對性調(diào)整。從PushPlus服務(wù)器到微信完成展示會有幾秒延遲這是正?,F(xiàn)象只要腳本沒報錯耐心等一會兒就行。如果長時間收不到去PushPlus公眾號的推送記錄里翻一下能看到歷史推送詳情這個功能排查很管用。7.6 一定要留意的安全底線ADB調(diào)試是一個高權(quán)限通道開啟后局域網(wǎng)內(nèi)的其他設(shè)備理論上都能嘗試連接你的F50。雖然連接ADB通常需要授權(quán)但adb tcpip 5555模式下如果設(shè)備端寬松授權(quán)風(fēng)險還是存在的。建議只在可信內(nèi)網(wǎng)里開啟不要為了遠(yuǎn)程管理把F50放到公網(wǎng)可達(dá)的環(huán)境更不要把5555端口映射出去。PushPlus的token等同于是你的“微信推送鑰匙”任何人拿到都能往你微信發(fā)消息不要上傳到公開的代碼倉庫。腳本里保存的短信內(nèi)容可能包含驗證碼、賬單、個人隱私運行腳本的機器要做好基本的安全防護不用的歷史短信數(shù)據(jù)定期清理。這套方案的本質(zhì)是把設(shè)備的私密信息轉(zhuǎn)發(fā)到你的私人微信安全這根弦繃緊一點沒壞處。最后聊一點我自己的實際體會。這套轉(zhuǎn)發(fā)方案跑起來之后最大的感受是“存在感極低”它不會像微信通知那樣頻繁打擾你只在真正有短信的時候響一下這一點非常符合我的預(yù)期。但折騰過程中真正花掉我最多時間的不是腳本邏輯而是排查F50無線連接掉線的問題——設(shè)備一休眠所有自動化都白搭所以后來我把F50固定插電又關(guān)掉省電模式才算真正穩(wěn)定下來。如果你也打算長期依賴這套方案我的建議是第一次部署多花一點時間把狀態(tài)保存、斷線重連、歷史短信跳過這幾個環(huán)節(jié)測透后面就真的可以做到“忘了它的存在”了。