ConnectivityManager/NetworkInfo 和 public wifi 代理

ConnectivityManager/NetworkInfo and public wifi proxy

我对 Android 中的 ConnectivityManagerNetworkInfo class 有疑问。

如果我走进 Tim Hortons、星巴克、麦当劳等,它们都有带密码或某种代理的免费 wifi,布尔值 isConnected() return 是否正确标记(在这种情况下,您将连接到 wifi,但互联网不可用,直到您 login/register)

如果这个标志(或 NetworkInfo 中的另一个标志)没有 return 正确的值,是否有类似 iPhone Reachability class 的东西检查这个标志。

谢谢

AP

我用了一个BroadcastReceiver接受了CONNECTIVITY_CHANGE

private void debugIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    if (extras != null) {
        for (String key: extras.keySet()) {
            LogText.appendLog(TAG + " key [" + key + "]: " +extras.get(key)); 
        }
    }
    else {
        LogText.appendLog(TAG + "no extras");
    }
}

@SuppressWarnings("deprecation")
public boolean hasConnectivity(final Context context, final Intent intent) {
    boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

    NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
    NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);

    if(currentNetworkInfo != null){
        return noConnectivity == false && currentNetworkInfo.isConnected();
    }

    return false;
}

public class ReachabilityTest extends AsyncTask<Void, Void, Boolean> {
    private Context mContext;
    private Intent mIntent;
    private String mHostname;
    private int mServicePort;

    public ReachabilityTest(Context context, Intent intent, String hostname, int port) {
        mContext = context.getApplicationContext(); // Avoid leaking the Activity!
        mIntent = intent;
        mHostname = hostname;
        mServicePort = port;
    }

    @Override
    protected Boolean doInBackground(Void... args) {
        if (hasConnectivity(mContext, mIntent)) {
            InetAddress address = isResolvable(mHostname);
            if (address != null) {
                if (canConnect(address, mServicePort)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        Intent newIntent = new Intent(mContext, NetworkConnService.class);
        newIntent.putExtra("hasConnectivity", result);
        mContext.startService(newIntent);
    }

    @SuppressWarnings("deprecation")
    private boolean hasConnectivity(final Context context, final Intent intent) {
        boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

        NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);

        if(currentNetworkInfo != null){
            LogText.appendLog("Current Network Info: " + currentNetworkInfo.getTypeName() + " isConnected: " + currentNetworkInfo.isConnected());
            return noConnectivity == false && currentNetworkInfo.isConnected();
        }
        if(otherNetworkInfo != null)
            LogText.appendLog("Other Network Info: " + otherNetworkInfo.getTypeName() + " isConnected: " + otherNetworkInfo.isConnected());

        return false;
    }

    private InetAddress isResolvable(String hostname) {
        try {
            return InetAddress.getByName(hostname);
        }
        catch (UnknownHostException e) {
            LogText.appendLog("isResolvable " + e.getLocalizedMessage());
            return null;
        }
    }

    private boolean canConnect(InetAddress address, int port) {
        Socket socket = new Socket();

        SocketAddress socketAddress = new InetSocketAddress(address, port);

        try {
            socket.connect(socketAddress, 2000);
        }
        catch (IOException e) {
            return false; 
        }
        finally {
            if (socket.isConnected()) {
                try {
                    socket.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return true;
    }

}