1. 程式人生 > >Android系統中通過shell命令實現wifi的連線控制

Android系統中通過shell命令實現wifi的連線控制

簡介

工作中遇到一個“變態”的需求,在android系統中不通過java層控制wifi的連線(主要是修改ap的essid和password),而是需要通過native層實現對wifi的控制。

How

  • 接到這個需求時,第一個想法是如何找到Android native層對應的wifi控制介面(也就是一些c層的介面),由於c層的介面都是android framework層的介面,屬於內部介面,android系統在設計之初就沒想暴露太多這層的介面,所以並沒有相關的文件說明(其實我也沒花太多時間去搜索,所以暫且認為沒有官方文件吧,不過我估計對android wifi模組有深入研究的人,應該會比較熟悉這方面的介面)
  • 分析wpa_supplicant service引數,wifi的控制逃不開wpa相關的服務,通過ps查看了wpa_supplicant的啟動引數發現androd系統是通過解析/data/misc/wifi/wpa_supplicant.conf 這個conf檔案來控制連線哪個ap,所以我麼只需要修改這個conf檔案,然後重啟wpa_supplicant這個服務即可。
  • 基於前面的分析,貌似該問題很容易解決,但是對wpa_supplicant服務的啟停,遇到問題,kill掉後,重啟wpa_supplicant無效,在沒有查明問題原因的時候,發現了svc wifi enable/disable命令,這個命令實現了wpa_supplicant的啟停而不用關心引數的設定。
  • 有了svc wifi這個命令,一切都簡單多了,但是除錯過程中,仍然遇到了問題,比如我輸入錯誤的password,android會嘗試多次重現連線ap,最後顯示無法連線,然後我們修改wpa_supplicant.conf輸入正確的password後,通過svc wifi啟停wpa_supplicant服務,android系統不會嘗試重新連線,仍然顯示之前的錯誤狀態,甚至重啟系統,仍然不會重新連線。
  • 在反覆嘗試確定前面的現象後,又陷入了一個僵局,一直找不到通過shell觸發重新連線的方式。在試過各種情況後,已經想不到其他嘗試的方式後,安靜下來,思考了下,突然意識到這個狀態一定是快取了,而且不是快取在程式碼層面(記憶體),而是快取在檔案上,否則重啟應該不會再記錄之前的狀態。所以無目的的查看了/data/misc/wifi目錄下的檔案,發現networkHistory.txt這麼個檔案,直覺上感覺就是它了,刪除之,通過svc wifi重啟wpa_supplicant服務,立馬觸發連線。

總結

通過上面的分析,通過shell命令實現wifi的連線控制只需要:

  • 通過svc wifi disable關閉wifi
  • 修改/data/misc/wifi/wpa_supplicant.conf配置檔案
  • 刪除/data/misc/wifi/networkHistory.txt檔案
  • 通過svc wifi enable開啟wifi

由於對該“變態”的需求沒有太多的興趣,所以導致連看看networkHistory.txt的內容都沒有,更沒有去深入研究這個檔案對連線的影響,想想自己探究問題本質的慾望怎麼越來越小了呢。由於筆者換了技術方向,近期也沒時間深入研究這個了,寫這個篇文章時大概搜尋了下,發現了一篇文章貌似講到了這個連線過程的,有興趣的朋友可以繼續看看http://www.itnose.net/detail/6637117.html

感想

有時解決問題,需要一點點靈感,一下子的靈光乍現也能解決一些問題,但總感覺很虛,我更喜歡循序漸進的構建知識體系,感覺這樣更踏實些。