2017. 3. 20
Android API 23 (Marshmallow) 이후 버전에서 Bluetooth LE 관련 코드가 동작하려면 다음 두 퍼미션중 하나를 AndroidManifest.xml파일에 추가해야 합니다. 여기서는 퍼미션과 관련된 내용만 있습니다. 나머지 내용은 본 포스팅에서 2016. 6.4일 작성된 부분을 보세요..
1 2 | android.permission.ACCESS_COARSE_LOCATION android.permission.ACCESS_FINE_LOCATION | cs |
추가 안하면 다음과 같은 에러가 납니다.
1 | java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results | cs |
AndroidManifest.xml파일에 android.permission.ACCESS_COARSE_LOCATION 퍼미션을 추가한 후..
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tistory.webnautes.bluetoothble"> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" /> | cs |
MainActivity.java에 Runtime Permission관련 코드 추가해야 합니다. 우선 다음 코드들을 추가해 준 후..
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 | static final int PERMISSION_REQUEST_CODE = 1; String[] PERMISSIONS = {"android.permission.ACCESS_COARSE_LOCATION"}; private boolean hasPermissions(String[] permissions) { int ret = 0; //스트링 배열에 있는 퍼미션들의 허가 상태 여부 확인 for (String perms : permissions){ ret = checkCallingOrSelfPermission(perms); if (!(ret == PackageManager.PERMISSION_GRANTED)){ //퍼미션 허가 안된 경우 return false; } } //모든 퍼미션이 허가된 경우 return true; } private void requestNecessaryPermissions(String[] permissions) { //마시멜로( API 23 )이상에서 런타임 퍼미션(Runtime Permission) 요청 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(permissions, PERMISSION_REQUEST_CODE); } } @Override public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){ switch(permsRequestCode){ case PERMISSION_REQUEST_CODE: if (grantResults.length > 0) { boolean Accepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Accepted ) { showDialogforPermission("앱을 실행하려면 퍼미션을 허가하셔야합니다."); return; }else { //이미 사용자에게 퍼미션 허가를 받음. } } } break; } } private void showDialogforPermission(String msg) { final AlertDialog.Builder myDialog = new AlertDialog.Builder( MainActivity.this); myDialog.setTitle("알림"); myDialog.setMessage(msg); myDialog.setCancelable(false); myDialog.setPositiveButton("예", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(PERMISSIONS, PERMISSION_REQUEST_CODE); } } }); myDialog.setNegativeButton("아니오", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { finish(); } }); myDialog.show(); } | cs |
MainActivity의 onCreate 메소드에서 블루투스 관련 코드가 시작되기 전에 넣어줘야 합니다.
1 2 3 4 5 | if (!hasPermissions(PERMISSIONS)) { //퍼미션 허가를 했었는지 여부를 확인 requestNecessaryPermissions(PERMISSIONS);//퍼미션 허가안되어 있다면 사용자에게 요청 } else { //이미 사용자에게 퍼미션 허가를 받음. } | cs |
전체 프로젝트 파일을 이곳에 올려둡니다.
2016. 6. 4
안드로이드 폰에서 Bluetooth BLE를 사용하는 Arduino 101를 검색하고 제공하는 서비스의 특정 Characteristic에 값을 기록하거나 읽어오는 것을 해봤습니다. 아래 링크에 있는 안드로이드 코드의 일부를 수정하여 사용했습니다.
https://github.com/youten/BLERW
수정한 부분은 DeviceActivity의 코드에서 아두이노 101에서 제공하는 서비스와 Characteristic를 지정해 주어 동작이 잘되도록 한 것과 일부 UI입니다.
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
71
72
73
74 |
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "value=", Toast.LENGTH_LONG);
if (v.getId() == R.id.read_state) {
BluetoothGattService disService = mConnGatt.getService(UUID.fromString("19B10000-E8F2-537E-4F6C-D104768A1214"));
if (disService == null) {
Log.d("", "Dis service not found!");
return;
}
BluetoothGattCharacteristic characteristic = disService.getCharacteristic(UUID.fromString("19B10001-E8F2-537E-4F6C-D104768A1214"));
if (characteristic == null) {
Log.d("", " charateristic not found!");
return;
}
boolean result = mConnGatt.readCharacteristic(characteristic);
if (result == false) {
Log.d("", "reading is failed!");
}
} else if (v.getId() == R.id.turn_off_led) {
BluetoothGattService disService = mConnGatt.getService(UUID.fromString("19B10000-E8F2-537E-4F6C-D104768A1214"));
if (disService == null) {
Log.d("", "Dis service not found!");
return;
}
BluetoothGattCharacteristic characteristic = disService.getCharacteristic(UUID.fromString("19B10001-E8F2-537E-4F6C-D104768A1214"));
if (characteristic == null) {
Log.d("", "firmware revison charateristic not found!");
return;
}
characteristic.setValue(new byte[] { (byte) 0x00 });
if (mConnGatt.writeCharacteristic(characteristic)) {
}
} else if (v.getId() == R.id.turn_on_led) {
BluetoothGattService disService = mConnGatt.getService(UUID.fromString("19B10000-E8F2-537E-4F6C-D104768A1214"));
if (disService == null) {
Log.d("", "Dis service not found!");
return;
}
BluetoothGattCharacteristic characteristic = disService.getCharacteristic(UUID.fromString("19B10001-E8F2-537E-4F6C-D104768A1214"));
if (characteristic == null) {
Log.d("", "charateristic not found!");
return;
}
characteristic.setValue(new byte[] { (byte) 0x01 });
if (mConnGatt.writeCharacteristic(characteristic)) {
}
}
} |
진행하기 전에 아두이노 101에 LED 예제가 업로드 되어 있어야 합니다. 메뉴에서 파일 - 예제 - CurieBLE - LED를 선택합니다.
코드 상단에 Arduino 101에서 제공하는 LED 서비스의 UUID와 LED를 제어에 사용되는 Characteristic의 UUID를 볼 수 있습니다.
1 2 3 4 5 6 7 | #include <CurieBLE.h> BLEPeripheral blePeripheral; // BLE Peripheral Device (the board you're programming) BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service // BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central BLEUnsignedCharCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); | cs |
아두이노 101이 Bluetooth LE 장치로 검색되어 질때 노출되는 문자열을 LED로 지정하고 있습니다.
1 2 3 | // set advertised local name and service UUID: blePeripheral.setLocalName("LED"); blePeripheral.setAdvertisedServiceUuid(ledService.uuid()); | cs |
안드로이드 앱을 실행시킨 후.. SCAN 버튼을 눌러주면 BLE장치의 이름, 맥어드레스 그리고 RSSI값을 출력해줍니다. 이때 STOP 버튼을 눌러주면 스캔이 중단됩니다. 첫번째 줄에 있는 LED 장치가 아두이노 101입니다. 선택해주면..
다른 화면이 보이는데 이때 READ_STATE버튼을 클릭하면 현재 LED의 상태값을 읽어와 화면에 출력해줍니다.
TURN ON LED버튼을 클릭하면 아두이노 101에 연결된 LED가 켜지고 이때 다시 READ_STATE 버튼을 클릭해보면 1로 값이 변경된 것을 확인할 수 있습니다.
다시 TURN OFF LED를 클릭하여 LED를 끄고 다시 READ_STATE버튼을 클릭해보면 상태값이 0으로 변한 것을 확인 할 수 있습니다ㅏ.
'Arduino 101' 카테고리의 다른 글
Arduino 101의 Bluetooth Low Energy(BLE) 예제를 안드로이드 폰과 테스트 (6) | 2017.08.02 |
---|---|
Windows에서 Genuino 101 ( Arduino 101) 보드 처음 사용해보기 (0) | 2017.08.02 |
Raspberry Pi 3와 Arduino 101간에 BLE 제어 및 정보 가져오기 ( python 라이브러리 사용 ) (27) | 2016.12.06 |
Arduino 101 CurieTime 예제 ( 시간 설정 및 불러오는 예제 ) (0) | 2016.06.10 |
Android에서 Bluetooth LE( BLE) 장치 연결시 16진수로 4바이트( 16-bit UUID )인 경우 처리 (0) | 2016.06.05 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!