안드로이드 4.3 블루투스 저에너지 불안정


189

현재 블루투스 저에너지를 사용하는 애플리케이션을 개발 중입니다 (Nexus 4에서 테스트). Android 4.3에서 공식 BLE API를 시작한 후 처음으로 장치를 연결 한 후에는 해당 장치 또는 다른 장치에 다시 성공적으로 연결 / 통신 할 수없는 것으로 나타났습니다.

여기에 있는 안내서에 따라 문제없이 장치에 성공적으로 연결하고 서비스 및 특성을 검색하며 알림을 읽고 쓸 수 있습니다. 그러나 연결을 끊고 다시 연결 한 후 서비스 / 특성을 스캔하거나 읽기 / 쓰기를 완료 할 수없는 경우가 종종 있습니다. 왜 이런 일이 발생했는지 나타내는 로그에서 아무것도 찾을 수 없습니다.

이 문제가 발생하면 응용 프로그램을 제거하고 Bluetooth를 비활성화 한 다음 전화를 다시 시작해야 작동합니다.

장치가 연결 해제 될 때마다 BluetoothGatt 객체에서 close ()를 호출하고 null로 설정해야합니다. 통찰력이 있습니까?


편집 :
로그 덤프 :이 로그의 경우 휴대 전화를 근절하고 /etc/bluetooth/bt_stack.conf에서 관련 항목의 추적 수준을 올렸습니다.

연결 성공 -전화를 재부팅하고 앱을 설치 한 후 먼저 시도하십시오. 연결하고 모든 서비스 / 특성을 발견하고 읽고 쓸 수 있습니다.

실패한 시도 1- 위의 성공적인 연결에서 연결을 끊은 다음 시도입니다. 특성을 발견 할 수 있었지만 첫 번째 시도는 null 값을 반환하고 곧 연결이 끊어졌습니다.

Failed Attempt 2- 서비스 / 특성을 발견 할 수없는 예입니다.


편집 2 :
연결하려는 장치는 TI의 CC2541 칩을 기반으로합니다. 나는 함께 놀 수있는 TI SensorTag (CC2541 기반)를 얻었고 TI가 어제 SensorTag 용 Android 앱 을 출시했음을 발견했습니다 . 그러나이 앱은 같은 문제가 있습니다. 동일한 결과로 두 개의 다른 Nexus 4에서 이것을 테스트했습니다. SensorTag에 대한 연결이 처음 또는 두 번 성공했지만 (로그에 따라) 이후에 서비스를 검색하지 못해 모든 종류의 충돌이 발생합니다. 이 특정 칩에 문제가 있는지 궁금해지기 시작했습니다.


문제가 발생할 때까지 부팅시 휴대 전화의 전체 로그를 게시하십시오.
AAnkit

3
유출 된 Google 에디션 Android 4.3이 설치된 Samsung Galaxy S4를 사용하고 있습니다. 여러 번 연결 / 연결 해제 후 서비스를 발견하면 임의로 129 (GATT_INTERNAL_ERROR)가 발생하고 상태가 133 (GATT_ERROR), state = BluetoothProfile.DEVICE_DISCONNECTED 인 onConnectionStateChange가 발생합니다.
reTs

1
한두 번 동안 짧은 시간에 여러 상태 129 및 133 콜백이 발생했으며 장치를 재부팅 할 때까지 BluetoothGattCallback에서 콜백을 수신 할 수 없었습니다 (그러나 스캔은 괜찮습니다).
reTs

1
TI 칩을 사용하여 약 10 개의 장치 (모델을 모르는 것이 유감입니다)와 노르딕 칩이있는 하나의 장치로 테스트하고 있다고 말하지 마십시오. 북유럽 칩이 장치는 오류를보고하지 (충분하지 않습니다 문제를 증명하기 TI의 특정는하지만).
RETS

1
이 문제가 여전히 Samsung Galaxy S5 ( G900VVRU2BOG5G900VVRU2BOA8 빌드 버전)에 존재 함을 확인할 수 있습니다 . Settings> Application Manager >> All >> Bluetooth 에서 데이터를 지우면 한동안 작동합니다.
IronBlossom

