2018年1月25日 星期四

[Android] 監控網路連線狀態(Monitoring network connectivity status)

問題:
我的App想加入網路監控,當無法連線時要跳通知,連上線後通知要消失,要怎麼做比較好呢?

處理:Google 「android 網路連線偵測」 → Google 「android internet connection detect」

參考:
[網路(Network)偵測區]
DevAndroid-DetermineAndMonitorDevAndroid-isConnectedOrConnectingCSDN-isConnected_vs_isAvailableStackOverflow-isConnectedAlwaysFalseStackOverflow-isConnectedAlwayTrue
[網際網路(Internet)偵測區]
StackOverflow-NoInternetStackOverflow-PingHost
[監控(Monitor)及通知(Notify)前端區]
StackOverflow-PhoneStateListenerGadgetSaint-BroadcastReceiverMILKMIDI BLOG-BroadcastReceiverCC's 程式碼-BroadcatReceiver
[跳轉設定(Settings)]
簡書

說明:
這題可以分成幾部分:
  1. 如何確定有無網路?
  2. 如何偵測網路連線狀態改變且通知畫面端?
  3. 畫面端要怎麼處理?

其中,"1.如何確定有無網路?"

  • 有用"ConnectivityManager"跟"TelephonyManager"兩種方法,看DevAndroid推薦的是ConnectivityManager,大部分網友也是用這種,所以就只看這種。

  • ConnectivityManager裡面又有用isAvailable、isConnected、isConnectedOrConnecting、getState 這4種判斷是否連線,getState要自己寫判斷式就先跳過,另外三種只有isConnected是確定連上網路的,但看來有些機器會遇到問題誤判,所以用isConnectedOrConnecting

  • 那這樣就真的能跟主機連線了嗎?不一定,搞不好連到的網路其實不能連到你的主機或是網際網路,那怎辦? 用StackOverflow裡查到的法1 或 法2,在確定有網路連線後,連到特定站台(如果要確定自己站台可以,可以在自己站台放個小檔或測網用API),看是否會通,如果連的不是自己的站要小心,有些站台在特定國家連不到(像是Google在中國)

好了,接著"2.如何偵測網路連線狀態改變且通知畫面端?",

  • 有用"PhoneStateListener"跟"BroadcastReceiver"兩種,因為第1題選了ConnectivityManager,而且看DevAndroid跟大部分網友都是用BroadcastReceiver,所以就只看這種囉。

  • BroadcastReceiver的寫法跟用法可參考GadgetSaint 或 CC's 程式碼,注意喔,這兩個寫的通知畫面端方法不同,GadgetSaint用的是Listener(interface),CC用的是寫inner class 的Receiver(就可以在onReceive裡面處理Activity的東東);兩種寫法都記得在Activity裡registerReceiver,才能收到通知。

  • 如果不需要即時監控變化的話,也有些Dev是寫在每個Activity的onCreate測一次,或是每次連線前測一次而已,那就不用用到BroacastReceiver,只是要注意有沒有地方沒防呆該擋沒擋。
[更新] 
如果你的Target API在24以上(新專案應該都是了吧),然後在AndroidManifest裡加上<recevicer>裡面intent-filter是<action android:name = "android.net.conn.CONNECTIVITY_CHANGE" />的話,Android Studio會跳警告,說明在manifest註冊的CONNECTIVITY_CHANGE將不會收到通知,所以要不用在manifest裡加這個,在要用的Activity再註冊即可,可參考CC's程式碼,如果不想寫inner class的Receiver,那就加上interface,onReceive時用interface通知外面吧。

Android官方的建議是:參考這篇,用 JobScheduler(如果min>=21) 或 GcmNetworkManager,只是還沒時間研究,因為GCM的網頁又說請用FCM(無言,很多官網文章也不會即時更新的),所以min<21,就呵呵,反正單Activity註冊Receiver還能用,先這樣吧,有空研究再更新 。

接下來,"3.畫面端要怎麼處理?",看看其他Apps怎麼處理囉~
  • YouTube是在BottomBar下方,長出一個小View顯示網路狀態,且中間Fragment內容會變成無網路圖。

  • GMail是出現一個Snackbar顯示"未連線",Action是"重試"。

  • Facebook是出現一個Snackbar顯示"目前無法連線。",Action是"更多",點了"更多"是會問你要不要到"設定"。(可參考簡書做法)

  • Line是在Fragment上方呈現一個半透明小View,顯示"未連接至網路",右邊有個"x"可以關閉該通知。

  • PLAY是整個畫面呈現"沒有網際網路連線。請確定Wi-Fi行動數據已開啟,然後再試一次。",中間有個按鈕[重試],點Wi-Fi會到WiFi設定,點行動數據會到可用的網路設定。
可以看出大部分知名Apps都是採用持續監控網路狀態,且離線還是能進App操作,只是限制部分功能。

沒有留言:

張貼留言