【问题标题】:Check INTENT internet connection检查 INTENT 互联网连接
【发布时间】:2011-04-15 14:52:02
【问题描述】:

是否有 Android Intent ACTION_XXX 在 Internet 连接可用时通知我?

我想实例化一个BroadcastReceiver,当用户启用 Internet 连接(通过 wifi、GSM 等)时通知我的应用程序

谁能帮帮我?

【问题讨论】:

    标签: android android-intent broadcastreceiver


    【解决方案1】:
    <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" />
    

    【讨论】:

    • 此代码不适用于 Android 7+ 设备,因为 this
    • 是的,答案应该更新以供将来参考。
    • @ShreyashSSarnayak 是的。我要补充一点,从 android N 开始,您需要在活动中注册(和取消注册)您的广播接收器。将此保留在 XML Manifest 中不会影响您的 Activity 在 Android N 上接收连接更改的能力。只是对那些想知道的人进行澄清。
    • 面向 Android 7.0(API 级别 24)及更高版本的应用如果在清单中声明广播接收器,则不会接收 CONNECTIVITY_ACTION 广播。如果应用向 Context.registerReceiver() 注册 BroadcastReceiver 并且该上下文仍然有效,则应用仍将接收 CONNECTIVITY_ACTION 广播。
    【解决方案2】:

    接受的答案是正确的。我只添加 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");
            }
       }
    }
    

    【讨论】:

    • BroadcastReceiver.onReceive 是抽象的,所以你不能调用super.onReceive(context, intent);
    • 您在哪里查看(文档)以找出 getExtras() Bundle 的内容?
    【解决方案3】:

    更新到@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");
                }
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答。您已经解决了已弃用的EXTRA_NETWORK_INFO 的问题。 +1
    • 虽然这似乎效果更好,但我从未看到“无网络连接”消息,尽管关闭了 wifi 和移动数据
    • 这里的上下文是什么?
    • @MrPablo 和其他任何有同样问题的人都需要像这样在接收器上注册 wifi
    【解决方案4】:

    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

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

    更新

    如果您的应用以 API 级别 26 或更高级别为目标,则您无法使用 清单以声明隐式广播的接收器(广播 不专门针对您的应用程序),除了一些隐含的 不受该限制的广播。在大多数情况下,您 可以改为使用计划作业。

    用法 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)
      }
    

    更新 2

    CONNECTIVITY_ACTION 此常量在 API 级别 28 中已弃用。 应用程序应该使用更通用的requestNetwork(NetworkRequest, PendingIntent)registerNetworkCallback(NetworkRequest, PendingIntent)registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) 函数来更快、更详细地更新他们关心的网络变化。

    因为它added in API level 22,所以上面的代码在所有版本的android上都可以正常工作

    【讨论】:

    【解决方案5】:

    所有答案中缺少的部分是提醒您注册该操作:

    IntentFilter filter = new IntentFilter();
    filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
    registerReceiver(your_receiver, filter);
    

    【讨论】:

    • 接受的答案确实注册了监听器。它只是在清单中的 XML 中这样做,而不是在您建议的代码中。
    • @Ridcully 我认为较新版本的 SDK(22 以上?)不会像以前那样自动调用接收器。
    • @BrillPappin 你是对的 - 请参阅对已接受答案的评论,它指的是 android sdk 文档中的一个新部分:developer.android.com/training/monitoring-device-state/…
    【解决方案6】:

    我每次都使用广播来检查连接。为连接信息创建一个类。

    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;
        }
    }
    

    将代码应用到您的活动中:

     private BroadcastReceiver receiver = new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
            if(!ConnectivityStatus.isConnected(getContext())){
                // no connection
            }else {
                // connected
            }
        }
     };
    

    在您的活动的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));
        ..
        ...
        ....
      }
    

    不要忘记在活动周期取消注册/注册:

    @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);
    
    }
    

    【讨论】:

    • 您的解决方案是我发现的最好和最简单的解决方案,谢谢 :)
    • ConnectivityManager.CONNECTIVITY_ACTION 现已弃用。
    【解决方案7】:

    此代码将工作(在所有版本中),因为清单注册不适用于 7+(API 25 及更高版本) 设备请参阅此@987654321 @

    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
            } 
        }
    };
    

    【讨论】:

    • 您能否解释一下foo() 方法是什么以及我应该在哪里/如何使用它?谢谢。
    • @EJusius 在onResume 中注册接收器并在onPause 中注销它们
    • 如果我想在应用/活动未运行时检测网络变化怎么办?
    【解决方案8】:

    继续喵喵的回答

    您可以通过以下方式启用/禁用接收器:

    启用

     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();
       }
    

    禁用

    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();
       }
    

    其中,同样可以在 Intent 或 onCreate 中调用

    【讨论】:

    • 错字?:我认为您的意思是“禁用”为“启用”,反之亦然。
    【解决方案9】:

    NetworkInfo.isConnected() 是测试互联网状态的不可靠方法,当有网络连接时它会返回 true,即使它可能无法访问互联网(例如没有互联网的 wifi)。更可靠的方法是使用 pingCONNECTIVITY_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;
    }
    

    【讨论】:

      【解决方案10】:
      **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);
          }
      }
      

      【讨论】:

        【解决方案11】:

        从 Android 7++ 开始,@fedj 的回答将不起作用,但您可以通过编程方式注册广播接收器。

        面向 Android 7.0(API 级别 24)及更高版本的应用无法接收 如果他们声明广播接收器,则 CONNECTIVITY_ACTION 广播 在他们的清单中。应用仍会收到 CONNECTIVITY_ACTION 广播,如果他们注册他们的广播接收器 Context.registerReceiver() 并且该上下文仍然有效。

        【讨论】:

          【解决方案12】:

          我会阅读为 nougat + 更新的文档,因为由于设备数量不推荐使用意图,仅网络信息是不够的。我会在那里使用连接管理器(连接操作,添加变量)命令和变量,因为仅去年一年就发生了大多数变化,并且为了测试,启用单元数据始终处于活动状态,详细日志记录和积极切换,如果需要,使用 wlan 过滤器:

          https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION

          【讨论】:

            【解决方案13】:

            **你可以把这行代码放在Helper Methods上,当你想检查互联网连接时调用它**

            public static class InternetState {
                static ConnectivityManager cm;
            
                static public boolean isConnected(Context context) {
                    try {
                        cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                    } catch (NullPointerException e) {
            
                    }
            
                    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                    boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
                    return isConnected;
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-03-16
              • 2014-02-08
              • 2012-06-12
              • 1970-01-01
              • 1970-01-01
              • 2015-08-20
              • 2012-11-13
              • 2011-04-08
              相关资源
              最近更新 更多