3

アプリケーションでワイヤレス ネットワークをスキャンし、スキャン結果を取得することができました。しかし、アプリ自体を使用してそれらに接続できる方法はありますか? 接続しようとしているネットワークの暗号化タイプを指定する必要があるかどうか疑問に思っていましたか? 私の要件は、暗号化の種類に関係なく、ワイヤレスネットワークに接続することですか?

何か案は?ありがとう

4

2 に答える 2

3

次の手順を実装するために必要な WiFi AP に接続するには:

  1. Wi-Fiをスキャン

    適切な AP があることを確認します。保護された AP にパスワードを提供する必要があることに注意してください。好みのウィッチ AP を知っているとします。次は別の手順に進みます。

  2. 新しいプロファイルを作成

    以下に関する情報をサポートする必要があります。

AP の種類: オープン スポット、WEP、WPA、(または WPA2)、共有キー認証、WPA2-Enterprise (RADIUS サーバー認証)

優先度- 優先度は、アソシエートするアクセス ポイントを選択するときに wpa_supplicant によってネットワークに与えられる優先度を決定します (私はデフォルトの 1000 を設定しました)

SSID - APName

パスワード- セキュア AP の場合。

この手法を示すスニペット メソッドを次に示します。

enum TEncMode encModeswitch ステートメントに single を使用しました

....
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;
     }
    

列挙型 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;
}

それで全部です。CONNECTEDイベントをキャッチするように変更されたWiFi状態でリッスンできることを確認してください。デバイスが AP に接続するのにかかる時間がわからないためです。ただし、他のすべての AP を無効にし、新しい AP を有効にしました。たとえば、Google から 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();
}
于 2012-10-19T13:16:53.613 に答える
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);
            }
    }
于 2012-10-19T12:13:12.083 に答える