用于互联网连接状态更改的Android事件

akh*_*lsa 55 connection events android connectivity

我正在创建一个应用程序,用户将频繁的信息和文件上传到我的服务器.这是通过专用的上传器服务在新线程中完成的.

我从这个帖子中知道

检测Android上是否有可用的Internet连接

你可以相对容易地检查是否有互联网连接.您还可以获取socketTimeoutExceptions以检测Internet连接问题.所有这一切都很好,并且当连接因任何原因无法正常工作时,我可以轻松地缓存上传内容.

我的问题是如何知道何时重新上传?连接恢复时是否触发了事件?或者我是不是在制作一个睡眠的新线程,然后每30秒检查一次互联网连接?

任何想法,将不胜感激!

Tom*_*sti 113

很老的帖子,但我想分享我的接收器

没有必要把你的手放在清单或其他无聊的资源:)

用法

你的活动:

/*
 * You need to implement NetworkStateReceiverListener.
 * This interface is described inside the NewtworkStateReceiver class
 */
public class MyActivity implements NetworkStateReceiverListener {
    /* ... */
    private NetworkStateReceiver networkStateReceiver;
}
Run Code Online (Sandbox Code Playgroud)

在你的活动中:安排收件人

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);
}
Run Code Online (Sandbox Code Playgroud)

在您的活动中:实施所需的方法

@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 */        
}
Run Code Online (Sandbox Code Playgroud)

收件人

只需将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();
    }
}
Run Code Online (Sandbox Code Playgroud)

请享用 ;)

  • 你不应该在activity的`onDestroy()`方法中调用`unregisterReceiver(networkStateReceiver);`吗? (7认同)
  • 不要忘记向清单文件添加相应的权限:<uses-permission android:name ="android.permission.ACCESS_NETWORK_STATE"/> (4认同)
  • 您永远不会取消注册接收器,它会保留对活动的硬引用。很多泄漏的观点 (2认同)

Xmi*_*ter 27

如果您只想在连接发生变化时做一些简单的事情,那么解决方案就更容易了.

在您的活动中,创建一个广播接收器:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

然后进入onResumeonPause进行注册:

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

@Override
public void onPause() {
    unregisterReceiver(networkStateReceiver);
    super.onPause();
}
Run Code Online (Sandbox Code Playgroud)

  • @JCarlos 基本上,如果您在清单中声明它,那么每次连接发生变化时,它都会在应用程序方面被触发。如果您使用 Activity 中定义的 Receiver 如此处所示,那么它只会在您的 Activity 运行时触发。 (3认同)

dar*_*son 11

不太确定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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 它如何更好地工作?在尝试其中一种解决方案之前,只是好奇. (2认同)

HKo*_*ept 10

Android Nougat&O(API 24+) - 网络状态

对@darnmason回答(构造函数)进行了更改,使其在API 24+上运行.

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();
}
Run Code Online (Sandbox Code Playgroud)