2

ここで問題が発生しました。ブロードキャスト レシーバーを実装して接続の変更をリッスンしようとしています。また、ブロードキャスト レシーバー内でカスタム リスナーを初期化して、接続の変更についてアクティビティと通信し、クルトン トーストを表示します。 .以下のようなさまざまなクラスのコード:

放送受信機:

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 が初期化されていない可能性があることを示す null ポインターが返されます。誰かがこれを手伝ってくれますか? 私は過去にこれを達成しましたが、これらの種類のシステム ブロードキャストではなく、カスタム ブロードキャストを使用しました。

4

1 に答える 1

3

CONNECTIVITY_CHANGEブロードキャストはシステムによって送信されます。これは、現在のセットアップにいくつかのことを意味します。

  1. アプリ内から発信されたブロードキャストのみを処理するため、BroadcastReceiver登録しているのインスタンスはLocalBroadcastManagerそのブロードキャストを受信しません。LocalBroadcastManager

  2. マニフェストに Receiver クラスを登録するということは、システムが Receiver の新しいインスタンスをインスタンス化して、各ブロードキャストを処理することを意味します。Activityこれらのインスタンスにはリスナーとしてのインスタンスが渡されていないため、 ではnetworkStateListenernull になります。これは、 currentがどこから来ているonReceive()可能性が最も高いかです。NullPointerException

希望する動作に応じて、いくつかのオプションから選択できます。

の実行中に接続の変更を通知するだけの場合Activity:

  1. 代わりに、Receiver のインスタンスをメソッドに登録し、マニフェストからエントリContext#registerReceiver()を削除してください。の内部クラス<receiver>を作成する場合、インターフェイスは必要ありません。NetworkStateReceiverHomeActivity

  2. LocalBroadcastManagerとの間の通信に、リスナーの代わりに使用しNetworkStateReceiverます。でエクストラを使用して接続状態を示すか、別のアクションを使用して区別することができます。ActivityinterfaceIntent

  3. 他のイベント バス実装を使用して、Receiver と の間で通信しActivityます。

アプリが実行されていないときでも変更の通知を受け取りたい場合:

  1. 接続状態を示すActivityために にエクストラを接続して、Receiver からを開始します。をまたはに設定し、そのメソッドをオーバーライドすると、これはすでに実行中のIntent場合も処理できます。ActivityActivitylaunchModesingleTasksingleToponNewIntent()

いずれにせよ、 yourActivityをリスナーとしてyour に渡すBroadcastReceiver必要はありません。

于 2016-04-15T23:21:30.873 に答える