답변:


184

중요한 구현 힌트

(아마도 이러한 힌트 중 일부는 Android OS 업데이트로 인해 더 이상 필요하지 않습니다.)

  1. Android 4.3 이 설치된 Nexus 4와 같은 일부 기기 는 기존 gatt 인스턴스를 사용하여 연결하는 데 45 초 이상 걸립니다 . 해결 방법 : 연결을 끊을 때 항상 gatt 인스턴스를 닫고 각 연결마다 새로운 gatt 인스턴스를 만드십시오.
  2. 전화하는 것을 잊지 마세요 android.bluetooth.BluetoothGatt#close()
  3. 내부에서 새 스레드 onLeScan(..) 를 시작한 다음 연결하십시오. 이유 : Android 4.3이 설치된 Samsung Galaxy S3의 동일한 스레드에서 BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)호출되면 항상 실패합니다 LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)(최소한 빌드 JSS15J.I9300XXUGMK6).
  4. 대부분의 장치는 광고를 필터링합니다
  5. android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) 특정 서비스 UUID를 필터링하기 위해 매개 변수와 함께 사용하지 않는 것이 좋습니다. Android 4.3이 설치된 Samsung Galaxy S3에서 완전히 손상 되어 일반적으로 128 비트 UUID 에서 작동하지 않기 때문 입니다.
  6. Gatt는 항상 한 번에 하나의 명령을 처리 할 수 ​​있습니다 . 여러 명령이 차례로 호출되면 첫 번째 명령 은 gatt 구현의 동기 특성으로 인해 취소 됩니다.
  7. Android 5가 장착 된 최신 기기에서도 Wi-Fi가 블루투스를 방해하고 그 반대의 경우도 종종 있습니다. 최후의 수단으로, 와이파이를 끄고 블루투스를 안정화하십시오.

초보자를위한 튜토리얼

초보자를위한 OK 진입 점은이 비디오 자습서 일 수 있습니다. Android 용 Bluetooth Smart 응용 프로그램 개발 http://youtu.be/x1y4tEHDwk0

아래에 설명 된 문제와 해결 방법은 아마도 OS 업데이트로 해결되었을 것입니다.

해결 방법 : 내 앱을 "안정화"할 수 있습니다 ...

  1. 사용자에게 "블루투스 다시 시작"설정을 제공합니다. 해당 설정이 활성화되어 있으면 BLE 스택의 시작이 불안정 해지는 일부 지점에서 Bluetooth를 다시 시작합니다. 예를 들어 startScan이 false를 반환하는 경우 serviceDiscovery가 실패하는 경우에도 좋은 포인트입니다. 방금 Bluetooth를 껐다 켜십시오.
  2. 다른 설정 인 "WiFi 끄기"를 제공합니다. 해당 설정을 사용하면 앱이 실행될 때 내 앱에서 Wi-Fi가 꺼지고 나중에 다시 켜집니다.

이 해결 방법은 다음과 같은 경험을 바탕으로합니다.

  • Bluetooth를 다시 시작하면 대부분의 경우 BLE 문제를 해결하는 데 도움이됩니다.
  • Wi-Fi를 끄면 BLE 스택이 훨씬 안정적입니다. 그러나 Wi-Fi가 켜져있는 대부분의 기기에서도 제대로 작동합니다.
  • Wifi를 끄면 Bluetooth를 다시 시작하면 대부분의 경우 장치를 재부팅하지 않고도 BLE 스택이 완전히 복구됩니다.

33
구글, 이제이 문제를 해결해야합니다. 이 해결 방법 (작동하기 때문에 더하기)은 어리 석습니다.
Chris Herbert

4
때로는 서비스 발견이 상태 0으로 성공하지만 (문제가 없다고 가정) 특성 읽기는 실제로 실제로 연결되지 않았거나 특성이 발견되지 않았기 때문에 NULL 값을 생성합니다 (로그에서이를 참조하십시오 : 11-01 18:37 : 32.131 : 경고 / BluetoothGatt를 (20119) 처리되지 않은 예외 : java.lang.NullPointerException이)
낮음 탄

