簡體   English   中英

在運行時檢查互聯網連接是否丟失

[英]Checking if the internet connection is lost at runtime

美好的一天。 我知道如何檢查是否有可用的Internet連接,我的問題是我想向用戶顯示一個AlertDialog,該警報對話框將阻止操作,除非在連接丟失或停用時再次嘗試。 我不知道如何只編寫一次代碼,所以我不需要在所有活動中手動復制它。

我嘗試使用觀察者模式,並在SplashActivity(Launcher Activity)中對其進行了初始化。


 @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連接的方式是使用ConnectivityManager,但它需要我傳遞上下文,並且上下文可以(並且將會)在整個應用程序中發生變化,我該如何克服呢? 還有其他解決方法嗎?

我建議在初始化連接更改偵聽器(在您的情況下為Observer)的地方創建BaseActivity ,並使用Splash,Main和其他正在使用的活動擴展此活動。

這樣,您將避免代碼重復。

當活動被破壞時,也不要忘記注銷監聽器。

另外,您不需要使用其他線程。 這是如何在Activity中監聽連接性變化的示例:

首先注冊接收者:

   @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();
                }
            }
        };

和isOnline()

 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版本> = N(24),另一種方法是在Application類中訂閱ConectivityManager 為了防止用戶進行交互,請在頂部啟動透明活動,並用一些陰影背景說明該連接已丟失。 這不是理想的方法,但是您無需堅持繼承。

TestApplication.java

public class TestApplication extends android.app.Application {
    private static final String TAG = "TestApplication";
    @Override
    public void onCreate() {
        super.onCreate();

        ConnectivityManager m = (ConnectivityManager) getSystemService(Service.CONNECTIVITY_SERVICE);
        m.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                Log.e(TAG, "onAvailable: ");
                startActivity(ConnectionLostScreen.createIntentHideSplashOnNetworkRecovery(TestApplication.this));
            }

            @Override
            public void onLost(Network network) {
                Log.e(TAG, "onLost: ");
                startActivity(ConnectionLostScreen.createShowSplashOnNetworkFailure(TestApplication.this));
            }

        });
    }
}

ConnectionLostScreen.java

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;
        }
    }
}

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>

優點:

  • 沒有繼承。
  • 獨立且跨應用程序工作
  • 沒有活動生命周期跟蹤
  • 不需要Activity上下文,因為整個Activity就像對話框一樣。
  • 自定義布局,圖形,動畫可以集成
  • 無需用戶操作,因為恢復ConnectionLostScreen時, ConnectionLostScreen將關閉。

缺點:

  • ConnectionLostScreen活動流管理(使其變為singleTop等)
  • 如果僅應覆蓋某些屏幕,則很難進行精細控制
  • 活動過渡的動畫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM