繁体   English   中英

如何在android中连接到无线网络?

[英]How to connect to a wireless network in android?

我已设法扫描无线网络并在我的应用程序中获取扫描结果。 但有没有办法可以使用我的应用程序本身连接到他们? 我想知道是否必须为我正在尝试连接的网络指定加密类型? 我的要求是连接到任何无线网络而不管它的加密类型?

有任何想法吗? 谢谢

要连接到实施以下步骤所需的WiFi AP:

  1. 扫描WiFi

    确保您有适当的AP。 请记住,您必须为安全的AP提供密码。 假设您知道自己喜欢的女巫AP,现在我们将采取其他措施:

  2. 创建新的个人资料

    我们需要支持以下信息:

应该是什么类型的AP :开放点,WEP,WPA,(或WPA2),具有共享密钥身份验证,WPA2-Enterprise(RADIUS服务器身份验证)

优先级 - 优先级确定wpa_supplicant在选择要关联的接入点时给予网络的优先级(我设置默认值1000)

SSID - AP Name

密码 - 如果它是安全的AP。

这是一个演示该技术的片段方法:

我使用单个enum TEncMode encMode来表示switch语句

....
WifiConfiguration wc = new WifiConfiguration();
    wc.allowedAuthAlgorithms.clear();
    wc.allowedGroupCiphers.clear();
    wc.allowedKeyManagement.clear();
    wc.allowedPairwiseCiphers.clear();
    wc.allowedProtocols.clear();

    switch (encMode) {
    case ENC_WEP:
        // If password is empty, it should be left untouched
        if (!TextUtils.isEmpty(pswd)) {

            wc.wepKeys[0] = TextUtil.convertToQuotedString(pswd);

        }

        wc.wepTxKeyIndex = 0;

        wc.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
        wc.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);

        wc.allowedKeyManagement.set(KeyMgmt.NONE);

        wc.allowedGroupCiphers.set(GroupCipher.WEP40);
        wc.allowedGroupCiphers.set(GroupCipher.WEP104);
        break;

    case ENC_WPA:
    case ENC_WPA2:
        wc.allowedGroupCiphers.set(GroupCipher.TKIP);
        wc.allowedGroupCiphers.set(GroupCipher.CCMP);

        wc.allowedKeyManagement.set(KeyMgmt.WPA_PSK);

        wc.allowedPairwiseCiphers.set(PairwiseCipher.CCMP);
        wc.allowedPairwiseCiphers.set(PairwiseCipher.TKIP);

        wc.allowedProtocols.set(Protocol.RSN);
        wc.allowedProtocols.set(Protocol.WPA);

        // If password is empty, it should be left untouched
        if (!TextUtils.isEmpty(pswd)) {
            if (pswd.length() == 64) {
                // Goes unquoted as hex
                wc.preSharedKey = pswd;
            } else {
                // Goes quoted as ASCII
                wc.preSharedKey = TextUtil.convertToQuotedString(pswd);
            }
        }
        break;

        //      case ENC_WPA2_ENTERPRISE:
        ....
        //          break;

    default:
        wc.allowedKeyManagement.set(KeyMgmt.NONE);
        break;
    }

    // This is must be quoted according to the documentation 
    // http://developer.android.com/reference/android/net/wifi/WifiConfiguration.html#SSID
    wc.SSID = TextUtil.convertToQuotedString(ssid.toString());

    wc.hiddenSSID = false;
    wc.priority = prior;
    wc.BSSID = null;


    wc.status = WifiConfiguration.Status.ENABLED; 

