android Ble가 개발한 것들 (3) - Ble 데이터 패키지 처리
프로젝트 실제 문제
우선, 내 프로젝트에서 겪은 실제 문제를 이야기해 봅시다.우리ble설비는 notify를 켜면 자동으로 데이터를 휴대전화에 보냅니다. 이 데이터의 길이는 길고 짧으며 서로 다른 의미를 의미합니다(예를 들어 배터리 전량, 채취한 데이터...).하드웨어의 디자인은 위챗 쪽과 관련된 디자인을 참고했다. ble가 전송하는 데이터의 길이가 제한되어 있기 때문에 ble의 데이터 발송을 네트워크와 유사한 하도급 과정으로 설계했다. 완전한 데이터를 보낼 때 ble설비는 먼저 데이터의 길이, 유형 등 정보를 데이터 헤더에 두었다.그리고 나머지 상세한 데이터 내용까지 최대 길이로 나누어 하나씩 방송해 보낸다.
앱이 해야 할 일은 이 데이터를 모두 받아서 하도급으로 해석하면 된다.그럼 어떻게 나눠요?
해결책
1. BluetoothBuffer 도구 클래스
처음에 저는 Byte Buffer로 실현하려고 했지만 프로젝트에서 사용하기에 특별히 편리하지 않다고 느꼈고 나중에 비슷한 도구류를 썼습니다. (이 도구류의 일부 방법은 시스템api에서 대체할 방법이 있을 것입니다. 자신이 쓰기에 비교적 편리하다고 느꼈기 때문에 시스템api를 사용하지 않았습니다. 여러분도 시스템과 관련된api로 대체할 수 있습니다.)
이 도구 종류는 주로 다음과 같은 몇 가지 방법이 있다. (1) append 버퍼(byte[] 버퍼) 추가 버퍼
public void appendBuffer(byte[] buffer) {
if (null == buffer || 0 == buffer.length) return;
int size = buffer.length + this._rawBufferSize;
if (size <= this._rawBuffer.length) {
System.arraycopy(buffer, 0, this._rawBuffer, this._rawBufferSize, buffer.length);
this._rawBufferSize += buffer.length;
} else {
int newSize = this._rawBuffer.length;
while (newSize <= size) {
newSize *= 1.5;
}
byte[] newRawBuffer = new byte[newSize];
System.arraycopy(this._rawBuffer, 0, newRawBuffer, 0, this._rawBufferSize);
this._rawBuffer = newRawBuffer;
System.arraycopy(buffer, 0, this._rawBuffer, this._rawBufferSize, buffer.length);
this._rawBufferSize += buffer.length;
}
}
(2) getFrontBuffer (int size) 이전 크기 버퍼
public byte[] getFrontBuffer(int size) {
if (0 >= size || size > this._rawBufferSize) return null;
byte[] buffer = new byte[size];
System.arraycopy(this._rawBuffer, 0, buffer, 0, size);
return buffer;
}
(3) releaseFrontBuffer (int size) 앞 크기 버퍼 방출
public void releaseFrontBuffer(int size) {
if (0 >= size || size > this._rawBufferSize) return;
System.arraycopy(this._rawBuffer, size, this._rawBuffer, 0, this._rawBufferSize - size);
this._rawBufferSize -= size;
}
2. 데이터 수신 및 하도급
(1) 수신 데이터의 수신은LiteBle Gatt Callback의 onCharacteristic Changed 리셋 함수에서 수신되기 때문에 하도급 처리도 이 리셋 함수에서 해야 한다.
private void connect(final BluetoothDevice device){
liteBluetooth.connect(device, false, new LiteBleGattCallback() {
......
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
// notify , 。
//
btBuffer.appendBuffer(characteristic.getValue());
while (true){
boolean ret = subPackageOnce(btBuffer);
if (false == ret) break;
}
super.onCharacteristicChanged(gatt, characteristic);
}
});
}
보시다시피 먼저 메시지를 받으면 저는 append에 올라가서subPackageOnce () 하도급 함수를 순환해서 하도급이false로 돌아가지 못할 때까지 이 순환을 끝내면 효율도 훨씬 빨라집니다.
(2) 데이터 하도급 데이터 하도급, 즉 데이터를 하나하나 떼어내는 것이다. 하도급을 하려면 데이터의 길이가 도대체 얼마인지 알고 길이가 얼마인 데이터를 떼어내면 된다.그래서 첫 번째 단계는 먼저 데이터 헤더를 얻은 다음에 가방 길이의 pkgSize를 얻은 다음에 pkgSize에 따라 데이터를 벗겨내고 끊임없이 순환하는 것이다...
private boolean subPackageOnce(BluetoothBuffer buffer) {
if (null == buffer) return false;
if (buffer.getBufferSize() >= 14) {
byte[] rawBuffer = buffer.getBuffer();
//
if (isHead(rawBuffer)){
pkgSize = byteToInt(rawBuffer[2], rawBuffer[3]);
}else {
pkgSize = -1;
for (int i = 0; i < rawBuffer.length-1; ++i){
if (rawBuffer[i] == -2 && rawBuffer[i+1] == 1){
buffer.releaseFrontBuffer(i);
return true;
}
}
return false;
}
//
if (pkgSize > 0 && pkgSize <= buffer.getBufferSize()) {
byte[] bufferData = buffer.getFrontBuffer(pkgSize);
long time = System.currentTimeMillis();
buffer.releaseFrontBuffer(pkgSize);
//
deal something。。。。。
return true;
}
}
return false;
}
이를 통해 알 수 있듯이 데이터 패키지의 길이를 얻고 데이터를 성공적으로 박리한 후에 데이터 분류의 표지 위치에 따라 서로 다른 데이터 처리 방법을 취할 수 있다.예를 들어 채집한 데이터에 대해 나는 이 데이터와 시간 스탬프를 서버에 올릴 것이다.관련 설정 정보를 앱에 선택적으로 표시합니다.
자, ble와 관련된 데이터 하도급 처리는 끝났습니다. 간단하지 않습니까? 이것은 단지 제 처리 방식일 뿐입니다. 만약에 더 좋은 생각이 있거나 잘못된 점이 있으면 지적을 환영하고 서로 교류하고 공부합니다.다음 편에서는 Ble 펌웨어 공중 업그레이드 이야기를 시작하겠습니다. 빨리 더욱.
오리지널 작품은 전재할 필요가 있으면 작가에게 연락하십시오. 그렇지 않으면 법적 책임을 추궁할 것입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.