2
@ Lo-Tan 예상되는 서비스가 포함되어 있으면 항상 서비스 검색 후 확인합니다. 서비스 검색 결과가 나오면 확신 할 수 없습니다. 때로는 콜백이 수신되지 않습니다. 그래서 서비스 검색에 시간 초과를 적용했습니다.
OneWorld

2
내 경험은 다음과 같습니다. 위의 단락 2에 설명 된대로 Gatt 클라이언트를 닫은 후 Samsung S3 (4.3)이 다시 연결되었습니다. Nexus 4 & 7 (4.4.2)을 사용하는 경우 BL 어댑터를 다시
시작해

1
사람의 확인은 android.bluetooth.BluetoothGatt은 하나의 출원 GATT 조작 처리 할 수있는 경우 PER 장치 , PER 과정 , 또는 기간 (: 모든 프로세스에 걸쳐 즉). 나는 그것이 장치 당이라고 가정하지만,이 문제는 너무 어려워서 그렇지 않으면 나를 놀라게하지 않을 것입니다. 제한이 PER PERVICE 인 경우 여러 동시 작업을 처리 할 수있는 OS / 장치는이 문제가 순전히 BluetoothAdapter 인스턴스의 일부 순진한 구현으로 인해 OS가 각 프로세스를 처리한다고 가정합니다. 모든 프로세스에서 싱글 톤).
swooby

18

WIFI 끄기 :

WIFI를 사용 중지하면 특히 Google Nexus (Nexus 7이 있음)에서 Bluetooth 4.0이 더 안정적임을 확인할 수 있습니다.

문제

개발중인 응용 프로그램 에는 WIFI 와 지속적인 Bluetooth LE 스캐닝이 모두 필요 합니다 . 따라서 WIFI를 끄는 것은 나에게 옵션이 아닙니다.

또한 나는 지속적인 블루투스 LE 스캔 이 실제로 WIFI 연결을 끊을 수 있으며 BLE 스캔이 ON 될 때까지 WIFI 어댑터가 WIFI 네트워크 에 다시 연결할 수 없다는 것을 깨달았습니다 . (모바일 네트워크와 모바일 인터넷에 대해 잘 모르겠습니다).
이것은 분명히 다음 장치에서 발생했습니다.

  • 넥서스 7
  • 모토로라 모토 G

그러나 WIFI를 사용하는 BLE 스캔은 다음과 같이 안정적으로 보입니다.

  • 삼성 S4
  • HTC 하나

내 해결 방법

나는 에 대한 상상력 스캔 시간의 짧은 기간 3-4초은 그때 3-4초에 대한 스캔을 끕니다 . 그런 다음 다시 ON하십시오.

  • 분명히 BLE 장치에 연결할 때 항상 BLE 스캔을 끕니다.
  • 장치에서 분리하면 스캔을 다시 시작하기 전에 BLE를 다시 시작하여 (어댑터를 껐다가 다시 켜서) 스택을 재설정하십시오.
  • 또한 발견 services하거나 characteristics실패 할 때 BLE를 재설정 합니다.
  • 앱이 연결 해야하는 장치에서 광고 데이터를 얻으면 (연결 할 수없는 상태에서 500 번-5 ~ 10 초 광고) BLE를 다시 재설정합니다.

장치 연결이 끊긴 후 BLE를 다시 시작했다고 말했습니다. 사용자가 블루투스 연결을 통해 파일을 전송하는 경우를 가정 해 봅시다. 그러면 언제라도 해당 Bluetooth 전송이 실패하게됩니다.
Rahul Rastogi 2019

1
"어댑터를 껐다 켜십시오"는 무슨 뜻입니까?
Marian Paździoch

Wi-Fi와 Bluetooth가 함께 Moto G에서 앱 성능을 저하시키고 있음에 동의합니다.
Nigilan

@ MarianPaździoch, "어댑터를 껐다 켜십시오"@ benka는 BluetoothAdapter를 의미합니다
Anup

9

