我在这里遇到了一个问题。我正在尝试通过实现广播接收器来监听连接变化。我还在广播接收器中初始化了一个自定义侦听器,以便与活动进行通信,以显示连接变化以显示一个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可能没有被初始化。有人可以帮我解决这个问题吗?我过去已经实现了这一点,但是通过自定义广播而不是这些系统广播。
答案 0 :(得分:2)
CONNECTIVITY_CHANGE
广播由系统发送。这对您当前的设置意味着一些事情。
您在BroadcastReceiver
注册的LocalBroadcastManager
实例将永远不会收到该广播,因为LocalBroadcastManager
仅处理来自您应用内的广播。
在清单中注册Receiver类意味着系统将实例化Receiver的新实例以处理每个广播。由于这些实例不会被Activity
作为收听者的实例传递,networkStateListener
中的onReceive()
将为空,这很可能是您当前NullPointerException
即将到来的地方从
根据您的期望行为,您可以选择一些选项。
如果您只是希望在Activity
正在运行时收到有关连接更改的通知:
使用Context#registerReceiver()
方法注册Receiver的实例,并从清单中删除<receiver>
条目。如果您将NetworkStateReceiver
设为HomeActivity
的内部类,则不需要该界面。
使用LocalBroadcastManager
在NetworkStateReceiver
和您的Activity
之间进行通信,而不是在您的听众interface
之间进行通信。您可以在Intent
上使用额外信息来指示连接状态,或者使用不同的操作来区分。
使用其他一些事件总线实现在Receiver和Activity
之间进行通信。
如果您希望即使应用未运行也会收到更改通知:
Activity
并附加一个额外的Intent
以指示连接状态。如果您将Activity
的{{1}}设置为Activity
或launchMode
,并覆盖其singleTask
,这也可以处理singleTop
已经投放的情况1}}方法。在任何情况下,将onNewIntent()
作为聆听者传递给Activity
都不是必需的。