簡介
工作中遇到一個“變態”的需求,在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。
感想
有時解決問題,需要一點點靈感,一下子的靈光乍現也能解決一些問題,但總感覺很虛,我更喜歡循序漸進的構建知識體系,感覺這樣更踏實些。