【问题标题】:How to check internet connectivity continuously in background while android application runningandroid应用程序运行时如何在后台连续检查互联网连接
【发布时间】:2014-01-21 09:50:30
【问题描述】:

我想在我的 android 应用程序运行时在后台连续检查互联网连接。我的意思是从申请开始到申请结束。我该怎么做?应该怎么做?

【问题讨论】:

标签: android


【解决方案1】:

我知道我回答这个问题迟到了。 但这是一种在 Activity/Fragment 中持续监控网络连接的方法。

我们将使用网络回调来监控我们在 Activity/Fragment 中的连接

首先,在类中声明两个变量

// to check if we are connected to Network
boolean isConnected = true;

// to check if we are monitoring Network
private boolean monitoringConnectivity = false;

接下来,我们将编写网络回调方法

private ConnectivityManager.NetworkCallback connectivityCallback
            = new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(Network network) {
            isConnected = true;
            LogUtility.LOGD(TAG, "INTERNET CONNECTED");
        }

        @Override
        public void onLost(Network network) {
            isConnected = false;
            LogUtility.LOGD(TAG, "INTERNET LOST");
        }
    };

现在既然我们已经编写了回调函数,我们现在将编写一个方法来监控我们的网络连接,并且在这个方法中,我们将注册我们的 NetworkCallback。

// Method to check network connectivity in Main Activity
    private void checkConnectivity() {
        // here we are getting the connectivity service from connectivity manager
        final ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(
                Context.CONNECTIVITY_SERVICE);

        // Getting network Info
        // give Network Access Permission in Manifest
        final NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();

        // isConnected is a boolean variable
        // here we check if network is connected or is getting connected
        isConnected = activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();

        if (!isConnected) {
            // SHOW ANY ACTION YOU WANT TO SHOW
            // WHEN WE ARE NOT CONNECTED TO INTERNET/NETWORK
            LogUtility.LOGD(TAG, " NO NETWORK!");
// if Network is not connected we will register a network callback to  monitor network
            connectivityManager.registerNetworkCallback(
                    new NetworkRequest.Builder()
                            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                            .build(), connectivityCallback);
            monitoringConnectivity = true;
        }

    }

我们所有的工作都快完成了,我们只需要调用我们的 checkConnectivity(),我们的 Activity/Fragment 的 onResume() 中的方法

  @Override
    protected void onResume() {
        super.onResume();
        checkConnectivity();
    }

*unRegister the NetworkCallback in onPause() ,method of your Activity/Fragment *

   @Override
    protected void onPause() {
        // if network is being moniterd then we will unregister the network callback
        if (monitoringConnectivity) {
            final ConnectivityManager connectivityManager
                    = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            connectivityManager.unregisterNetworkCallback(connectivityCallback);
            monitoringConnectivity = false;
        }
        super.onPause();
    }

就是这样,只需添加这段代码,你的活动/片段的每个类都是你需要监控网络的!别忘了取消注册!!!

【讨论】:

  • 我注意到当用户切换网络(例如从 wifi 到蜂窝)时,首先为蜂窝网络调用 onAvailable(),然后为断开的 wifi 网络调用 onLost()。因此,该应用程序的行为就像没有网络一样。你有解决办法吗?
  • 尝试在 onLost() 方法中执行代码之前添加一些延迟。延迟 5 或 10 秒就足够了。如果这没有帮助,请检查我的库是否没有网络连接 github.com/vasu-bhardwaj/NoInternet.This 库使用可观察设计模式。
  • 我还注意到,当 WIFI 连接但没有互联网可用时,此代码不会涵盖该场景。我们如何才能从这种情况中克服任何可以避免定期 ping 的情况。
【解决方案2】:

创建扩展BroadcastReceiver 的类,使用ConnectivityManager.EXTRA_NO_CONNECTIVITY 获取连接信息。

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.widget.Toast;

public class CheckConnectivity extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent arg1) {

    boolean isConnected = arg1.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
    if(isConnected){
        Toast.makeText(context, "Internet Connection Lost", Toast.LENGTH_LONG).show();
    }
    else{
        Toast.makeText(context, "Internet Connected", Toast.LENGTH_LONG).show();
    }
   }
 }

在 mainfest 中也添加此权限

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

【讨论】:

  • 糟糕的主意!使用服务进行网络检查,然后从 BroadcastReceiver 中提取它
【解决方案3】:

在 Activity 或片段中

public static final String BROADCAST = "checkinternet";
IntentFilter intentFilter;

在 oncreate 中

   intentFilter = new IntentFilter();
   intentFilter.addAction(BROADCAST);
   Intent serviceIntent = new Intent(this,Networkservice.class);
   startService(serviceIntent);
   if (Networkservice.isOnline(getApplicationContext())){
       Toast.makeText(getApplicationContext(),"true",Toast.LENGTH_SHORT).show();
   }else
       Toast.makeText(getApplicationContext(),"false",Toast.LENGTH_SHORT).show();

