5

有一次我遇到问题,你们真的很有帮助。所以在这里我又遇到了另一个我遇到的问题......:/

我正在运行一个扩展 BroadcastReceiver 的自定义 NetworkReceiver。我想检测手机何时有互联网连接,以便我可以随时启动服务。我已经阅读了很多主题,所有主题都或多或少地提示了以下对我不起作用的代码:

public class NetworkReceiver extends BroadcastReceiver {

private static final String tag = NetworkReceiver.class.getSimpleName();

@Override
public void onReceive(Context context, Intent intent) {
    Log.i(tag,"****** NetworkReceiver // onReceive()");

    boolean noConnection = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

    if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
        Log.i(tag,"****** NetworkReceiver // Network Down?: " + intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false));
    }

    // TODO Bug: Never stops the service. Stays always connected!
    if(noConnection) {
        Log.i(tag,"****** NetworkReceiver // Stopping Service...");
        context.stopService(new Intent(context, FetchService.class));
    } else {
        Log.i(tag,"****** NetworkReceiver // Starting Service!");
        context.startService(new Intent(context, FetchService.class));
    }
}

我遇到的问题是 logcat 总是返回NetworkDown?: false并且服务永远不会停止(它总是重新启动)。我通过按 F8 在模拟器上进行了尝试,我还在我的开发手机上尝试了它(它没有 SIM,通过我的 wifi 路由器访问互联网),方法是关闭路由器 -> 保证没有互联网访问!

我的清单包括以下几行:

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

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

我还应该注意,我也尝试 <action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" />在我的清单文件中没有任何更改,并且当我更改行时: intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) 结果 intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true) 总是正确的 - 因此它总是试图停止我的服务并且从不启动它。

我怀疑 Intent 中的 Extras 根本没有被读取,这就是为什么getBooleanExtra()总是返回默认值的原因。

PS。我在安卓 2.1

谢谢!

4

2 回答 2

3

我不确定在 中无法阅读的 Extras BroadcastReceiver,但我可以向您展示我使用 的方式,BroadcastReceiver用于与您类似的目的。

我的接收器只捕捉到连接变化,但它不评估连接状态。它通知Service相反,因为在这两种情况下(连接或未连接)该服务将有一些事情要做。这个服务可以在那个时候运行或者不运行,所以它要么被启动要么被“通知”(记住你可以安全地调用 startService() 几次,这些调用不会嵌套):

public class ConnectivityReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        final Intent intentService = new Intent(context, MyService.class);
        intentService.putExtra(MyService.INTENT_HANDLE_CONNECTIVITY_CHANGE, "");

        context.startService(intentService);
    }
}

然后,在我的服务中,我会评估连接性,然后采取相应的行动。请注意,我不会以与您相同的方式评估连接状态,这可能是以下代码有效但您的代码无效的原因(以下仅是相关代码):

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null) {
        final Bundle bundle = intent.getExtras();

        // Handle the intent INTENT_HANDLE_CONNECTIVITY_CHANGEif any
        if ((bundle != null) && (bundle.get(INTENT_HANDLE_CONNECTIVITY_CHANGE) != null)) {         
            handleConnectivity(); 
        }
    }

    return START_STICKY;
}

private void handleConnectivity() {
    final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    final NetworkInfo netInfo = cm.getActiveNetworkInfo();

    if(netInfo != null && netInfo.isConnected()) {
        // WE ARE CONNECTED: DO SOMETHING
    }   
    else {
        // WE ARE NOT: DO SOMETHING ELSE    
    }
}

这在 Android-7 (2.1) 下也可以正常工作。

于 2011-08-30T16:04:15.617 回答
2

不知道奇怪的 NO_CONNECTIVITY 标志,但您可以从意图中检索活动网络:

(NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);

您可能只需在此对象上调用 isConnected() 即可。

于 2011-09-01T10:42:23.720 回答