Nexus가 기기와 페어링되어 있는지 확인하세요. 통신이 제대로 작동하는지 확인할 수 없지만 재부팅하지 않고 두 번 이상 연결할 수 있습니다. 첫 번째 연결에는 페어링이 필요하지 않지만 모든 후속 시도는 필요합니다.

서비스 검색을 테스트하고 재부팅없이 gatt 읽기 및 쓰기 요청을 테스트하면 며칠 안에이 답변을 업데이트 할 것입니다.

편집 : 페어링되지 않은 경우 문제를 일으키는 개발 펌웨어 버전 (센서)을 테스트하고있는 것으로 나타났습니다. 최신 프로덕션 펌웨어 빌드는 2540 및 2541에서 잘 작동합니다.

편집 : Nexus 7 2013에서 WiFi가 꺼져있을 때 연결이 더 안정적임을 알았습니다. 이것이 다른 사람에게 도움이되는지 알고 싶습니다.

편집 : 페어링을 거꾸로 한 것 같습니다. 페어링되지 않으면 모든 것이 잘 작동합니다. 페어링 후 OP와 동일한 증상이 나타납니다. 이것이 펌웨어 또는 Android BLE API와 관련이 있는지 여부는 아직 알려지지 않았습니다. 한 번 페어링되면이 게시물의 3b에 설명 된 버그로 인해 페어링을 해제하지 못할 수 있으므로 테스트 할 때주의하십시오 .


수동 페어링이나 재부팅없이 CC2541 장치에 지속적으로 연결하고 다시 연결하고 있습니다.
dgel

내 의견으로는 페어링이 필요하지 않습니다. 공식 문서는 페어링에 대해서도 언급하지 않습니다. 또한 페어링, 쓰기, 읽기, 특성 변경 알림을 수행 할 수 있습니다. 그러나 짧은 시간 동안 만. 이제 또 다시 흔들리고 ... SAMSUNG BLE SKD v2.0도 페어링이 필요하지 않았으며 꽤 잘 작동했습니다.
OneWorld

3
Wi-Fi를 끈 후 더 안정적 임을 확인할 수 있습니다 . 모두 시도해야합니다.
OneWorld

1
페어링이 필요한지 여부는 장치 구현에 따라 다릅니다. nrf8002 장치는 페어링이 필요하며 Samsung 2.0 및 1.2 API는 모두이를 지원합니다. ble 장치를 페어링 한 후 공식 api 지원이 페어링 측면에서 문제가있는 것처럼 보입니다. 페어링을 해제하는 것은 불가능합니다!
Chris Herbert

2
페어링을 해제 할 수없는 문제가 해결되었습니다. 1) bt 메뉴로 이동하여 페어링 해제를 선택하고 영역에서 ble 장치를 제거하거나 전원을 끈 다음 bt 메뉴에서 ble 장치를 선택하면 페어링 및 실패를 시도한 다음 블루투스를 재설정합니다. 재설정하면 장치가 페어링 해제됩니다.
Chris Herbert

7

일부 모델에는 결함이 있습니다 : https://code.google.com/p/android/issues/detail?id=180440

반면에 내 문제는 onDestroy 메소드에서 연결이 제대로 닫히지 않았다는 것입니다. 올바른 폐쇄 후 나에게 문제가 존재하지 않습니다 .WiFi가 켜져 있거나 꺼져 있는지 상관 없습니다.

btGatt.disconnect();
btGatt.close();

close필요한가요?
IgorGanapolsky

3
블루투스를 여러 번 연결하려면 올바른 닫기 절차가 중요합니다. 내 경험상 별도의 UNBOUND 서비스에서 Ble 연결을 실행하면 수동으로 시작하고 중지 할 수 있습니다. 그리고 당신은 mConnectedGatt.disconnect (); ble_device = null; inDestroy ()에서. 필자의 경우이 패턴은 문제없이 안정적으로 작동합니다.
medTech

4

나는 비슷한 문제에 직면했다. 내 수정은

if (Build.VERSION.SDK_INT >= 23) {
  mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
} else {
  mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}

& 연결 해제 후 닫기를 호출합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.