在创建之外

 public BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(BROADCAST)){
            if (intent.getStringExtra("online_status").equals("true")){
                Toast.makeText(getApplicationContext(),"true",Toast.LENGTH_SHORT).show();
                Log.d("data","true");
            }else {
                Toast.makeText(getApplicationContext(), "false", Toast.LENGTH_SHORT).show();
                Log.d("data", "false");
            }
        }
    }
};

@Override
protected void onRestart() {
    super.onRestart();
    registerReceiver(broadcastReceiver,intentFilter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(broadcastReceiver);
}

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(broadcastReceiver,intentFilter);
}

//类

public class Networkservice extends Service {

@Override
public void onCreate() {
    super.onCreate();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    handler.post(perioud);
    return START_STICKY;
}
public static boolean isOnline(Context context){
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo nf=cm.getActiveNetworkInfo();
    if (nf!=null&&nf.isConnectedOrConnecting())
        return true;
        else
            return false;
}
Handler handler=new Handler();
private Runnable perioud =new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(perioud,1*1000- SystemClock.elapsedRealtime()%1000);

        Intent intent = new Intent();
        intent.setAction(MainActivity.BROADCAST);
        intent.putExtra("online_status",""+isOnline(Networkservice.this));
        sendBroadcast(intent);
    }
};
}

【讨论】:

    【解决方案4】:

    Android 系统已经为您做到了。无需不断轮询手机网络状态,而是注册BroadcastReceivers 获取 WiFi 和网络状态变化,并在 WiFi 或网络状态变化时处理系统发送的 Intents。

    查看this question 了解更多信息。

    一旦您注册了BroadcastReceiver,网络状态更改侦听将在后台(在操作系统中)发生,并且Intent 将在网络状态更改时(很可能)在 UI 线程上发送到您的接收器.如果您想在后台线程上接收Intents,请查看this question 了解更多信息。

    【讨论】:

      【解决方案5】:

      你也可以试试这个服务类。只需设置以秒为单位的时间间隔和要 ping 的 url:

      Android Check Internet Connection

      只记得将服务添加到Manifest文件中,并添加权限

      【讨论】:

        【解决方案6】:

        要检查互联网连接,只需为 CONNECTIVITY_CHANGEWIFI_STATE_CHANGED 注册广播。因此,每当互联网连接或断开连接事件发生时,我们的 BroadcastReceiver 的 onReceive 方法就会被调用,我们可以在其中编写逻辑。

        在 AndroidManifest.xml 中

         <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
             <uses-permission android:name="android.permission.INTERNET" />
             <receiver
                    android:name="NetworkChangeReceiver"
                    android:label="NetworkChangeReceiver" >
                    <intent-filter>
                        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                        <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
                    </intent-filter>
                </receiver>
        

        在 NetworkChangeReceiver 类中。

         public class NetworkChangeReceiver extends BroadcastReceiver {
            
                @Override
                public void onReceive(final Context context, final Intent intent) {
            
                    int status = NetworkUtil.getConnectivityStatusString(context);
                    if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
                        if (status == NetworkUtil.NETWORK_STATUS_NOT_CONNECTED) {
                         
                          //write code for internet is disconnected...
        
                        } else {
        
                           //write code for internet is connected...
        
                        }
                   }
                }
            }
        

        检查互联网状态。

         public class NetworkUtil {
            public static final int TYPE_NOT_CONNECTED = 0;
                public static final int TYPE_WIFI = 1;
                public static final int TYPE_MOBILE = 2;
                public static final int NETWORK_STATUS_NOT_CONNECTED = 3;
                public static final int NETWORK_STATUS_WIFI = 4;
                public static final int NETWORK_STATUS_MOBILE = 5;
            
                public static int getConnectivityStatus(Context context) {
                    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            
                    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                    if (null != activeNetwork) {
                        if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                            return TYPE_WIFI;
            
                        if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                            return TYPE_MOBILE;
                    } 
                    return TYPE_NOT_CONNECTED;
                }
            
                public static int getConnectivityStatusString(Context context) {
                    int conn = NetworkUtil.getConnectivityStatus(context);
                    int status = 0;
                    if (conn == NetworkUtil.TYPE_WIFI) {
                        status = NETWORK_STATUS_WIFI;
                    } else if (conn == NetworkUtil.TYPE_MOBILE) {
                        status = NETWORK_STATUS_MOBILE;
                    } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
                        status = NETWORK_STATUS_NOT_CONNECTED;
                    }
                    return status;
                }
            }
        

        【讨论】:

          猜你喜欢
          • 2019-08-22
          • 2013-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-14
          • 1970-01-01
          • 2013-02-02
          相关资源
          最近更新 更多