2015-09-27 30 views
3

這是廣播接收器檢查互聯網連接它顯示「沒有互聯網」吐司兩次,當我斷開WiFi。請幫忙。廣播接收器檢查互聯網連接被稱爲兩次,當我斷開WiFi

InternetDetector.java

package com.hfad.evenit; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.util.Log; 
import android.support.v7.app.AlertDialog; 
import android.widget.Toast; 

/** 
* Created by Vicky on 26-Sep-15. 
*/ 

public class InternetDetector extends BroadcastReceiver { 
    public InternetDetector() { 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 


     boolean isVisible = MyApplication.isActivityVisible(); 

     try { 
      if (isVisible == true) { 
       ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
       NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 

       // Check internet connection and accrding to state change the 
       // text of activity by calling method 
       if (networkInfo != null && networkInfo.isConnected()) 
       { 
        Toast.makeText(context, "Internet Available", Toast.LENGTH_SHORT).show(); 
       } else 
       { 
        Toast.makeText(context, "No Internet", Toast.LENGTH_SHORT).show(); 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.hfad.evenit" > 

    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".EnterPhoneNumber" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait" 
      android:windowSoftInputMode="stateVisible" /> 
     <activity 
      android:name=".EnterVerificationCode" 
      android:label="@string/title_activity_enter_verification_code" 
      android:screenOrientation="portrait" 
      android:windowSoftInputMode="stateVisible" /> 
     <activity 
      android:name=".GetNameAndEmail" 
      android:label="@string/title_activity_get_name_and_email" 
      android:screenOrientation="portrait" 
      android:windowSoftInputMode="stateVisible" /> 
     <activity 
      android:name=".Launcher" 
      android:label="@string/title_activity_launcher" 
      android:screenOrientation="portrait" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name=".Home" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait" 
      > 
     </activity> 
     <activity 
      android:name=".SettingsActivity" 
      android:label="@string/title_activity_settings" 
      android:screenOrientation="portrait"> 
     </activity> 
     <receiver 
      android:name=".InternetDetector" 
      android:enabled="true" > 
      <intent-filter> 
       <!-- Intent filters for broadcast receiver --> 
       <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
      </intent-filter> 
     </receiver> 
    </application> 

</manifest> 

我嘗試了好幾種解決方案,但他們都不工作。

回答

3

由於它採用的是Android文檔中提到這個廣播可以是每當發送連接狀態發生了變化時,而且當設備是從移動數據移動到WIFI等。

設備連接的更改可能非常頻繁 - 每次在移動數據和Wi-Fi之間移動時都會觸發此廣播。

source

有很多國家的聯繫,他們的人可以發現in docs

要檢查你應該使用getActiveNetworkInfo()網絡連接的當前狀態。

所以你的方法來檢查狀態可能看起來像:

private void checkNetworkState(){ 
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 

    if(activeNetworkInfo == null){ 
     //no network 
    } else { 
     NetworkInfo.State state = activeNetworkInfo.getState(); 

     switch (state){ 
      case CONNECTED: 
       break; 
      case CONNECTING: 
       break; 
      case DISCONNECTED: 
       break; 
      case DISCONNECTING: 
       break; 
      case SUSPENDED: 
       break; 
      case UNKNOWN: 
       break; 
     } 
    } 
} 

記住權限:android.Manifest.permission.ACCESS_NETWORK_STATE

+0

Dude在你的方法'checkNetworkState'中沒有問題,問題是它會被調用兩次,因爲'BroadcastReceiver'被調用兩次,所以它會再次產生兩個Toasts。 – Vicky

+0

不,如果您要檢查網絡的實際狀態,它將不會被調用兩次。是的,廣播將被多次調用,一次用於DISCONNECTING狀態,第二次用於DISCONNECTED。對您作出反應是您的責任。 – jakubbialkowski

+0

@ jakubbialkowsk好吧,想想這個,我打開應用程序,我關掉了我的wifi -'BroadcastReceiver',因爲無線網絡連接斷開了。現在系統會檢查移動數據是否可用,假設它已關閉,然後再次調用BroadcastReceiver。所以'CONNECTED'的狀態將是真實的兩次。如果我對'CONNECTED'狀態做出反應,它將執行兩次。你怎麼看? – Vicky

5

ConnectivityManager發送各種意圖通知有關不同的狀態,所以這是正常的,你不只捕捉互聯網開/關的變化,這個功能有更多的選擇,更多細節見here

UPD,這裏是解決方案:

public class InternetDetector extends BroadcastReceiver { 
    public InternetDetector() { 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) {  
     boolean isVisible = MyApplication.isActivityVisible(); 

     try { 
      if (isVisible == true) { 
       ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
       NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 

       // Check internet connection and accrding to state change the 
       // text of activity by calling method 
       if ((networkInfo != null) && (networkInfo.getState() == NetworkInfo.State.CONNECTED)) { 
        Toast.makeText(context, "Internet Available", Toast.LENGTH_SHORT).show(); 
       } else { 
        Toast.makeText(context, "No Internet", Toast.LENGTH_SHORT).show(); 
       } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 
+0

那麼應該怎樣的正確的解決方案? – Vicky

+0

@Vicky,這是有用的嗎? –

+0

對不起,夥計。 – Vicky

0

我想可以幫助這個。我已更新您的Receiver。讓我們試試這個肯定幫助你。

package com.hfad.evenit; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.util.Log; 
import android.support.v7.app.AlertDialog; 
import android.widget.Toast; 

/** 
* Created by Vicky on 26-Sep-15. 
*/ 

public class InternetDetector extends BroadcastReceiver { 

    private boolean isConnected = false; 

    public InternetDetector() { 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     boolean isVisible = MyApplication.isActivityVisible(); 

     try { 
      if (isVisible == true) { 
       isNetworkAvailable(context); 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    private boolean isNetworkAvailable(Context context) { 
     ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
     if (connectivity != null) { 
      NetworkInfo[] info = connectivity.getAllNetworkInfo(); 
      if (info != null) { 
       for (int i = 0; i < info.length; i++) { 
        if (info[i].getState() == NetworkInfo.State.CONNECTED) { 
         if (!isConnected) { 
          Log.v(LOG_TAG, "Now you are connected to Internet!"); 
          Toast.makeText(context, "Internet availablle via Broadcast receiver", Toast.LENGTH_SHORT).show(); 
          isConnected = true; 
          // do your processing here --- 
          // if you need to post any data to the server or get 
          // status 
          // update from the server 
         } 
         return true; 
        } 
       } 
      } 
     } 
     Log.v(LOG_TAG, "You are not connected to Internet!"); 
     Toast.makeText(context, "Internet NOT availablle via Broadcast receiver", Toast.LENGTH_SHORT).show(); 
     isConnected = false; 
     return false; 
    } 

} 
+0

Dude它不會工作,因爲廣播接收器被調用兩次,方法'isNetworkAvailable'也會被調用兩次,因此產生兩個Toast。 – Vicky

+0

我檢查了它,它不起作用,它會產生兩個Toasts。 – Vicky

0

你需要聲明一個變量BOOL刪除重複的動作。

bool b = true; 
if(b){ 
    // do something, in the first trigger 
}else{ 
    //do nothing, cancel trigger 
} 
b = !b; 
+0

是的,這是邏輯.Ok , 我會試試看。謝謝。 – Vicky

+0

當應用程序未運行且BroadCastReceiver「醒來」時,「b」將爲「真」,例如,如果他在第一次檢查後關閉應用程序,那麼這不是合乎邏輯的事情。 –