Android 检查 INTENT 互联网连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3767591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check INTENT internet connection
提问by CeccoCQ
Is there an Android Intent ACTION_XXX
that notifies me when an Internet Connection is available?
Intent ACTION_XXX
当 Internet 连接可用时,是否有 Android会通知我?
I want to instantiate a BroadcastReceiver
that notifies my application when a user enables Internet Connection (by wifi, by GSM, etc.)
BroadcastReceiver
当用户启用 Internet 连接(通过 wifi、通过 GSM 等)时,我想实例化通知我的应用程序
Could anyone help me?
有人可以帮助我吗?
回答by fedj
<receiver android:name=".YOURRECEIVER">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
回答by lujop
Accepted answer is correct. I only add Receiver code for completion:
接受的答案是正确的。我只添加 Receiver 代码来完成:
public class NetworkStateReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Log.d("app","Network connectivity change");
if(intent.getExtras()!=null) {
NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
Log.i("app","Network "+ni.getTypeName()+" connected");
} else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
Log.d("app","There's no network connectivity");
}
}
}
回答by Felipe Lima
Update to @lujop answer:
更新@lujop 答案:
public class NetworkStateReceiver extends BroadcastReceiver {
private static final String TAG = "NetworkStateReceiver";
@Override
public void onReceive(final Context context, final Intent intent) {
Log.d(TAG, "Network connectivity change");
if (intent.getExtras() != null) {
final ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo ni = connectivityManager.getActiveNetworkInfo();
if (ni != null && ni.isConnectedOrConnecting()) {
Log.i(TAG, "Network " + ni.getTypeName() + " connected");
} else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
Log.d(TAG, "There's no network connectivity");
}
}
}
}
回答by vuhung3990
MyReceiver.java
我的接收器
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(isConnected(context)) Toast.makeText(context, "Connected.", Toast.LENGTH_LONG).show();
else Toast.makeText(context, "Lost connect.", Toast.LENGTH_LONG).show();
}
public boolean isConnected(Context context) {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
return isConnected;
}
}
AndroidManifest.xml
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
UPDATE
更新
If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for implicit broadcasts (broadcasts that do not target your app specifically), except for a few implicit broadcasts that are exempted from that restriction. In most cases, you can use scheduled jobs instead.
如果您的应用面向 API 级别 26 或更高级别,则不能使用清单声明隐式广播(不专门针对您的应用的广播)的接收器,除了一些不受该限制的隐式广播。在大多数情况下,您可以改用计划作业。
usage
connection = MyReceiver()
用法
connection = MyReceiver()
// onCreate - onDestroy, onResume - onPause depends on you
override fun onStart() {
super.onStart()
registerReceiver(connection, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}
override fun onStop() {
super.onStop()
// remember unregister to avoid leak
unregisterReceiver(connection)
}
UPDATE 2
更新 2
CONNECTIVITY_ACTION
This constant was deprecated in API level 28.
apps should use the more versatile requestNetwork(NetworkRequest, PendingIntent)
, registerNetworkCallback(NetworkRequest, PendingIntent)
or registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback)
functions instead for faster and more detailed updates about the network changes they care about.
CONNECTIVITY_ACTION
这个常量在 API 级别 28 中被弃用。应用程序应该使用更通用的requestNetwork(NetworkRequest, PendingIntent)
,registerNetworkCallback(NetworkRequest, PendingIntent)
或registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback)
函数来代替他们关心的网络变化的更快和更详细的更新。
because it added in API level 22
, so above code will work fine on all versions of android
因为它added in API level 22
,所以上面的代码可以在所有版本的 android 上正常工作
回答by hasan
The missing part of all answers is a reminder to register for that action:
所有答案中缺少的部分是提醒您注册该操作:
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(your_receiver, filter);
回答by Nicky
This code will work (in all versions)as the manifest registration will not work for 7+(API 25 and above)devices see this link.
此代码将适用(在所有版本中),因为清单注册不适用于7+(API 25 及更高版本)设备,请参阅此链接。
private void foo(){
registerReceiver(connectionBroadcastReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
private BroadcastReceiver connectionBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || intent.getExtras() == null)
return;
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getState() == NetworkInfo.State.CONNECTED) {
// connected
}
}
};
回答by W4R10CK
I'm using broadcast to check the connection every time. Create a class for connection info.
我每次都使用广播来检查连接。为连接信息创建一个类。
import android.content.Context;
import android.content.ContextWrapper;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class ConnectivityStatus extends ContextWrapper{
public ConnectivityStatus(Context base) {
super(base);
}
public static boolean isConnected(Context context){
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo connection = manager.getActiveNetworkInfo();
if (connection != null && connection.isConnectedOrConnecting()){
return true;
}
return false;
}
}
Apply code into your Activity:
将代码应用到您的活动中:
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(!ConnectivityStatus.isConnected(getContext())){
// no connection
}else {
// connected
}
}
};
Register broadcast in your activity's onCreate()
method:
在您的活动onCreate()
方法中注册广播:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
your_activity_context.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
..
...
....
}
Don't forget to unregistered/register on Activity cycle:
不要忘记在活动周期取消注册/注册:
@Override
protected void onResume() {
super.onResume();
your_activity_context.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
@Override
protected void onPause() {
super.onPause();
your_activity_context.unregisterReceiver(receiver);
}
回答by JRE.exe
Continuing meow mwo's Answer
继续喵喵的回答
you can enable/disable the receiver by:
您可以通过以下方式启用/禁用接收器:
enable
使能够
ComponentName receiver = new ComponentName(MainActivity.this, MyReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
Toast.makeText(this, "Disabled broadcst receiver", Toast.LENGTH_SHORT).show();
}
disable
禁用
ComponentName receiver = new ComponentName(MainActivity.this, MyReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
Toast.makeText(this, "Enabled broadcast receiver", Toast.LENGTH_SHORT).show();
}
where, the same can be called in an Intent or in onCreate
其中,可以在 Intent 或 onCreate 中调用相同的方法
回答by razz
NetworkInfo.isConnected()
is unreliable method to test for internet status, it will return true when there is a network connection even though it may have no internet access (ex. wifi with no internet). A more reliable approach would be to use ping
with a CONNECTIVITY_ACTION
BroadcastReceiver
:
NetworkInfo.isConnected()
是不可靠的测试互联网状态的方法,即使它可能没有互联网访问(例如没有互联网的wifi),当有网络连接时它也会返回true。更可靠的方法是ping
与 a一起使用CONNECTIVITY_ACTION
BroadcastReceiver
:
private void registerInternetReceiver()
{
if (this.internetReceiver != null) return;
this.internetReceiver = new BroadcastReceiver()
{
@Override
public void onReceive (Context context, Intent intent)
{
if (isInternetAvailable()) Log.i ("Tag", "internet status online");
else Log.i ("Tag", "internet status offline");
}
};
IntentFilter filter = new IntentFilter();
filter.addAction (ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver (internetReceiver, filter);
}
private boolean isInternetAvailable()
{
try
{
return (Runtime.getRuntime().exec ("ping -c 1 google.com").waitFor() == 0);
}
catch (Exception ex)
{
ex.printStackTrace();
}
return false;
}
回答by Coldfin Lab
**Also worked on above Android 7.0**
// AndroidManifest.xml
<service
android:name=".NetworkSchedulerService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"/>
// MyApplication.java
import android.app.Application;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
public class MyApplication extends Application {
private static Context context;
public static Context getContext() {
return context;
}
public static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication mInstance;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
mInstance = this;
scheduleJob();
}
public static synchronized MyApplication getInstance() {
return mInstance;
}
private void scheduleJob()
{
JobInfo myJob = new JobInfo.Builder(0, new ComponentName(this, NetworkSchedulerService.class))
.setRequiresCharging(true)
.setMinimumLatency(1000)
.setOverrideDeadline(2000)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.build();
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
assert jobScheduler != null;
jobScheduler.schedule(myJob);
}
}
// Constants.java
public class Constants {
public static final String CONNECT_TO_WIFI = "WIFI";
public static final String CONNECT_TO_MOBILE = "MOBILE";
public static final String NOT_CONNECT = "NOT_CONNECT";
public final static String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
}
// LiveConnectivityReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class LiveConnectivityReceiver extends BroadcastReceiver {
private MConnectivityReceiver mConnectivityReceiver;
LiveConnectivityReceiver(MConnectivityReceiver listener) {
mConnectivityReceiver = listener;
}
@Override
public void onReceive(Context context, Intent intent) {
mConnectivityReceiver.onNetworkConnectionChanged(isConnected(context));
}
public static boolean isConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
public interface MConnectivityReceiver {
void onNetworkConnectionChanged(boolean isConnected);
}
}
// MainActivity.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver mReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStop() {
stopService(new Intent(this, NetworkSchedulerService.class));
super.onStop();
}
@Override
protected void onStart() {
super.onStart();
startService( new Intent(this, NetworkSchedulerService.class));
}
@Override
protected void onPause() {
super.onPause();
this.unregisterReceiver(this.mReceiver);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter("android.intent.action.MAIN");
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean isConnection = intent.getBooleanExtra("VALUE", false);
if (!isConnection) {
Toast.makeText(context, "No Internet Connection", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Back to online", Toast.LENGTH_SHORT).show();
}
}
};
this.registerReceiver(mReceiver, intentFilter);
}
}
// NetworkSchedulerService.java
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
import android.content.IntentFilter;
public class NetworkSchedulerService extends JobService implements LiveConnectivityReceiver.ConnectivityReceiverListener
{
private LiveConnectivityReceiver mLiveConnectivityReceiver;
@Override
public void onCreate()
{
super.onCreate();
mLiveConnectivityReceiver = new LiveConnectivityReceiver(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
registerReceiver(mLiveConnectivityReceiver, new IntentFilter(Constants.CONNECTIVITY_ACTION));
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
unregisterReceiver(mLiveConnectivityReceiver);
return true;
}
@Override
public void onNetworkConnectionChanged(boolean isConnected)
{
Intent broadcastedIntent=new Intent("android.intent.action.MAIN");
broadcastedIntent.putExtra("VALUE", isConnected);
sendBroadcast(broadcastedIntent);
}
}