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.
为什么旧方案不行?
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
onLostmethod runs on a background thread, so we userunOnUiThreadto show the Toast and callfinish()—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
NetworkCallbackinonDestroyto 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

