Android/WI-FI | Posted by 덩치 2015. 8. 31. 14:55

소스코드로 WiFi 연결시키기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO




WPA2 이외 보안방식에서도 작동하는지 테스트 안됨.

테스트 해보신분 댓글로 알려주시면 감사하겠습니다.


WifiConfiguration wifiConfig = new WifiConfiguration();

wifiConfig.SSID = String.format("\"%s\"", "ssid");

wifiConfig.preSharedKey = String.format("\"%s\"", "password");


WifiManager wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);

int netId = wifiManager.addNetwork(wifiConfig);

wifiManager.disconnect();

wifiManager.enableNetwork(netId, true);

wifiManager.reconnect();




출처 : http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically



Android/WI-FI | Posted by 덩치 2015. 5. 8. 11:13

Wifi 비활성화일 때 스캔하는 방법

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO



일반적으로 많이 알려진 Wifi Scan 방법은 Wifi 활성화 돼 있을때만 가능하다.


때문에 Wifi Scan이 필요할 때, 사용자의 Wifi를 강제로 Enable 시킨 뒤 스캔을 하고, 스캔이 끝다면 다시 비활성화 시키는


방식으로 많이들 구현한다.


그런데 Android 버전 4.3(SDK 18)부터 추가된 '항상 검색 허용' 설정을 이용하면 Wifi비활성화 상태라


Wifi스캔할 수 있다.




해당 옵션이 활성화 돼 있을때만 위와같은 동작이 가능하다.


소스코드상으로는 해당 설정을 컨트롤 할 수 없으며, 사용자가 직접 설정할 수 있다.



따라서 SDK 버전이 18 이상인지, '항상 검색 허용' 설정이 활성화상태인지 체크를 한 다음


조건을 만족하지 않는다면 기존 방식을 이용하고, 만족한다면 Wifi를 건들지 않고 바로 스캔을 진행할 수 있다.



위 조건을 구현하는 방법은 아래와 같다.


if (Build.VERSION.SDK_INT >= 18) {  //  4.3 버전 이상인지 체크한다.

if (mWM.isScanAlwaysAvailable()) {  //  항상검색 허용 설정이 활성화상태인지 체크한다.

mWM.startScan();  // 바로 스캔 실행

return;

}

}

mWM.setWifiEnabled(true);

// 위 조건을 만족하지 않는다면 Wifi 상태에 변화를 줘서 BroadcastReceiver에 액션이 들어오게 하여 스캔을 진행한다.

// 자세한 방법은 http://biig.tistory.com/14 참조


끝.







펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


이 포스팅에서 다루게 될 내용 :

1. Wi-Fi 주파수 추출법

2. 주파수에 다른 채널값 추출법




위 표는 IEEE 802.11b/g/n 2.4GHz 방식과 IEEE 802.11a/n 5GHz 방식의 표준을 나타낸 표이다.


쉽게 말해 일반적으로 말하는 2.4G 대역 와이파이와 5G 대역 와이파이의 주파수와 채널에 대한 정보이다.


먼저 연결된 Wi-Fi의 주파수를 검출하는 방법에 대해 알아보자.


주파수는 WifiManager를 이용하여 와이파이 스캔을 실시하고, 이 결과를 이용하여 추출하게 되는데 방법은 아래와 같다.


WifiManager mWM = (WifiManager) context.getSystemService(WIFI_SERVICE);

WifiInfo wifiInfo = mWM.getConnectionInfo();


try {

for (ScanResult scanResult : mWM.getScanResults()) {

if (wifiInfo != null && wifiInfo.getBSSID() != null

&& wifiInfo.getBSSID().equals(scanResult.BSSID)) {


mCurrentFrequency = scanResult.frequency;

break;

}

}

} catch (Exception e) {


}


주변 Wifi를 스캔하여 현재 연결된 WifiBSSID와 일치하는 와이파이의 주파수를 추출하고 있다.


이렇게 추출된 주파수와 채널값에는 일정한 규칙이 있다.


이 규칙을 공식으로 만들어 채널값을 계산할 수 있다.


방법은 아래와 같다.


public static int convertFrequencyToChannel(int freq) {

if(freq >= 2412 && freq <= 2484) {

if (freq == 2484)

return (freq-2412) /5;

return (freq-2412) /5 + 1;

}else if( freq >= 5170 && freq <= 5825) {

return (freq-5170) /5 + 34;

}

else {

return -1;

}

}


해당 계산식을 적용하면 표에 나와있는 채널값과 동일한 값이 얻어지는것을 확인 할 수 있다.


범위 확인중인 주파수 영역을 벗어나는 새로운 주파수가 추가된다면 소스코드의 수정이 필요할 수 있다.



Android/WI-FI | Posted by 덩치 2014. 1. 8. 12:56

연결된 Wifi의 IP Address 확인

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

WifiInfo에서 검출할 수 있는 ip address는 현재 연결된 Wifi의 아이피 주소가 아니다.

(단말기의 IP Address였던가 정확히 기억은 나지 않는다. 죄송)


현재 연결된 와이파이의 아이피 주소를 검출하는 소스는 다음과 같다.


WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);

DhcpInfo dhcpInfo = wm.getDhcpInfo() ; 

