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

时间:2012-10-19 12:01:57

标签: android android-wifi android-wireless

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

有什么想法吗? 感谢

2 个答案:

答案 0 :(得分:4)

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

  1. 扫描WiFi

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

  2. 创建新的个人资料

    我们需要支持以下信息:

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

    优先级 - 优先级决定了给网络的偏好                    选择与之相关的接入点时,通过wpa_supplicant                    associate(我设置默认值为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   
              }
          }
      
    2. 如果您跳过此实施,在关闭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;
         }
        
      2. 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();
        }
        

答案 1 :(得分:1)

我唯一知道的是检查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);
            }
    }