JobScheduler
作为替代方法。但是JobScheduler
并不能完全提供与CONNECTIVITY_ACTION
广播相同的行为。在我的Android应用程序中,我使用此广播来了解设备的网络状态。我想通过
CONNECTIVITY_ACTION
广播知道这个状态是CONNECTING
还是CONNECTED
,它最适合我的需求。现在它被弃用了,有人能建议我获取当前网络状态的替代方法吗?
JobScheduler
作为替代方法。但是JobScheduler
并不能完全提供与CONNECTIVITY_ACTION
广播相同的行为。CONNECTIVITY_ACTION
广播知道这个状态是CONNECTING
还是CONNECTED
,它最适合我的需求。即将被废弃的是后台应用程序接收网络连接状态更改的功能。
正如David Wasser所说,如果满足以下条件仍然可以收到连接更改的通知:
context
在程序中注册了接收器,而不是在清单文件中进行注册,例如:
IntentFilter filter = new IntentFilter();
@SuppressWarnings({"deprecation", "RedundantSuppression"})
String action = ConnectivityManager.CONNECTIVITY_ACTION;
filter.addAction(action);
myContext.registerReceiver(myReceiver, filter);
如果您不喜欢@SuppressWarnings
部分,或者认为甚至编程注册接收器可能在某些未来的Android版本中停止工作,则继续阅读:
您可以改用NetworkCallback,它也需要前台状态。 特别地,您需要覆盖onAvailable以处理连接状态的更改。
让我快速草拟一段代码片段:
public class ConnectionStateMonitor extends NetworkCallback {
final NetworkRequest networkRequest;
public ConnectionStateMonitor() {
networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
}
public void enable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.registerNetworkCallback(networkRequest, this);
}
// Likewise, you can have a disable method that simply calls ConnectivityManager.unregisterNetworkCallback(NetworkCallback) too.
@Override
public void onAvailable(Network network) {
// Do what you need to do here,
// or instead, override `onUnavailable()` or `onLost()`,
// (to detect absense of network).
}
}
我会更新 Sayem
的回答,以解决它向我展示的 lint 问题。
class ConnectionLiveData(val context: Context) : LiveData<Boolean>() {
private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
private val networkRequestBuilder: NetworkRequest.Builder = NetworkRequest.Builder()
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI)
override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityMarshmallowManagerCallback())
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> marshmallowNetworkAvailableRequest()
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest()
else -> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")) // android.net.ConnectivityManager.CONNECTIVITY_ACTION
}
}
}
}
override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
} else {
context.unregisterReceiver(networkReceiver)
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkAvailableRequest() {
connectivityManager.registerNetworkCallback(networkRequestBuilder.build(), getConnectivityLollipopManagerCallback())
}
@TargetApi(Build.VERSION_CODES.M)
private fun marshmallowNetworkAvailableRequest() {
connectivityManager.registerNetworkCallback(networkRequestBuilder.build(), getConnectivityMarshmallowManagerCallback())
}
private fun getConnectivityLollipopManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) {
postValue(true)
}
override fun onLost(network: Network?) {
postValue(false)
}
}
return connectivityManagerCallback
} else {
throw IllegalAccessError("Accessing wrong API version")
}
}
private fun getConnectivityMarshmallowManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(network: Network?, networkCapabilities: NetworkCapabilities?) {
networkCapabilities?.let { capabilities ->
if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
postValue(true)
}
}
}
override fun onLost(network: Network?) {
postValue(false)
}
}
return connectivityManagerCallback
} else {
throw IllegalAccessError("Accessing wrong API version")
}
}
private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
updateConnection()
}
}
private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
postValue(activeNetwork?.isConnected == true)
}
}
同样的用法:
val connectionLiveData = ConnectionLiveData(context)
connectionLiveData.observe(this, Observer { isConnected ->
isConnected?.let {
// do job
}
})
顺便说一句,感谢 Sayem 提供的解决方案。
Android N的文档说明如下:
针对Android N的应用程序即使具有请求接收网络连接状态改变通知的清单条目,也不会接收到CONNECTIVITY_ACTION广播。仍在前台运行的应用程序可以通过BroadcastReceiver在主线程上监听CONNECTIVITY_CHANGE以接收通知。
这意味着,如果你的应用程序在前台运行,仍然可以注册一个BroadcastReceiver来检测网络连接状态的更改。
CONNECTIVITY_CHANGE
" 而不是过时的方法,但最终发现那只是 "CONNECTIVITY_ACTION
" 变量的值。我希望人们停止复制/粘贴文档,如果那真的有用,我们就不会在这里了。 - Top-Master请先查看@Amokrane Chentir的Android N支持答案。
对于那些想要在所有API级别上提供支持并在用户界面中观察它的人,请检查下面的代码。
NetworkConnection的LiveData:
class ConnectionLiveData(val context: Context) : LiveData<Boolean>(){
var intentFilter = IntentFilter(CONNECTIVITY_ACTION)
private var connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var networkCallback : NetworkCallback
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
networkCallback = NetworkCallback(this)
}
}
override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(networkCallback)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
val builder = NetworkRequest.Builder().addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI)
connectivityManager.registerNetworkCallback(builder.build(), networkCallback)
}
else -> {
context.registerReceiver(networkReceiver, intentFilter)
}
}
}
override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(networkCallback)
} else{
context.unregisterReceiver(networkReceiver)
}
}
private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
updateConnection()
}
}
fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
postValue(activeNetwork?.isConnectedOrConnecting == true)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class NetworkCallback(val liveData : ConnectionLiveData) : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) {
liveData.postValue(true)
}
override fun onLost(network: Network?) {
liveData.postValue(false)
}
}
}
在UI中观察(Activity/Fragment):
val connectionLiveData = ConnectionLiveData(context)
connectionLiveData.observe(this, Observer {
// do whatever you want with network connectivity change
})
IntentFilter
。像这样:var intentFilter = IntentFilter(CONNECTIVITY_ACTION)
- Ryan AmaralintentFilter
和connectivityManager
这两个全局变量/属性的类型(分别为IntentFilter
和ConnectivityManager
)。 - Ryan Amaral基于 @KebabKrabby 的回答:
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.CONNECTIVITY_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.ConnectivityManager.CONNECTIVITY_ACTION
import android.net.ConnectivityManager.EXTRA_NO_CONNECTIVITY
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.os.Build
import androidx.lifecycle.LiveData
class ConnectivityWatcher(
private val context: Context
): LiveData<Boolean>() {
private lateinit var networkCallback: ConnectivityManager.NetworkCallback
private lateinit var broadcastReceiver: BroadcastReceiver
override fun onActive() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
networkCallback = createNetworkCallback()
cm.registerDefaultNetworkCallback(networkCallback)
} else {
val intentFilter = IntentFilter(CONNECTIVITY_ACTION)
broadcastReceiver = createBroadcastReceiver()
context.registerReceiver(broadcastReceiver, intentFilter)
}
}
override fun onInactive() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
cm.unregisterNetworkCallback(networkCallback)
} else {
context.unregisterReceiver(broadcastReceiver)
}
}
private fun createNetworkCallback() = object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
val isInternet = networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)
val isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)
postValue(isInternet && isValidated)
}
override fun onLost(network: Network) {
postValue(false)
}
}
private fun createBroadcastReceiver() = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val isNoConnectivity = intent?.extras?.getBoolean(EXTRA_NO_CONNECTIVITY) ?: true
postValue(!isNoConnectivity)
}
}
}
使用它的方式与原始答案几乎相同(例如从Activity观察):
ConnectivityWatcher(this).observe(this, Observer {
Log.i("*-*-*", "is internet available? - ${if (it) "Yes" else "No"}")
})
JobSchedular
、GcmNetworkManager
和BroadcastReceiver
。new JobRequest.Builder(DemoSyncJob.TAG)
.setRequiresCharging(true)
.setRequiresDeviceIdle(false)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) // this is what gets the job done
.build()
.schedule();
LiveData
。我决定调用(此时)最新的API方法({{link2:ConnectivityManager#registerDefaultNetworkCallback
}}),该方法针对Android Nougat。/**
* Observes network connectivity by consulting the [ConnectivityManager].
* Observing can run infinitely or automatically be stopped after the first response is received.
*/
class ConnectivityObserver @JvmOverloads constructor(
val context: Context,
val onConnectionAvailable: () -> Unit,
val onConnectionLost: () -> Unit = {},
val shouldStopAfterFirstResponse: Boolean = false
) {
private val connectivityManager
get() = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@Suppress("DEPRECATION")
private val intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
private val broadCastReceiver = object : BroadcastReceiver() {
@Suppress("DEPRECATION")
override fun onReceive(context: Context?, intent: Intent?) {
if (ConnectivityManager.CONNECTIVITY_ACTION != intent?.action) {
return
}
val networkInfo = connectivityManager.activeNetworkInfo
if (networkInfo != null && networkInfo.isConnectedOrConnecting) {
onConnectionAvailable.invoke()
} else {
onConnectionLost.invoke()
}
if (shouldStopAfterFirstResponse) {
stop()
}
}
}
private lateinit var networkCallback: ConnectivityManager.NetworkCallback
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
onConnectionAvailable.invoke()
if (shouldStopAfterFirstResponse) {
stop()
}
}
override fun onLost(network: Network?) {
super.onLost(network)
onConnectionLost.invoke()
if (shouldStopAfterFirstResponse) {
stop()
}
}
}
}
}
fun start() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
// Decouple from component lifecycle, use application context.
// See: https://developer.android.com/reference/android/content/Context.html#getApplicationContext()
context.applicationContext.registerReceiver(broadCastReceiver, intentFilter)
} else {
connectivityManager.registerDefaultNetworkCallback(networkCallback)
}
}
fun stop() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
context.applicationContext.unregisterReceiver(broadCastReceiver)
} else {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
}
}
使用方法:
val onConnectionAvailable = TODO()
val connectivityObserver = ConnectivityObserver(context, onConnectionAvailable)
connectivityObserver.start()
connectivityObserver.stop()
或者:
val onConnectionAvailable = TODO()
val onConnectionLost = TODO()
ConnectivityObserver(context,
onConnectionAvailable,
onConnectionLost,
shouldStopAfterFirstResponse = true
).start()
ACCESS_NETWORK_STATE
权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
我期待着从您那里阅读到有帮助的评论和改进意见。
(context as AppCompatActivity).runOnUiThread(object: Runnable{ override fun run() { onConnectionAvailable.invoke() } })
而不是 onConnectionAvailable.invoke()
。对于 onConnectionLost.invoke()
也是如此。 - Андрей Воробьев我决定检查这里的解决方案here,并进行了一些改进和示例。我还使其避免了多次设置相同的值,因此观察者不会一次又一次地获取相同的值:
ConnectionLiveData.kt
class ConnectionLiveData(private val context: Context) : LiveData<Boolean>() {
private val handler = Handler(Looper.getMainLooper())
private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
private lateinit var networkReceiver: BroadcastReceiver
init {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
@AnyThread
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
setNewValue(true)
}
}
override fun onAvailable(network: Network) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1)
setNewValue(true)
}
override fun onLost(network: Network) {
setNewValue(false)
}
}
}
else -> {
networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
updateConnection()
}
}
}
}
}
/**this prevents observers to get multiple times the same value*/
@AnyThread
private fun setNewValue(isConnected: Boolean) {
handler.removeCallbacksAndMessages(null)
if (isUiThread()) {
if (value != isConnected)
@SuppressLint("WrongThread")
value = isConnected
return
}
handler.post {
if (value != isConnected)
value = isConnected
}
}
@UiThread
override fun onActive() {
super.onActive()
val connectivityManager: ConnectivityManager = context.getSystemService()!!
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> connectivityManager.registerDefaultNetworkCallback(connectivityManagerCallback, handler)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(connectivityManagerCallback)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
val networkRequest =
NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build()
connectivityManager.registerNetworkCallback(networkRequest, connectivityManagerCallback)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
val networkRequest =
NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build()
connectivityManager.registerNetworkCallback(networkRequest, connectivityManagerCallback)
}
else -> {
@Suppress("DEPRECATION") context.registerReceiver(networkReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}
}
}
override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val connectivityManager: ConnectivityManager = context.getSystemService()!!
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
} else {
context.unregisterReceiver(networkReceiver)
}
}
@Suppress("DEPRECATION")
private fun updateConnection() {
setNewValue(isConnectedToInternet(context))
}
companion object {
@JvmStatic
fun isUiThread(): Boolean =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) Looper.getMainLooper().isCurrentThread else Thread.currentThread() === Looper.getMainLooper().thread
private fun isConnectedToInternet(context: Context): Boolean {
val connectivityManager: ConnectivityManager = context.getSystemService()!!
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
return activeNetwork?.isConnectedOrConnecting == true
}
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.textView)
ConnectionLiveData(this).observe(this) {
textView.text = if (it) "connected" else "disconnected"
Log.d("AppLog", "connected?$it")
}
val internetSettings = findViewById<View>(R.id.internetSettings)
internetSettings.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
internetSettings.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
startActivity(Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY))
}
findViewById<View>(R.id.wifiSettings).setOnClickListener {
startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
}
findViewById<View>(R.id.mobileDataSettings).setOnClickListener {
startActivity(Intent(Settings.ACTION_DATA_ROAMING_SETTINGS))
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"
android:orientation="vertical" tools:context=".MainActivity">
<TextView
android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:id="@+id/internetSettings" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="internet settings" />
<Button
android:id="@+id/wifiSettings" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="wifi settings" />
<Button
android:id="@+id/mobileDataSettings" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="mobile-data settings" />
</LinearLayout>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
CONNECTIVITY_ACTION
广播(请参见 Svelte)。ConnectivityManager.registernetworkCallback()
显式注册网络回调。JobScheduler
,并通过 setRequiredNetworkType()
指定一个非计量网络。这是我的Java解决方案!适用于从安卓LOLLIPOP到安卓S及以上版本
@RequiresApi (api = Build.VERSION_CODES.LOLLIPOP)
public final class NetworkWatcher extends LiveData<Boolean> {
// Variables
private final Context context;
private final ConnectivityManager connectivityManager;
private ConnectivityManager.NetworkCallback networkCallback;
private NetworkRequest networkRequest;
private NetworkWatcher.NetworkStateWatcherReceiver networkStateWatcherReceiver;
// Constructors
public NetworkWatcher(@NonNull Context context){
this.context = context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
this.connectivityManager = context.getSystemService(ConnectivityManager.class);
this.networkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onLost(@NonNull Network network) {
NetworkWatcher.super.postValue(false);
}
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
NetworkWatcher.super.postValue(
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
);
}
};
this.networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
.build();
} else {
this.networkStateWatcherReceiver = new NetworkStateWatcherReceiver();
this.networkStateWatcherReceiver.setOnNetworkChangedListener(NetworkWatcher.super::postValue);
}
}
// Override methods
@Override
protected void onActive() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
this.connectivityManager.registerBestMatchingNetworkCallback(this.networkRequest, this.networkCallback, null);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
this.connectivityManager.registerDefaultNetworkCallback(this.networkCallback);
} else {
this.connectivityManager.registerNetworkCallback(this.networkRequest, this.networkCallback);
}
} else {
this.context.registerReceiver(
this.networkStateWatcherReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
);
}
}
@Override
protected void onInactive() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
this.connectivityManager.unregisterNetworkCallback(this.networkCallback);
} else {
this.context.unregisterReceiver(this.networkStateWatcherReceiver);
}
}
// Inner method classes
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
private static final class NetworkStateWatcherReceiver extends BroadcastReceiver {
// Variables
private NetworkStateWatcherReceiver.OnNetworkChangedListener onNetworkChangedListener;
// Constructors
public NetworkStateWatcherReceiver() {
}
// Override methods
@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
if (this.onNetworkChangedListener != null) {
boolean isConnected = this.isConnected(context);
this.onNetworkChangedListener.onNetworkChangedListener(isConnected);
}
}
// Methods
private boolean isConnected(@NonNull Context context){
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
public void setOnNetworkChangedListener(@Nullable OnNetworkChangedListener onNetworkChangedListener) {
this.onNetworkChangedListener = onNetworkChangedListener;
}
// Inner interfaces
private interface OnNetworkChangedListener{
void onNetworkChangedListener(boolean isConnected);
}
}
}
在你的主活动中的onCreate方法中使用它
new NetworkWatcher(this).observe(this, aBoolean -> {
if (aBoolean){
// Internet connection available
} else {
// No internet connection
}
});
BroadcastReceiver
和android.net.conn.CONNECTIVITY_CHANGE
意图过滤器,只需在Application.OnCreate
中注册即可。当应用程序关闭时,您将不会收到任何更新。 - Pierrepublic class MainApplication extends Application implements Application.ActivityLifecycleCallbacks {...}
,重写public void onCreate() {
方法,在其中调用IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); registerReceiver(new MyBroadcastReceiver(), intentFilter);
。别忘了在你的AndroidManifest.xml
中添加android:name
到应用程序<application android:name=".MainApplication" ...>
。 - Pierre