티스토리 뷰


Wifi Scanning 

 

 이번 시간에는 Android 에서 Wifi Scanning을 하여 결과를 Dialog 에 띄워주는 방법에 대해서 알아보겠습니다. 일단 Wifi를 Scanning하는 방법은 Wifi Manager Class 를 이용하는 방법이 있습니다.Wifi Manager는 주변의 Wifi 신호를 검색하여 결과를 보여주거나 연결을 하는 기능을 지원합니다.


 원리는 간단합니다. 우선 BroadcastReceiver가 필요합니다. 앱을 실행했을 때 주기적으로 Wifi 신호를 받아 오는 데 그때 마다 onReceive 콜백 메소드가 호출되어 동작을 수행합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
private BroadcastReceiver mWifiScanReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if(action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
                getWIFIScanResult();
                wifiManager.startScan();
            }else if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
                mContext.sendBroadcast(new Intent("wifi.ON_NETWORK_STATE_CHANGED"));
            }
        }
    };
cs


 이제 Scan을 시작하기 전에 initialize 작업이 필요합니다. 그래서 initWifiScan() 이라는 메소드를 만들겠습니다.



1
2
3
4
5
6
7
8
    public void initWIFIScan(){
        wifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
        scanCount = 0;
        final IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mContext.registerReceiver(mWifiScanReceiver, filter);
        wifiManager.startScan();
    }
cs


 위 메소드에서 Scan을 하기 위해서 getSystemService() 메소드로 Wifimanager 객체를 시스템으로부터 얻고 기본 작업을 진행합니다.


 이제 실제 Wifi 검색 결과를 나타내주는 메소드는 아래와 같습니다.


 

1
2
3
4
5
6
7
8
9
    public void getWIFIScanResult(){
        scanResult = wifiManager.getScanResults();
        test_tv.setText("");
        for (int i = 0; i < scanResult.size(); i++) {
            ScanResult result = scanResult.get(i);
            test_tv.append((i + 1+ ". SSID : " + result.SSID.toString()
                    + "\t\t RSSI : " + result.level + " dBm\n");
        }
    }
cs


 

Android 6.0

 그런데 구현을 하다 보니 Wifi 결과 값이 전혀 넘어오지 못하는 현상이 발생했습니다. 원인을 살펴보니 Android Marshmallow 이상 부터는 ACCESS_COARSE_LOCATION 퍼미션이 필요하다는 것을 알게 되었습니다. 이 곳 에서 자세한 원인을 살펴 볼수 있습니다. 그래서 필요한 퍼미션들은 다음과 같습니다.



1
2
3
4
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
cs


 권한 요청을 하는 부분은 TED Library를 이용했습니다. 자세한 사용법은 이 곳 참고 하시면 됩니다.



Dialog 구현

 일단 WIFI 목록들을 보여줄 Dialog 의 XML 은 아래와 같습니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
 
            <RelativeLayout
                android:id="@+id/layout_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="16dp"
                android:background="@color/colorPrimary">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="28sp"
                    android:text="WIFI 목록"/>
 
            </RelativeLayout>
 
        <LinearLayout
                    android:id="@+id/layout_content"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:padding="16dp">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/test_tv" />
        </LinearLayout>
    </LinearLayout>
</ScrollView>
 
 
cs

 

 이제 이 Dialog를 제어할 Fragment를 만들겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class SpeakerScanDialogFragment extends DialogFragment {
 
    private static final String TAG = "SpeakerScanDialogFragment";
 
    private Context mContext;
    private ImageButton refreshBtn;
    private WifiManager wifiManager;
    private ConnectivityManager connManager;
    private List<ScanResult> scanResult;
    private SimpleAdapter adapter;
    private ArrayList<HashMap<String,String>> list;
    private int scanCount = 0;
    String result = "";
    StringBuilder sb = new StringBuilder();
    TextView test_tv;
    public static SpeakerScanDialogFragment newInstance(){
 
        SpeakerScanDialogFragment fragment = new SpeakerScanDialogFragment();
 
        return fragment;
    }
 
 
    private BroadcastReceiver mWifiScanReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if(action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
                getWIFIScanResult();
                wifiManager.startScan();
            }else if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
                mContext.sendBroadcast(new Intent("wifi.ON_NETWORK_STATE_CHANGED"));
            }
        }
    };
 
 
    public void getWIFIScanResult(){
        scanResult = wifiManager.getScanResults();
        test_tv.setText("");
        for (int i = 0; i < scanResult.size(); i++) {
            ScanResult result = scanResult.get(i);
            test_tv.append((i + 1+ ". SSID : " + result.SSID.toString()
                    + "\t\t RSSI : " + result.level + " dBm\n");
        }
    }
 
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v  = inflater.inflate(R.layout.dialog_speakerscan, container, false);
        mContext = v.getContext();
        initWIFIScan();
        test_tv = (TextView)v.findViewById(R.id.test_tv);
        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        LinearLayout scanList = (LinearLayout)v.findViewById(R.id.layout_content);
 
        return v;
    }
    public void initWIFIScan(){
        wifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
        scanCount = 0;
        final IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mContext.registerReceiver(mWifiScanReceiver, filter);
        wifiManager.startScan();
    }
}
 
 
cs




 

결과 값
 
 그래서 구현된 모습은 다음과 같습니다. 혹시 잘못된점이나 이상한 점이 있으면 말씀해 주시면 감사하겠습니다 : )




참고 자료: http://saoa.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9CAndroid-WiFi-%EC%8A%A4%EC%BA%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8

반응형
댓글