安卓SDK中用于网络事件的Intent动作

38

我需要接收网络连接状态变化等网络操作的广播。为此,我使用了一个广播接收器。请问有人能告诉我需要捕获哪个意图动作来处理网络事件?根据我在互联网上的搜索,目前我正在使用android.net.ConnectivityManager.CONNECTIVITY_ACTION

这是我的广播接收器类:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class NetworkStateReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub


    if (intent.getAction().equals(
            android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {

        // do something..
    }
}
}

我还添加了访问网络状态的权限:

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

这是我在清单文件中声明此类的方式:

<receiver class=".NetworkStateReceiver" android:name=".NetworkStateReceiver">
    <intent-filter>
            <action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" />
    </intent-filter>
</receiver>
请建议我正确的意图操作,如果我错了或者有其他方法来捕获网络事件,请告诉我。
2个回答

51

这是一个可行的示例:

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

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

.

的翻译是:

public class ConnectivityReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(ConnectivityReceiver.class.getSimpleName(), "action: "
                + intent.getAction());
    }

}

根据我的测试,我不需要任何权限来接收广播,无论 WLAN 是现在上线还是下线,或者 3G 是现在上线还是下线。我有点困惑,那么 android.net.conn.CONNECTIVITY_CHANGE 有什么用呢? - stefan.at.kotlin
如果你再看一遍,你会发现CONNECTIVITY_CHANGE不是一个权限,而是注册一个意图接收器(你也可以在代码中进行替代)。 - Hamid
答案看起来和问题一样。那么为什么在答案之前它不起作用呢? - AlikElzin-kilaka
2
这个答案只是在清单文件中修复了意图操作名称。android.net.ConnectivityManager.CONNECTIVITY_ACTIONandroid.net.conn.CONNECTIVITY_CHANGE,它是与意图操作匹配的。 - FabiF
3
这段代码能够运行,但只提示了“连接改变”,有没有办法判断它是连接还是断开? - Evan R.

6

yanchenko的回答非常有用,我只是简化一下以获取连接状态,请按以下方式修改onReceive:

public class ConnectivityReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(ConnectivityReceiver.class.getSimpleName(), "action: "
                + intent.getAction());
        MyConstants.IS_NETWORK_AVAILABLE = haveNetworkConnection(context);
        //IS_NETWORK_AVAILABLE this variable in your activities to check networkavailability.

    } 


    private boolean haveNetworkConnection(Context context) {
        boolean haveConnectedWifi = false;
        boolean haveConnectedMobile = false;

        ConnectivityManager cm = (ConnectivityManager)   context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] netInfo = cm.getAllNetworkInfo();
        for (NetworkInfo ni : netInfo) {
            if (ni.getTypeName().equalsIgnoreCase("WIFI"))
                if (ni.isConnected())
                    haveConnectedWifi = true;
            if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
                if (ni.isConnected())
                    haveConnectedMobile = true;
        }
        return haveConnectedWifi || haveConnectedMobile;    
    }
}

Ravi K Sharma,你是否知道android.net.ConnectivityManager.EXTRA_NO_CONNECTIVITY?这是自API级别1以来Intent extras中的额外布尔值,用于指示是否存在连接。 - class stacker
1
关于昨天的评论,我注意到它不够精确。看起来,在某些情况下,只有在没有连接时才会将EXTRA_NO_CONNECTIVITY添加到Intent extras中。因此,使用getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)访问它应该会产生一个布尔值,如果根本没有连接,则为true,如果有任何连接,则为false。此外,这个答案中的代码是一种反模式,因为分析是有限的。它将无法检测到蓝牙共享、USB共享或局域网连接。不要这样做。 - class stacker
2
这段代码的归属,因为Ravi忘记了:https://dev59.com/j2855IYBdhLWcg3woVw_#4239410 - paulw1128
为什么不直接获取getActiveNetworkInfo()并检查它是否连接,然后就完成了呢? - Ε Г И І И О
是的,如果您不需要知道连接类型,那么您是正确的。 - Ravi K. Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接