55

如果 wifi 连接/断开连接,我的班级必须实现哪个侦听器才能自动检查代码?

我可以手动检查 wifi 连接/断开连接,但每次我需要从 android 设置连接/断开 WIFI,然后运行我的程序以获得结果。

我当前的代码很简单:

WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
if (wifi.isWifiEnabled()==true)
{
    tv.setText("You are connected");
}
else
{
    tv.setText("You are NOT connected");
}
4

6 回答 6

79

实际上,您正在检查 Wi-Fi 是否启用,这并不一定意味着它已连接。这只是意味着手机上的 Wi-Fi 模式已启用并且能够连接到 Wi-Fi 网络。

这就是我在广播接收器中监听实际 Wi-Fi 连接的方式:

public class WifiReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {     
        ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
        NetworkInfo netInfo = conMan.getActiveNetworkInfo();
        if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) 
            Log.d("WifiReceiver", "Have Wifi Connection");
        else
            Log.d("WifiReceiver", "Don't have Wifi Connection");    
    }   
};

为了访问活动网络信息,您需要将以下使用权限添加到您的 AndroidManifest.xml:

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

以及以下意图接收器(或者您可以以编程方式添加它......)

<!-- Receive Wi-Fi connection state changes -->
<receiver android:name=".WifiReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

编辑:在 Lollipop 中,如果您希望在用户连接到未计量的网络连接时执行操作,作业调度可能会有所帮助。看看:http: //developer.android.com/about/versions/android-5.0.html#Power


编辑 2:另一个考虑因素是我的回答没有检查您是否连接到 internet。您可以连接到需要您登录的 Wi-Fi 网络。这是一个有用的“IsOnline()”检查:https ://stackoverflow.com/a/27312494/1140744

于 2012-10-15T10:56:53.033 回答
18

创建您自己的扩展广播接收器的类...

public class MyNetworkMonitor extends BroadcastReceiver {

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

        // Process the Intent here

    }
}

在 AndroidManifest.xml 中

<receiver
    android:name=".MyNetworkMonitor" >
        <intent-filter>
            <action android:name="android.net.wifi.STATE_CHANGE" />
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
</receiver>

有关使用 Intent 的说明,请参阅WIFI_STATE_CHANGED_ACTIONCONNECTIVITY_ACTION

于 2011-06-15T18:29:28.600 回答
15

查看 javadoc 的这两页: ConnectivityManager WiFiManager

请注意,每一个都定义了广播动作。如果您需要了解有关注册广播接收器的更多信息,请查看: 以编程方式注册广播接收器

BroadcastReceiver receiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    if (wifi.isWifiEnabled()) {
      tv.setText("You are connected");
    } else {
      tv.setText("You are NOT connected");
    }
  }
};

在您的清单中,您可以执行以下操作(如果您不想在代码中注册接收器):

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <receiver android:name=".WiFiReceiver" android:enabled="true">
        <intent-filter>
            <action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" />
        </intent-filter>
    </receiver>
</application>

编辑:

我应该补充一点,如果您只需要在应用程序运行时接收广播,最好在您的代码中而不是在清单中注册此广播接收器。通过在清单中指定它,即使之前没有运行,您的进程也会收到连接更改的通知。

面向 Android 7.0(API 级别 24)及更高版本的应用如果在其清单中声明广播接收器,则不会收到此广播。如果应用程序将其 android.content.BroadcastReceiver} 注册到 android.content.Context#registerReceiver Context.registerReceiver() 并且该上下文仍然有效,应用程序仍将接收广播。

于 2011-06-15T18:25:13.030 回答
4

我同意@tanner-perrien 的回答,对于 2020 年,Kotlin 表示:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerReceiver(wifiBroadcastReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
    }

    private val wifiBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
            Log.d("TUT", "Wifi is ${wifiManager.isWifiEnabled}")
        }
    }

    override fun onDestroy() {
        unregisterReceiver(wifiBroadcastReceiver)
        super.onDestroy()
    }
}

但可能想与时俱进:https ://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback

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

活动:

lateinit var connec: ConnectivityManager

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    connec = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    val networkRequestWiFi = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .build()

    connec.registerNetworkCallback(networkRequestWiFi, networkCallbackWiFi)
 }

private var networkCallbackWiFi = object : ConnectivityManager.NetworkCallback() {
    override fun onLost(network: Network?) {
        Log.d("TUT", "WiFi disconnected")
    }

    override fun onAvailable(network: Network?) {
        Log.d("TUT", "WiFi connected")
    }
}

override fun onDestroy() {
    connec.unregisterNetworkCallback(networkCallbackWiFi)
    super.onDestroy()
}
于 2020-01-28T11:17:53.360 回答
3

AndroidManifest.xml添加以下权限。

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

创建新的接收器类。

public class ConnectionChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectivityManager =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();

        if (activeNetInfo != null
            && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
            Toast.makeText(context, "Wifi Connected!", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context, "Wifi Not Connected!", Toast.LENGTH_SHORT).show();
        }
    }

并将该接收器类添加到AndroidManifest.xml文件中。

<receiver android:name="ConnectionChangeReceiver"
          android:label="NetworkConnection">
  <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
  </intent-filter>
</receiver>
于 2015-02-03T09:02:06.133 回答
2

回应 sabsab。为了连接到 Connectivity Change 广播接收器,我使用了 warbi 的答案并添加了一个带有静态方法的类。

public class WifiHelper
{
    private static boolean isConnectedToWifi;
    private static WifiConnectionChange sListener;

    public interface WifiConnectionChange {
        void wifiConnected(boolean connected);
    }

    /**
     * Only used by Connectivity_Change broadcast receiver
     * @param connected
     */
    public static void setWifiConnected(boolean connected) {
        isConnectedToWifi = connected;
        if (sListener!=null)
        {
            sListener.wifiConnected(connected);
            sListener = null;
        }
    }

    public static void setWifiListener(WifiConnectionChange listener) {
        sListener = listener;
    }
}

然后我对上面显示的第一个答案的接收器类进行了更改。

public class ConnectivityReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
    ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = conMan.getActiveNetworkInfo();
    if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI)
    {
        Log.d("WifiReceiver", "Have Wifi Connection");
        WifiHelper.setWifiConnected(true);
    } else
    {
        Log.d("WifiReceiver", "Don't have Wifi Connection");
        WifiHelper.setWifiConnected(false);
    }

}
}

最后,在您的活动中,您可以添加一个侦听器来利用此回调。

wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
wasWifiEnabled = (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED || wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING);
WifiHelper.setWifiListener(new WifiHelper.WifiConnectionChange()
    {
        @Override
        public void wifiConnected(boolean connected)
        {
            //Do logic here
        }
    });

注意回调触发后监听器被移除,这是因为它是一个静态监听器。无论如何,这个实现对我来说是有效的,并且是挂钩你的活动的一种方式,或者任何地方都让它是静态的。

于 2016-11-19T01:17:11.153 回答