Android中wifi與數(shù)據(jù)流量的切換監(jiān)聽詳解
最近在做一個wifi和移動數(shù)據(jù)的監(jiān)控功能,來來回回折騰了一陣子,這個模塊的主要功能是監(jiān)聽整個APP的wifi與數(shù)據(jù)流量的切換,讓用戶使用專用流量,而不是用wifi,給一個彈窗,點擊確認,自動切換數(shù)據(jù)流量,關閉wifi。我的思路是寫一個靜態(tài)廣播,監(jiān)聽在廣播里面進行監(jiān)聽,啟用系統(tǒng)彈窗,點擊確認,自動切換網(wǎng)絡,這里面有一個坑就是彈窗會在廣播中多次被調用,其實只調用了一次,但是實際上多次調用系統(tǒng)的彈窗會一個疊加一個,搞了好久,終于搞好了,原來是系統(tǒng)廣播導致的疊加,詳情看代碼:
網(wǎng)絡封裝類ConnectivityManager:
ConnectivityManager 是一個網(wǎng)絡連接的管理類,里面封裝了網(wǎng)絡請求的詳細信息,包括WiFi與移動數(shù)據(jù)流量的開關狀態(tài),正在開啟與關閉的狀態(tài),連接狀態(tài)等等,很適合做網(wǎng)絡監(jiān)聽。還有一個類WifiManager ,這個類專門用來做WiFi的監(jiān)聽,他的監(jiān)聽效果比ConnectivityManager更加詳細豐富,可以檢測但是對流量沒法生效。這里使用ConnectivityManager 就足夠了。
一、注冊廣播
1、寫一個類繼承自BroadcastReceiver。
@Override public void onReceive(Context context, Intent intent) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo gprs = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); NetworkInfo wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (intent.getAction().equals("Android.net.conn.CONNECTIVITY_CHANGE")) { //移動數(shù)據(jù)連接上時 if (gprs.isConnected()){ } //wifi連接上時 if (wifi.isConnected()) { // 切換網(wǎng)絡,關閉wifi,開啟流量 if (isShow) {//做一個標記,避免多次彈窗的疊加bug,初始值為true,重要 switchNetwork(context); } } //斷網(wǎng)時 if (!netManager.getGRPS().isConnected() || !netManager.getGRPS().isConnected()) { } }
二、彈窗
彈窗一般用四種常用的方式:
1、使用popupwindow
2、使用dialog
3、WindowManager
4、系統(tǒng)彈窗
一般的彈窗需要依附于activity,在activity中彈窗,但是在服務中,不能簡單的使用這種方式,一般是采用系統(tǒng)的彈窗,他的優(yōu)先級很高,覆蓋于應用界面的最高層,并且要設置setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT),要不然會崩潰的。
private void switchNetwork(final Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialog); builder.setTitle("提示"); builder.setMessage("請關閉wifi,打開移動網(wǎng)絡"); builder.setCancelable(false); builder.setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 控制網(wǎng)絡的開關 controlNetWork(context); isShow = true; } }); AlertDialog dialog = builder.create(); // 需要把對話框的類型設為TYPE_SYSTEM_ALERT,否則對話框無法在廣播接收器里彈出 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.show(); isShow = false; }
三、網(wǎng)絡切換
wifi的網(wǎng)絡切換比較容易,直接設置setWifiEnabled就可以完成切換,而數(shù)據(jù)流量的切換比較麻煩,他的方法是私有的,無法調用,我們可以通過反射,找到他的方法進行調用:具體看代碼
private void controlNetWork(Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); // 允許流量,阻止wifi wifiManager.setWifiEnabled(false);//false表示斷開WiFi NetManager netManager = new NetManager(context); if (!netManager.getGRPS().isConnected()) { ConnectivityManager gprsCM = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); Class conmanClass; try { conmanClass = Class.forName(gprsCM.getClass().getName()); final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); iConnectivityManagerField.setAccessible(true); final Object iConnectivityManager = iConnectivityManagerField.get(gprsCM); final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); final Method setMobileDataEnabledMethod = iConnectivityManagerClass .getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); setMobileDataEnabledMethod.setAccessible(true);//true表示連接網(wǎng)絡 setMobileDataEnabledMethod.invoke(iConnectivityManager, true); } catch (Exception e) { e.printStackTrace(); } } } }
2、在清單文件中注冊廣播
<receiver android:name=".NetChangeReceiver" android:label="NetChangeReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
添加權限:
<uses-permission Android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
以上代碼很詳細的描述了網(wǎng)絡切換的實時檢測,更加詳細豐富的就不在這里寫出來了。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關文章
Android進程間大數(shù)據(jù)通信LocalSocket詳解
這篇文章主要為大家介紹了Android進程間大數(shù)據(jù)通信LocalSocket詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03Android編程之電池電量信息更新的方法(基于BatteryService實現(xiàn))
這篇文章主要介紹了Android編程之電池電量信息更新的方法,主要基于BatteryService實現(xiàn)該功能,以實例形式分析了Android獲取電池電量的具體步驟與實現(xiàn)技巧,需要的朋友可以參考下2015-11-11Android開發(fā)必備:秒殺真機超快模擬器Genymotion介紹
這篇文章主要介紹了Android開發(fā)必備:秒殺真機超快模擬器Genymotion介紹,本文直接用圖片說明Genymotion的安裝和模擬效果,并提供官網(wǎng),需要的朋友可以參考下2015-04-04學習Android Material Design(RecyclerView代替ListView)
Android Material Design越來越流行,以前很常用的 ListView 現(xiàn)在也用RecyclerView代替了,實現(xiàn)原理還是相似的,感興趣的小伙伴們可以參考一下2016-01-01