检查INTENT互联网连接


70

Intent ACTION_XXX可用的Internet通知我的Android吗?

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

有人可以帮我吗?

Answers:


161
<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" />

27
这段代码,因为Android的设备7+不工作
Shreyash小号Sarnayak

是的,应该更新答案以供将来参考。
Sarthak Mittal

5
@ShreyashSSarnayak是的。我要补充一点,从android N开始,您需要在活动中注册(和注销)您的广播接收器。将此保留在XML清单中不会干扰您的活动在Android N上接收连接性更改的能力。这只是对那些想知道的人的澄清。
severin.julien

1
如果目标为Android 7.0(API级别24)及更高版本的应用在清单中声明了广播接收器,则不会接收CONNECTIVITY_ACTION广播。如果应用向C​​ontext.registerReceiver()注册其BroadcastReceiver,并且该上下文仍然有效,则它们仍将接收CONNECTIVITY_ACTION广播。
vivek verma

127

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

26
BroadcastReceiver.onReceive是抽象的,因此您不能调用super.onReceive(context, intent);
菲利佩·利马

3
您在哪里看了一下(文档)以了解getExtras()捆绑包的内容?
ЯрославРахматуллин

56

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

5
感谢您的回答。您已经解决了已弃用的问题EXTRA_NETWORK_INFO。+1
Sami Eltamawy 2015年

2
尽管这似乎更好,但尽管关闭了wifi和移动数据,但我从未看到“没有网络连接”消息
Pablo Mr

这里的背景是什么?
巴尔加夫

1
@MrPablo和其他有相同问题的人,您需要在接收器上注册wifi,例如<receiver android:name =“ com.swipeclock.android.network.receivers.NetworkStateReceiver”> <intent-filter> <action android:name =“ android .net.wifi.supplicant.CONNECTION_CHANGE“ /> <action android:name =” android.net.wifi.STATE_CHANGE“ /> <action android:name =” android.net.conn.CONNECTIVITY_CHANGE“ /> </ intent-filter > </ receiver>
Marc Niceler '17

19

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上都能正常工作


对不起,先生,你可以看到更多在这里或google一下:stackoverflow.com/questions/14701422/...
vuhung3990

你好,你可以回答这个问题,请stackoverflow.com/questions/28294677/...
JRE.exe

您可以Ping检查互联网访问,如果超时已连接但没有互联网,那是正确的,因为我看到您已经这样做了
vuhung3990 2015年

17

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

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

4
接受的答案会注册侦听器。它只是在清单中的XML中执行此操作,而不是像您建议的代码中那样执行。
2015年

@Ridcully我认为较新版本的SDK(高于22?)不会像过去那样自动调用接收方。
Brill Pappin

1
@BrillPappin您说对了-请参阅已接受答案的评论,该评论指的是android sdk文档中的新部分:developer.android.com/training/monitoring-device-state/…–
Ridcully

8

我正在使用广播来每次检查连接。创建一个用于连接信息的类。

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

}

1
您的解决方案是我发现的最好,最简单的解决方案,谢谢:)
艾哈迈德·穆萨

ConnectivityManager.CONNECTIVITY_ACTION现在已弃用。
tahsinRupam

8

该清单代码(在所有版本中均适用),因为清单注册不适用于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
        } 
    }
};

您能解释一下什么foo()方法以及在哪里/应该使用它吗?谢谢。
小飞象

@EJusius在其中注册接收者,onResume并在以下位置注销他们的注册onPause
Santhosh '18

如果应用/活动未运行时我想检测网络更改怎么办?
Mohaimanul Chowdhury

6

继续喵喵的答案

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

使能

 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中调用


2
Typos ?:我认为您的意思是“禁用”为“启用”,反之亦然。
JDOaktown '16

3

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

2
**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);
    }
}

1

在Android 7 ++中,@ fedj的答案无效,但是您可以通过编程方式注册广播接收器。

如果目标为Android 7.0(API级别24)及更高版本的应用在清单中声明了广播接收器,则不会接收CONNECTIVITY_ACTION广播。如果应用向C​​ontext.registerReceiver()注册其BroadcastReceiver,并且该上下文仍然有效,则它们仍将接收CONNECTIVITY_ACTION广播。


0

我会阅读针对nougat +更新的文档,因为由于设备数量而弃用了Intent,仅靠网络信息是不够的。我将在此处使用连接管理器(连接操作,在其中添加变量)命令和变量,因为大多数仅在去年进行了更改,然后进行测试,启用单元数据始终处于活动状态,详细的日志记录和主动切换,如果需要,请使用wlan筛选器:

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


0

**您可以将这行代码放在“辅助方法”上,并在需要检查互联网连接时调用它**

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;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.