5

有一次,我有一个概率,你们真的很有帮助。所以在这里,我又遇到了另一个问题,我已经陷入了......:/getBoolean(EXTRA_NO_CONNECTIVITY)总是返回false

我正在运行扩展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在模拟器上尝试了它,并且我还通过关闭路由器在我的dev-phone上尝试了它(它没有SIM,因特网访问是通过我的无线路由器) - >没有上网保证!

我的清单包括下面几行:

... 
<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) 结果总是如此 - 因此它总是试图阻止我的服务并且永远不会启动它。

我怀疑根本不读取来自意图的附加功能,这就是为什么getBooleanExtra()的默认值总是返回。

PS。我在Android 2.1上

谢谢!

回答

3

我不确定在BroadcastReceiver内无法读取的附加功能,但我可以通过使用BroadcastReceiver来达到类似于您的目的。

我的接收器只捕获连接更改,但它不评估连接状态。它通知Service而不是在这两种情况下(连接与否)这项服务将有所作为。此服务可以在那个时候被运行或没有,所以它要么启动或“通知”(记住you can safely call startService() several times,这些调用不能嵌套):

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)也是如此。

+0

我知道你用过的方法。然而,我有些惊讶,很多人推荐我使用的代码(我也在最近在android上购买的O'reilly书上阅读它!)如果我无法找到CONNECTIVITY_ACTION广播的解决方案,我想我会按照您的示例并使用ConnectivityManager的方法检查我的服务。感谢您的回复:) – snoopaki

+0

不用客气@snoopaki - 实际上,我宁愿使用您的方法提供解决方案,但我只是看不到发生了什么,为什么。 – Shlublu

+1

我实际上已将我的服务更改为IntentService,并且对连接更改的服务中处理更有意义。所以我应该选择合适的答案! thx :) – snoopaki

2

不知道怪NO_CONNECTIVITY标志,但你可以从意向检索活动网络:

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

你可能只需要调用isConnected()这个对象上。

+1

Thanx的答复,我会牢记在心。对于目前的任务,我使用了上面的答案,它的工作原理相当不错:) – snoopaki

+1

现在这个常量已经被弃用了。 –