Android - 以编程方式检查互联网连接并在未连接时显示对话框
Posted
技术标签:
【中文标题】Android - 以编程方式检查互联网连接并在未连接时显示对话框【英文标题】:Android - Programmatically check internet connection and display dialog if notConnected 【发布时间】:2013-07-26 15:51:12 【问题描述】:我正在做一个实时项目。当用户点击应用程序时。欢迎屏幕出现(该屏幕上有一个网络视图)。如果未连接互联网,则应用程序崩溃。基本上,我的问题是以编程方式检查移动设备是否连接到互联网。如果没有,则不要从 web 服务获取数据到 webview 并显示一个对话框,显示“检查您的互联网连接”
在进行研究时,我发现了很多东西,并且我已经尝试实施。但是,它不能满足我的要求
我的代码是,
public boolean isOnline()
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting())
return true;
else
Description.setVisibility(View.INVISIBLE);
new AlertDialog.Builder(WelcomePage.this)
.setTitle(getResources().getString(R.string.app_name))
.setMessage(
getResources().getString(
R.string.internet_error))
.setPositiveButton("OK", null).show();
return false;
我在doInBackground()
的AsyncTask
中调用这个函数
请帮忙!
【问题讨论】:
这是否检查互联网连接或 wifi 连接。我怀疑是后者,而互联网连接只能通过 ping 来验证? 【参考方案1】:你可以查看这个库:
https://github.com/novoda/merlin
您只需implement Connectable
,当网络出现故障或恢复时,您都会收到回调。
因此,您可以在这种情况下显示您的对话框。
你也可以查询库的当前状态,选择不做你的网络任务
创建 Merlin(使用 Merlin.Builder())
merlin = new Merlin.Builder().withConnectableCallbacks().build(context);
在您的活动中绑定和取消绑定服务
@Override
protected void onResume()
super.onResume();
merlin.bind();
@Override
protected void onPause()
super.onPause();
merlin.unbind();
注册回调
merlin.registerConnectable(new Connectable()
@Override
public void onConnect()
// Do something!
);
演示中的MerlinActivity 展示了一种将 Merlin 从主应用程序代码中整理出来的简单方法。
【讨论】:
如果您转到github.com/novoda/merlin 并向下滚动,请阅读自述文件,它的解释非常简单 每次我使用 merlin 完成第二个活动时,merlin 都会不断泄漏(第一次也是在使用它)(我在 onPause 和 onDestroy 中有 merlin.unbind 和 merlin == null) @KrzysztofDziuba 如果您在 GH 回购github.com/novoda/merlin/issues 上打开问题,我们将很乐意帮助您处理 Merlin 问题。【参考方案2】:终于,我得到了答案。
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMgr.getActiveNetworkInfo();
if (netInfo == null)
Description.setVisibility(View.INVISIBLE);
new AlertDialog.Builder(WelcomePage.this)
.setTitle(getResources().getString(R.string.app_name))
.setMessage(getResources().getString(R.string.internet_error))
.setPositiveButton("OK", null).show();
else
dialog = ProgressDialog.show(WelcomePage.this, "", "Loading...", true,false);
new Welcome_Page().execute();
【讨论】:
这不应该是预期的答案,因为您自己问如何检查 Internet 连接而不是网络连接,而上面的答案显示了后一部分 如果设备已连接到网络但没有数据(互联网)余额可供使用,这将执行 Welcome_Page() 您必须小心,因为 Internet 连接与网络连接不同。我强烈建议你使用像***.com/a/17880697/245638 这样可靠的东西,或者查看源代码【参考方案3】:NetworkInfo
类在 API 29 (android 10.0)
中被弃用,更多详情请参见此处:
This class was deprecated in API level 29. Use ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties to get information synchronously
更新代码(使用 Kotlin)
var isConnected = false
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
val networkCapabilities = connectivityManager.activeNetwork ?: return false
val activeNetwork = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
isConnected = when
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
else
connectivityManager.run
activeNetworkInfo?.run
isConnected = when (type)
ConnectivityManager.TYPE_WIFI -> true
ConnectivityManager.TYPE_MOBILE -> true
ConnectivityManager.TYPE_ETHERNET -> true
else -> false
【讨论】:
【参考方案4】:检查互联网连接
ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = mgr.getActiveNetworkInfo();
if (netInfo != null)
if (netInfo.isConnected())
// Internet Available
else
//No internet
else
//No internet
【讨论】:
【参考方案5】:这是检查您的互联网连接的简单功能。如果已连接,则返回 true,否则返回 false。
public boolean isInternetOn()
// get Connectivity Manager object to check connection
ConnectivityManager connec =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// Check for network connections
if (connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTED ||
connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTING ||
connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTING ||
connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTED)
return true;
else if (
connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.DISCONNECTED ||
connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.DISCONNECTED)
return false;
return false;
这是一个检查互联网连接并检查有效或包含在服务器 this 中的 URL 的项目。
【讨论】:
【参考方案6】:if (InternetConnection.checkConnection(context))
// Internet Available...
else
// Internet Not Available...
只复制下面的类
public class InternetConnection
/** CHECK WHETHER INTERNET CONNECTION IS AVAILABLE OR NOT */
public static boolean checkConnection(Context context)
final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
if (activeNetworkInfo != null) // connected to the internet
Toast.makeText(context, activeNetworkInfo.getTypeName(), Toast.LENGTH_SHORT).show();
if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI)
// connected to wifi
return true;
else if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE)
// connected to the mobile provider's data plan
return true;
return false;
授予以下权限以显示
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
【讨论】:
【参考方案7】:我尝试了上述不同的方法,除此之外,我在某些情况下被抓到了。所以最后,我使用下面的代码 sn-p 进行网络调用...
try
InetAddress address = InetAddress.getByName("www.***.com");
//Connected to working internet connection
catch (UnknownHostException e)
e.printStackTrace();
//Internet not available
这在许多方面都很有用。如果这种方法有问题,请告诉我。
【讨论】:
这可行,但必须在工作线程中执行。上面的代码给出了 Network on main thread 异常。 同意@SkyTreasure,这取决于我们如何使用这个sn-p ;) @SkyTreasure 能否给出在主线程中使用它的代码?【参考方案8】: public boolean isOnline()
NetworkInfo activeNetworkInfo = ((ConnectivityManager)
getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
return activeNetworkInfo != null &&
activeNetworkInfo.isConnectedOrConnecting();
【讨论】:
【参考方案9】:您的设备具有网络连接并不意味着您可以访问互联网。它可以是没有互联网的 wifi,也可以是没有数据包的数据 SIM。 从 API 23 开始,您可以使用下面的方法来检查它。您可以在 UI 上执行此操作。或者在广播接收器中。
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network currentnetwork = cm.getActiveNetwork();
if (currentnetwork != null)
if (cm.getNetworkCapabilities(currentnetwork).hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && cm.getNetworkCapabilities(currentnetwork).hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
// do your stuff. We have internet.
else
// We have no internet connection.
else
// We have no internet connection.
【讨论】:
【参考方案10】:private boolean isOnline()
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
这是官方的方式,谷歌也使用同样的方式来检查安卓设备的互联网连接。你可以在这里查看 - link。 这是一个非常完美的方法,它实际上检查互联网是否正常工作。
现在你的具体问题,使用一个计时器类,然后在 if(isOnline) 然后 toast 中放一个 toast。
【讨论】:
【参考方案11】:doInBackground
在与主 UI 不同的线程上运行,因此您无法在此处创建显示对话框。相反,在您的 AsyncTask
中覆盖 onPreExecute,并在那里进行测试。
【讨论】:
@Java_Android 它对我来说看起来不错 - 它只需要移动到不同的方法(在 UI 线程中运行的方法)。 @Java_Android 请阅读我的回答。您需要在onPreExecute
中执行此操作,您可以在 AsyncTask
中覆盖它。按照提供的链接获得更多帮助。
@Phil..Buddy,我也试过了......它既不能在主线程的“onCreate”中工作,也不能在“AsyncTask”的“onPreExecute”中工作【参考方案12】:
关于如何检查互联网连接的更新 Kotlin 和 Android 29 版本(getNetworkInfo 在 SDK 29 中已弃用)适用于 minSDK >= 23:
fun hasInternet(): Boolean
val connectivityManager = appContainer.contextProvider.currentAppContext()
.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
var hasInternet = false
capabilities?.let
hasInternet = it.hasCapability(NET_CAPABILITY_INTERNET)
return hasInternet
【讨论】:
【参考方案13】:这组代码可帮助您检查从 API 级别 16 到 30 的互联网连接是否可用
@SuppressWarnings("deprecation")
public static boolean isInternetAvailable(Activity activity)
ConnectivityManager conMgr = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
Network network = conMgr.getActiveNetwork();
NetworkCapabilities networkCapabilities = conMgr.getNetworkCapabilities(network);
if (networkCapabilities != null)
return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
else return false;
else
// below API Level 23
return conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()
&& conMgr.getActiveNetworkInfo().isConnected();
【讨论】:
【参考方案14】:Internet 连接也可以在onCreate()
或onResume()
方法中检查。无需在 AsyncTask 内部调用。
或者你可以在调用AsyncTask execute()方法之前调用
if(isOnline)
MyAsyncTask task=new MyAMyAsyncTask();
task.execute();
else
// no internet connection
【讨论】:
以上是关于Android - 以编程方式检查互联网连接并在未连接时显示对话框的主要内容,如果未能解决你的问题,请参考以下文章
检查 ufw 状态并在未激活时发送 Prometheus 警报