How to connect to a wireless network in android?

こ雲淡風輕ζ 提交于 2019-12-04 14:13:23

TO connect to WiFi AP needed to implement followed steps:

  1. Scan WiFi

    To be sure that you have appropriate AP. Bear in mind that you must provide password to secured AP. Suppose you know witch AP you prefer and now we are going to other step:

  2. Create new profile

    We need must support information about:

What type AP should be: Open spot, WEP, WPA, (or WPA2), with shared-key authentication, WPA2-Enterprise (RADIUS Server authentication)

Priority - Priority determines the preference given to a network by wpa_supplicant when choosing an access point with which to associate (I set default 1000)

SSID - AP Name

Password - if it's secured AP.

Here is a snippets method demonstrating the technique:

I used single enum TEncMode encMode for switch statement

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

For now we configured new AP according to our requst. Now lets create it:

  1. Create new AP only

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

if you skip this implementation, after turn WiFi off your created AP will dissapear m_WifiManager.saveConfiguration();

So far so good, we can wait for android to connect to our new AP or we can do it by ourselves

  1. Create and connect to 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;
}

That's all. For sure you can listen on WiFi state changed to catch CONNECTED event. Because we don't know how long it will take to device to connect to your AP. But we disabled all other APs and enabled new one. After we can get HTTP response for example from google to be sure that our AP has internet.

Asked me to add this method:

    /**
 * 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();
}

The only thing I know of, is checking the IP address to determine where you are connected. I would imagine that choosing the SSID would require using the device's interface (i.e. issuing an intent to the WiFi service instead of doing your own chooser).

For what it's worth, to detect where I'm connected, I use something like this:

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);
            }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!