web-dev-qa-db-ja.com

Androidインターネット接続状態変更のイベント

私は、ユーザーがサーバーに情報とファイルをある程度頻繁にアップロードするアプリを作成しています。これは、専用のアップローダーサービスを通じて新しいスレッドで実行されます。

私はこのスレッドから知っています

Androidでインターネット接続が利用可能かどうかを検出

インターネット接続があるかどうかを比較的簡単に確認できます。 socketTimeoutExceptionsを取得して、インターネット接続の問題を検出することもできます。すべてがうまく機能しており、何らかの理由で接続が機能しなかったときにアップロードを簡単にキャッシュできます。

私の質問は、アップロードを再試行するタイミングをどのように知るのですか?接続が復元されたときにトリガーされるイベントはありますか?それとも、スリープしてから30秒ごとにインターネット接続をチェックする新しいスレッドを作成するのにこだわっていますか?

どんなアイデアでも大歓迎です!

54
akhalsa

非常に古い投稿ですが、受信機を共有したいです

マニフェストや他の退屈なリソースに手を置く必要はありません:)

使用法

あなたの活動:

/*
 * You need to implement NetworkStateReceiverListener.
 * This interface is described inside the NewtworkStateReceiver class
 */
public class MyActivity implements NetworkStateReceiverListener {
    /* ... */
    private NetworkStateReceiver networkStateReceiver;
}

あなたの活動で:受信者をインスタンス化する

public void onCreate(Bundle savedInstanceState) {
    /* ... */
    networkStateReceiver = new NetworkStateReceiver();
    networkStateReceiver.addListener(this);
    this.registerReceiver(networkStateReceiver, new IntentFilter(Android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}

public void onDestroy() {
    super.onDestroy();
    networkStateReceiver.removeListener(this);
    this.unregisterReceiver(networkStateReceiver);
}

あなたの活動で:必要な方法を実装する

@Override
public void networkAvailable() {
    Log.d("tommydevall", "I'm in, baby!");
    /* TODO: Your connection-oriented stuff here */
}

@Override
public void networkUnavailable() {
    Log.d("tommydevall", "I'm dancing with myself");
    /* TODO: Your disconnection-oriented stuff here */        
}

受信機

networkStateReceiver.Javaとしてプロジェクトにコピーアンドペーストするだけです

public class NetworkStateReceiver extends BroadcastReceiver {

    protected Set<NetworkStateReceiverListener> listeners;
    protected Boolean connected;

    public NetworkStateReceiver() {
        listeners = new HashSet<NetworkStateReceiverListener>();
        connected = null;
    }

    public void onReceive(Context context, Intent intent) {
        if(intent == null || intent.getExtras() == null)
            return;

        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = manager.getActiveNetworkInfo();

        if(ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
            connected = true;
        } else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
            connected = false;
        }

        notifyStateToAll();
    }

    private void notifyStateToAll() {
        for(NetworkStateReceiverListener listener : listeners)
            notifyState(listener);
    }

    private void notifyState(NetworkStateReceiverListener listener) {
        if(connected == null || listener == null)
            return;

        if(connected == true)
            listener.networkAvailable();
        else
            listener.networkUnavailable();
    }

    public void addListener(NetworkStateReceiverListener l) {
        listeners.add(l);
        notifyState(l);
    }

    public void removeListener(NetworkStateReceiverListener l) {
        listeners.remove(l);
    }

    public interface NetworkStateReceiverListener {
        public void networkAvailable();
        public void networkUnavailable();
    }
}

楽しい ;)

109
Tommaso Resti

接続が変わったときに単純なことをしたいだけなら、もっと簡単な解決策があります。

アクティビティで、ブロードキャストレシーバーを作成します。

private BroadcastReceiver networkStateReceiver=new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = manager.getActiveNetworkInfo();
        doSomethingOnNetworkChange(ni);
    }
};

次に、onResumeおよびonPauseで登録を行います。

@Override
public void onResume() {
    super.onResume();
    registerReceiver(networkStateReceiver, new IntentFilter(Android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}

@Override
public void onPause() {
    unregisterReceiver(networkStateReceiver);
    super.onPause();
}
23
Xmister

Tommasoの放送受信機で何が起こっているのかはよくわかりませんが、私にとってはうまくいきませんでした。これが私の実装です。接続の利用可能/利用不可の変更時にのみ通知します。

また、onResume()で登録し、onPause()で登録解除します。それ以外は上記と同じです。

public class NetworkStateReceiver extends BroadcastReceiver {

    private ConnectivityManager mManager;
    private List<NetworkStateReceiverListener> mListeners;
    private boolean mConnected;

    public NetworkStateReceiver(Context context) {
        mListeners = new ArrayList<NetworkStateReceiverListener>();
        mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        checkStateChanged();
    }

    public void onReceive(Context context, Intent intent) {
        if (intent == null || intent.getExtras() == null)
            return;

        if (checkStateChanged()) notifyStateToAll();
    }

    private boolean checkStateChanged() {
        boolean prev = mConnected;
        NetworkInfo activeNetwork = mManager.getActiveNetworkInfo();
        mConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        return prev != mConnected;
    }

    private void notifyStateToAll() {
        for (NetworkStateReceiverListener listener : mListeners) {
            notifyState(listener);
        }
    }

    private void notifyState(NetworkStateReceiverListener listener) {
        if (listener != null) {
            if (mConnected) listener.onNetworkAvailable();
            else listener.onNetworkUnavailable();
        }
    }

    public void addListener(NetworkStateReceiverListener l) {
        mListeners.add(l);
        notifyState(l);
    }

    public void removeListener(NetworkStateReceiverListener l) {
        mListeners.remove(l);
    }

    public interface NetworkStateReceiverListener {
        public void onNetworkAvailable();

        public void onNetworkUnavailable();
    }
}
11
darnmason

Android Nougat&O(API 24+)-ネットワーク状態

API 24 +で動作するように@darnmasonの回答(コンストラクター)が変更されました。

public NetworkStateReceiver(Context context) {
    mListeners =  new ArrayList<>();
    mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    context.registerReceiver(NetworkStateReceiver.this, intentFilter);

    checkStateChanged();
}
9
HKoncept