现在我们根据我们的要求配置了新的AP。 现在让我们创建它:

  1. 仅创建新AP

      .... int res = -1; WifiManager m_WifiManager = (WifiManager)m_context.getSystemService(Context.WIFI_SERVICE); .... /** If profile exists, do nothing */ if(ifConnectionProfileExists(ssid) == true){ Log.i(Constants.TAG, "createConnectionProfile :: " + "CREATE_PROFILE ssid=" + ssid + " exists"); } else{ res = m_WifiManager.addNetwork(wc); Log.i(Constants.TAG, "createConnectionProfile :: " + " CREATE_PROFILE ssid=" + ssid + " dosn't exist, addNetwork ... res = " + res); // Don't make to AP high priority to connect //m_WifiManager.enableNetwork(res, false); m_WifiManager.saveConfiguration(); if(res != -1){ // profile created } else{ // failed to add profile } } 

如果你跳过这个实现,关闭WiFi关闭你创建的AP将消失m_WifiManager.saveConfiguration();

到目前为止,我们可以等待android连接到我们的新AP,或者我们可以自己做

  1. 创建并连接到AP

      int res = -1; /** If profile exists, do nothing */ if(ifConnectionProfileExists(ssid) == true){ res = getNetIdBySSID(ssid); } else{ res = m_WifiManager.addNetwork(wc); } // Don't make to AP high priority to connect boolean b = m_WifiManager.enableNetwork(res, true); if(b == true){ fixSupplicant(); m_WifiManager.saveConfiguration(); // start connect to AP } else{ // failed } .... private void fixSupplicant() { final SupplicantState state = m_WifiManager.getConnectionInfo().getSupplicantState(); boolean isReconnectDone = false; if ((state == SupplicantState.SCANNING) || (state == SupplicantState.DISCONNECTED) || (state == SupplicantState.DORMANT)) { isReconnectDone = m_WifiManager.reconnect();; } } private boolean ifConnectionProfileExists(String ssid){ List<WifiConfiguration> apProfiles = m_WifiManager.getConfiguredNetworks(); // remove profile if exists: for (int i = 0; i < apProfiles.size(); i++) { final WifiConfiguration ap = apProfiles.get(i); if ((ap.SSID != null)) { // try to find by SSID if (TextUtils.equals(ap.SSID), ssid) { return true; } } } return false; } 

Enum TEncMode

/**
* Represents encryption types modes of access points
*/
public enum TEncMode {

/**
 * No encryption (open spot)
 */
ENC_NONE(0),

/*
 * General encryption
 */
ENC_UNKNOWN(1),

/**
 * WEP
 */
ENC_WEP(2),

/**
 * WPA
 */
ENC_WPA(3),

/**
 * WPA (or WPA2), with shared-key authentication
 */
ENC_WPA2(4),

/**
 * WPA2-Enterprise (RADIUS Server authentication).
 */
ENC_WPA2_ENTERPRISE(5)
;

public static TEncMode
FromIntToEnum(
    int value ) throws Exception
{
    for ( TEncMode c : TEncMode.values() ) {
        if ( c.mId == value ) {
            return c;
        }
    }

    throw new AgException( new StringBuilder("Illegal TEncMode: ").append(value).toString() );
}

public int
FromEnumToInt() {
    return mId;
}

private TEncMode( int id ){
    mId = id;
}

private int mId;
}

就这样。 肯定你可以听取WiFi状态改变以捕获CONNECTED事件。 因为我们不知道设备连接到您的AP需要多长时间。 但我们禁用了所有其他AP并启用了新AP。 我们可以从谷歌获得HTTP响应,以确保我们的AP有互联网。

要我添加这个方法:

    /**
 * Surround the given string in quotes.
 * 
 * @param string The text to surround in quotes.
 * @return string wrapped with quotes.
 */
static public String convertToQuotedString(String string){

    if (string==null) {
        string = "";
    }
    empty(workBuffer);
    workBuffer.append("\"");
    workBuffer.append(string);
    workBuffer.append("\"");

    return workBuffer.toString();
}

我唯一知道的是检查IP地址以确定您的连接位置。 我认为选择SSID需要使用设备的接口(即向WiFi服务发出意图而不是自己选择)。

为了它的价值,检测我连接的位置,我使用这样的东西:

package com.nifty.android.initialization;

import android.content.Context;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.nifty.android.R;
import com.nifty.android.preferences.Preferences;

public class NetworkDetector {
    Context mContext = null;
    Preferences mPrefs = null;

    public static final String NONE                =        "none";
    public static final String HI_SPEED            =        "hiSpeed";
    public static final String MED_SPEED           =        "medSpeed";
    public static final String LOW_SPEED           =        "lowSpeed";

    public NetworkDetector(Context aContext) {
            mContext = aContext;
            mPrefs = new Preferences(aContext);

            WifiManager lWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
            TelephonyManager lTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

            String netSpeed = null;

            if( (lWifiManager.isWifiEnabled() && lWifiManager.getConnectionInfo() != null && lWifiManager.getConnectionInfo().getIpAddress() != 0)) {
                    netSpeed = HI_SPEED;
            } else {
                    if(lTelephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS  && lTelephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED) {
                            netSpeed = MED_SPEED;
                    } else {
                            if( (   lTelephonyManager != null && lTelephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED) ){
                                    netSpeed = LOW_SPEED;
                            } else {
                                    netSpeed = NONE;
                            }
                    }
            }

            mPrefs.networkSpeed(netSpeed);
            }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM