2

我在这里遇到了一个问题。我正在尝试通过实现广播接收器来收听连接更改。此外,我已经在广播接收器中初始化了一个自定义侦听器,以便与有关连接更改的活动进行通信以显示 Crouton Toast .各种类的代码如下:

广播接收器:

public class NetworkStateReceiver extends BroadcastReceiver {

    private NetworkStateListener networkStateListener;

    public NetworkStateReceiver() {
    }

    public NetworkStateReceiver(NetworkStateListener networkStateListener) {
        this.networkStateListener = networkStateListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("test", "Network connectivity change ::: " + this.networkStateListener);
        if (intent.getExtras() != null) {

            NetworkInfo ni = (NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                Log.i("test", "Network " + ni.getTypeName() + " connected");
                networkStateListener.onConnected();
            }
        }
        if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d("test", "There's no network connectivity");
            networkStateListener.onDisconnected();
        }
    }
}

自定义侦听器接口:

public interface NetworkStateListener {

    public void onConnected();

    public void onDisconnected();
}

实现监听器并注册接收器以进行连接更改的活动:

    public class HomeActivity extends AppCompatActivity implements NetworkStateListener {
     private NetworkStateReceiver mReceiver;
     private LocalBroadcastManager mBroadcastManager;
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
      mBroadcastManager =    LocalBroadcastManager.getInstance(HomeActivity.this);
        mReceiver = new NetworkStateReceiver(HomeActivity.this);
    }

@Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
        mBroadcastManager.registerReceiver(mReceiver, intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mBroadcastManager.unregisterReceiver(mReceiver);
    }
    }

这是清单条目:

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

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

 <application
        android:name=".TestApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"

<receiver android:name=".shared.receivers.NetworkStateReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

我不知道为什么 networkstateListener 没有被初始化。它给出一个空指针,表示 NetWorkStateListener 可能没有被初始化。有人可以帮我解决这个问题吗?我过去已经实现了这一点,但是使用自定义广播而不是此类系统广播。

4

1 回答 1

3

CONNECTIVITY_CHANGE广播由系统发送。这对您当前的设置意味着几件事。

  1. BroadcastReceiver您注册的实例LocalBroadcastManager将永远不会收到该广播,因为LocalBroadcastManager仅处理源自您的应用程序内部的广播。

  2. 在清单中注册您的 Receiver 类意味着系统将实例化一个新的 Receiver 实例来处理每个广播。由于这些实例不会Activity作为侦听器传递给您的实例,networkStateListener因此将是 null in onReceive(),这很可能是您的 currentNullPointerException来自哪里。

根据您想要的行为,您有几个选项可供选择。

如果您只想在Activity运行时收到有关连接更改的通知:

  1. 而是使用该方法注册 Receiver 的实例,并从清单Context#registerReceiver()中删除该条目。<receiver>如果你创建NetworkStateReceiver一个内部类HomeActivity,你将不需要接口。

  2. 用于和你的,而不是你的听众LocalBroadcastManager之间进行交流。您可以在 上使用额外的来指示连接状态,或者使用不同的操作来区分。NetworkStateReceiverActivityinterfaceIntent

  3. 使用其他一些事件总线实现在 Receiver 和Activity.

如果您想在应用未运行时也收到更改通知:

  1. 从 Receiver开始Activity,附加附加到Intent以指示连接状态。如果您将's设置为or并覆盖其方法,这也可以处理您Activity已经运行的情况。ActivitylaunchModesingleTasksingleToponNewIntent()

无论如何,将您Activity作为听众传递给您BroadcastReceiver并不是真正必要的。

于 2016-04-15T23:21:30.873 回答