You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用运行中断网强制关闭及CONNECTIVITY_CHANGE接收器兼容问题

Hey there, I totally get your frustration—you’ve got your app checking for internet on launch and closing if there’s no connection, but it doesn’t react when the network drops while the app’s running. The old CONNECTIVITY_CHANGE broadcast approach is indeed deprecated on Android N (API 24) and above, so let’s switch to the official, reliable alternative: ConnectivityManager.NetworkCallback.

解决Android N+运行中断网强制关闭应用的问题

为什么旧方案不行?

Starting from Android 7.0, static registration for CONNECTIVITY_CHANGE is blocked, and even dynamic registration has strict throttling. Google recommends using NetworkCallback for real-time network state monitoring—it’s more efficient and avoids the broadcast limitations.

步骤1:添加必要权限

First, make sure your AndroidManifest.xml has these permissions (you probably already have them, but double-check):

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

步骤2:修复你的build.gradle错误

I noticed you added <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> directly in your build.gradle—this is wrong! That line belongs in an <intent-filter> inside AndroidManifest.xml, and since we’re using NetworkCallback, we don’t need it at all. Just delete that misplaced line from your build.gradle.

步骤3:实现NetworkCallback监听

Here’s the modified version of your LogRegActivity that adds real-time network monitoring. We’ll register the callback when the activity starts, unregister it when it’s destroyed (to avoid memory leaks), and trigger the app close when network is lost.

Modified Activity Code

public class LogRegActivity extends AppCompatActivity {
    private Button register_btn;
    private Button login_btn;
    private ConnectivityManager.NetworkCallback networkCallback;
    private ConnectivityManager connectivityManager;

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

        // Initialize UI elements
        register_btn = findViewById(R.id.registerbtn);
        login_btn = findViewById(R.id.loginbtn);

        // Check network state on launch (keep your existing logic)
        if (!isNetworkAvailable(this)) {
            Toast.makeText(this, "No Internet connection", Toast.LENGTH_LONG).show();
            finish();
        }

        // Set up network state listener
        initNetworkCallback();
        connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        // Register the callback (compatible with all API levels)
        if (connectivityManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                connectivityManager.registerDefaultNetworkCallback(networkCallback);
            } else {
                NetworkRequest networkRequest = new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .build();
                connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
            }
        }

        // Button click listeners (keep your existing code)
        register_btn.setOnClickListener(v -> {
            startActivity(new Intent(LogRegActivity.this, RegisterActivity.class));
        });

        login_btn.setOnClickListener(v -> {
            startActivity(new Intent(LogRegActivity.this, LoginActivity.class));
        });
    }

    private void initNetworkCallback() {
        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onLost(@NonNull Network network) {
                super.onLost(network);
                // Run UI operations on the main thread (required!)
                runOnUiThread(() -> {
                    Toast.makeText(LogRegActivity.this, "No Internet connection", Toast.LENGTH_LONG).show();
                    finish();
                });
            }

            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);
                // Optional: Add logic if you need to react when network comes back
            }
        };
    }

    // Keep your existing network check method
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (conMan != null) {
            NetworkInfo activeNetwork = conMan.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnected();
        }
        return false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Unregister callback to prevent memory leaks
        if (connectivityManager != null && networkCallback != null) {
            connectivityManager.unregisterNetworkCallback(networkCallback);
        }
    }
}

Key Notes

  • UI Thread Safety: The onLost method runs on a background thread, so we use runOnUiThread to show the Toast and call finish()—this avoids crashes from updating UI off the main thread.
  • Compatibility: The code checks API levels to use the appropriate registration method, so it works on devices from API 16 up to the latest versions.
  • Memory Leaks: Always unregister the NetworkCallback in onDestroy to prevent the system from holding references to your activity after it’s closed.

With this setup, your app will now immediately detect when the network drops while running, show the toast, and close the activity—just like you wanted!

内容的提问来源于stack exchange,提问作者Amr Mohammed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:41:29