私は、ユーザーがサーバーに情報とファイルをある程度頻繁にアップロードするアプリを作成しています。これは、専用のアップローダーサービスを通じて新しいスレッドで実行されます。
私はこのスレッドから知っています
インターネット接続があるかどうかを比較的簡単に確認できます。 socketTimeoutExceptionsを取得して、インターネット接続の問題を検出することもできます。すべてがうまく機能しており、何らかの理由で接続が機能しなかったときにアップロードを簡単にキャッシュできます。
私の質問は、アップロードを再試行するタイミングをどのように知るのですか?接続が復元されたときにトリガーされるイベントはありますか?それとも、スリープしてから30秒ごとにインターネット接続をチェックする新しいスレッドを作成するのにこだわっていますか?
どんなアイデアでも大歓迎です!
非常に古い投稿ですが、受信機を共有したいです
マニフェストや他の退屈なリソースに手を置く必要はありません:)
/*
* 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 */
}
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();
}
}
楽しい ;)
接続が変わったときに単純なことをしたいだけなら、もっと簡単な解決策があります。
アクティビティで、ブロードキャストレシーバーを作成します。
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();
}
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();
}
}
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();
}