int serverIp = dhcpInfo.gateway;


String ipAddress = String.format(

"%d.%d.%d.%d",

(serverIP & 0xff),

(serverIP >> 8 & 0xff),

(serverIP >> 16 & 0xff),

(serverIP >> 24 & 0xff));


이것때문에 나도 고생을 많이 했었는데 이렇게 하니 해결됐다.



Android/만들어보세요. | Posted by 덩치 2013. 12. 26. 15:03

과제 - 3. wifi 매니저

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

(이 글은 초보자를 위한 학습용 과제입니다.)

근처 wifi 목록과 보안종류, 세기를 보여주는 어플


구성은 텍스트뷰와 버튼만 있으면 됨.


1. "체크" 버튼을 누르면 wifi 검색을 시작하고, 텍스트뷰에 와이파이의 SSID(이름), RSSI(파워), NetworkId(보안종류)를 출력한다.

내용은 이게 다임.


필요한 기술은

WifiManager와 WifiInfo가 핵심.


wifi를 다루기 위한 기본적인 내용은 이 과제를 만들다보면 다 익힐 수 있다.

응용한다면 보안설정이 안돼있는 와이파이에 자동으로 연결, 또는 연결해제 해줄 수 있겠다.


궁금한점은 댓글로 문의 또는 Wifi 카테고리의 글이나 Exam 카테고리의 wifi 관련 예제를 참고하면 된다.

Android/WI-FI | Posted by 덩치 2013. 10. 23. 16:18

Wifi를 검색하여 자동으로 연결하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

wifi를 검색하는 방법에 대해서는 이전 글에서 알아보았다.


wifi에 연결하기 위해서는 보안방식과 비밀번호, ssid가 필요한데

보안방식과 ssid는 이전글의 ScanResult에서 뽑아낼 수가 있다.


비밀번호를 모르면 당연히 보안이 걸려있는 wifi에는 연결이 불가능.


일단 소스를 살펴보자


open일때

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

wfc.allowedAuthAlgorithms.clear();

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

 

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

wep일때

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

 

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

wfc.wepKeys[0] = "123456abcd";   <<--이부분중요. \"부분 빼고 그냥 비밀번호만 넣는다

wfc.wepTxKeyIndex = 0;

wpa나 wpa2일때

wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

wfc.preSharedKey = "\"".concat("123456abcd").concat("\"");


이렇게 보안방식별로 설정 방법이 다르다.

wpa와 wpa2는 설정이 같다고 하는데 필자의경우 wpa방식은 연결이 안되더라.

실제 테스트해본건 wpa2와 wep, open밖에 없다.

참고로 ScanResult.capabilites에서 뱉어주는 보안방식이 실제 open, web, wpa로 나오는건 아니고

[WPA-PSK-TKIP+CCMP][ESS]

[WPA2-PSK-CCMP][WPS][ESS]  이런식이며, 같은 방식도 length가 다른경우가 있다.

이부분은 알아서 잘 처리해주리라 믿고,



먼저 공통설정을

WifiConfiguration wfc = new WifiConfiguration(); (WifiConfiguration는 전역변수,지역변수 알아서 상황에 맞게 조절한다)

wfc = new WifiConfiguration();

wfc.SSID = "\"".concat(ssid 입력).concat("\"");

wfc.status = WifiConfiguration.Status.DISABLED;

wfc.priority = 40;

이렇게 해준다.


그리고 위의 보안방식에 따른 설정을 해 주고,


int networkId = wm.addNetwork(wfc);

if (networkId != -1) {

wm.enableNetwork(networkId, true);

}


이렇게 해주면 해당하는 wifi에 연결이 완료된다.

open형의 경우에는 level(신호세기)에 따라 정렬을 해 주고, 위의 소스를 적용시키면 가장 신호가 센놈으로

자동으로 연결될듯하다.



-끝-


Android/WI-FI | Posted by 덩치 2013. 10. 23. 16:08

Wifi 목록 검색하는법

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


전역변수로 

ScanResult scanResult;

WifiManager wm;

List apList;


WifiManager 초기화

wm = (WifiManager) getSystemService(WIFI_SERVICE);


검색

wm.startScan(); 때려주고


IntentFilter filter = new IntentFilter();

filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);

registerReceiver(wifiReceiver, filter);

이렇게 브로드캐스트리시버를 사용해줘야한다.

이유는 스캔이 끝났을 때를 체크하기 위해서이다


브로드캐스트리시버 선언

private BroadcastReceiver wifiReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {

searchWifi();

}

}

};

스캔이끝났다는 방송이 전달되면 searchWifi() 호출


searchWifi를 보면

public void searchWifi() {

apList = wm.getScanResults();

if (wm.getScanResults() != null) {

int size = apList.size();

for (int i = 0; i < size; i++) {

scanResult = (ScanResult) apList.get(i);

}

}

}


이렇게 하면 scanResult에 Wifi에 대한 정보들이 입력된다. 호출은 반복문 안에서나 원하는 위치에서

scanResult.SSID 등으로 이용할 수 있다.

Wifi가 on인지 off인지 모를때는 필터액션에 와이파이 스테이트 체인지액션까지 넣어주면 더욱좋다


-끝-