Android/WI-FI | Posted by 덩치 2015.08.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



댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 2016.09.02 16:21

    비밀댓글입니다

Android/WI-FI | Posted by 덩치 2015.05.08 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 참조


끝.







댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 minsoo 2015.07.26 15:33

    저기 질문좀 드려도되나요?

  2.  댓글주소  수정/삭제  댓글쓰기 위에 2016.01.28 10:03

    알려주신거 적용을 해봤는대 코드상에서는 오류가 안나는대 어플을 실행하면 오류나고 꺼지더라고요
    혹시 알려주신거 온크리에이트에 넣으면 되는건가요? 제가 초보자라서 자세히좀 알려주시면 안될까요?
    부탁드립니다 고맙습니다.

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

}

}


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


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



댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 컴공초보자 2015.05.05 14:12

    저 채널값이 현재 접속한 와이파이의 채널값인가요? 그렇다면 그 채널을 변경할 수 있나요? 현재 접속한 와이파이의 채널을 변경하는 건 어떻게 코드를 짜야되는지 궁금합니다.

    •  댓글주소  수정/삭제 덩치 2015.05.06 10:32 신고

      와이파이의 채널은 어플에서 변경할 수 없을것같습니다.
      장치 자체에 할당된 채널이기때문에 .. 와이파이장치를 직접 수정하지 않는 이상 채널 변경은 어려워보입니다.

    •  댓글주소  수정/삭제 덩치 2015.05.06 10:33 신고

      그리고 현재 접속하고있는 와이파이의 채널 뿐만이 아니라, 스캔된 모든 와이파이의 채널을 알 수있습니다.
      접속된 와이파이의 채널만 알고싶다면, ScanResult에서 WifiInfo.getBSSID 와 동일한 값을 가진 와이파이의 채널을 뽑으시면 됩니다.

Android/WI-FI | Posted by 덩치 2014.01.08 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));


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



댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 진우 2017.07.08 21:15

    저도 안드로이드 기기의 공인IP 를 가져오는 문제로 고민중인데
    올레와이파이에서는 공인IP를 가져오는데
    집이나 사무실 공유기에 접속된 경우 사설IP 를 가져오는것같아서 같은 고민중입니다
    위 소스도 방금 테스트 해보니 집이나 사무실 공유기에 접속된 상태에서는 사설IP를 가져오네요..
    다른 서버에 접속해서 서버에서 알려주게끔 해야하는건지..

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 > 만들어보세요.' 카테고리의 다른 글

과제 - 3. wifi 매니저  (0) 2013.12.26
과제 - 2. 스탑워치  (1) 2013.12.26
과제 - 1. 심플 타마고  (2) 2013.12.26
안드로이드 공부하고싶으신분들 만들어보세요.  (0) 2013.12.26

댓글을 달아 주세요

펌 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(신호세기)에 따라 정렬을 해 주고, 위의 소스를 적용시키면 가장 신호가 센놈으로

자동으로 연결될듯하다.



-끝-


댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 elsekid 2015.03.25 14:46

    GroupCipherdml 세팅이 굉장히 많은데 한 보안방식내에서 저 중 하나 골라서 쓰는건가요? 아니면 전부 세팅해줘야되나요?

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인지 모를때는 필터액션에 와이파이 스테이트 체인지액션까지 넣어주면 더욱좋다


-끝-

댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 학생 2016.08.24 11:30

    좋은정보 감사합니다.