Java 检查internet连接是否在运行时丢失

Java 检查internet连接是否在运行时丢失,java,android,Java,Android,你好。 我知道如何检查是否有可用的internet连接,我的问题是,我想向用户提供一个AlertDialog,该对话框阻止用户执行操作,除非在连接丢失或停用时重试。我不知道的是如何只编码一次,所以我不需要在所有活动中手动复制它 我尝试使用观察者模式,并在SplashActivityLauncher活动中初始化它 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(s

你好。 我知道如何检查是否有可用的internet连接,我的问题是,我想向用户提供一个AlertDialog,该对话框阻止用户执行操作,除非在连接丢失或停用时重试。我不知道的是如何只编码一次,所以我不需要在所有活动中手动复制它

我尝试使用观察者模式,并在SplashActivityLauncher活动中初始化它


 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        ObservedObject observedObject = new ObservedObject();
        observedObject.addObserver(new ObserverInternetConnection());

}
 public class ObservedObject extends Observable {
        private boolean isConnected;

        public boolean isConnected() {
            return isConnected;
        }

        public void setConnected(boolean connected) {
            isConnected = connected;
            setChanged();
            notifyObservers();
        }

     public class ObserverInternetConnection implements Observer {

        @Override
        public void update(Observable observable, Object o) {
            if (observable instanceof ObservedObject) {
                if (observable.hasChanged())
//alert is a method to show toast message
                    alert("connection changed");
                if (((ObservedObject) observable).isConnected)
                    alert("connected");
                else
                    alert("disconnected");

            }

        }
    }

当我手动设置observedObject连接时,它起作用了。但我想避免这样做。有没有一种方法可以自动做到这一点?我正在考虑使用另一个线程,但是我怎么能这样做呢? 另一个问题是,我检查internet连接的方式是使用ConnectionManager,但它需要我传递上下文,并且上下文可以并且将在整个应用程序中发生变化,我如何克服这种情况?是否有其他解决此问题的方法?

我建议创建BaseActivity,在您的案例中,您将在其中初始化连接更改侦听器观察器,并使用Splash、Main和您正在使用的其他活动扩展此活动

这样可以避免代码重复

当活动被销毁时,也不要忘记注销侦听器

此外,您不需要使用不同的线程。以下是如何在活动中侦听连接更改的示例:

首先注册接收者:

   @Override
    public void register(Context context) {
        initReceiver();
        final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        context.registerReceiver(receiver, intentFilter);
    }
接受者

receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (isOnline()) {
                    hideNoConnectionError();
                } else {
                    showNoConnectionError();
                }
            }
        };
和等值线

 val isOnline: Boolean
        get() {
            return try {
                val connectivityManager = context.getSystemService(
                        Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                connectivityManager.activeNetworkInfo != null &&
                        connectivityManager.activeNetworkInfo.isConnected
            } catch (exception: Exception) {
                false
            }
        }

很抱歉,最后一个方法是用Kotlin编写的,但我认为这是完全可以理解的

如果您的最低SDK版本>=N24,另一种方法是在应用程序类中订阅ConctivityManager。为了防止用户交互,请在顶部启动Transparent活动,并在阴影背景下声明连接已丢失。这不是理想的方法,但您不需要坚持继承

TestApplication.java

ConnectionLostScreen.java

ConnectionLostScreen的主题是

<style name="Theme.Transparent" parent="AppTheme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>
优点:

没有继承权。 独立和跨应用程序工作 无活动生存期跟踪 不需要活动上下文,因为整个活动的行为类似于对话框。 可集成定制布局、图形、动画 无需用户操作,因为当连接恢复时,ConnectionLostScreen将关闭。 缺点:

ConnectionLostScreen的活动流管理 单顶等。 如果只是确定的话,很难进行粒度控制 应覆盖屏幕 活动转换的动画
然后初始化另一个线程以定期设置连接(如果上下文可用)?
public class ConnectionLostScreen extends AppCompatActivity {
    private final static int SHOW = 1;
    private final static int HIDE = 2;
    private final static String EXTRA_NAME = "ACTION";

    public static Intent createShowSplashOnNetworkFailure(Context app) {
        Intent intent = new Intent(app, ConnectionLostScreen.class);
        intent.putExtra(EXTRA_NAME, SHOW);
        intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT| Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_ANIMATION);
        return intent;
    }

    public static Intent createIntentHideSplashOnNetworkRecovery(Context app) {
        Intent intent = new Intent(app, ConnectionLostScreen.class);
        intent.putExtra(EXTRA_NAME, HIDE);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        return intent;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen);

        if (getIntent() != null) handleIntent(getIntent());
    }

    @Override
    public void onBackPressed() {
       //disabled so user would not be able to close this activity.
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        if (intent != null) handleIntent(intent);
    }

    void handleIntent(Intent intent) {
        int value = intent.getIntExtra(EXTRA_NAME, 0);

        if (value == 0 || value == HIDE) {
            finish();
            return;
        }
    }
}
<style name="Theme.Transparent" parent="AppTheme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>