ANCS本質(zhì)上就是BLE的使用:
協(xié)議網(wǎng)絡(luò)上介紹很清楚,暫且不說了,最最重要的就是解析數(shù)據(jù):
關(guān)鍵代碼:
/**
*連接gatt server結(jié)果處理回調(diào)類
*/
private classLocalBluetoothGattCallbackextendsBluetoothGattCallback {
@Override
public voidonConnectionStateChange(BluetoothGatt gatt, intstatus, intnewState) {
Log.v(TAG," BluetoothGatt status: "+ status);
if(newState == BluetoothProfile.STATE_CONNECTED) {
isConnected=true;
Log.v(TAG,"ancs connected");
mStateIntent.putExtra("state",Constants.CONNECT_SUCCESS);
sendBroadcast(mStateIntent);
mConnectedGatt= gatt;
gatt.discoverServices();
mBluetoothLeScanner=mBluetoothAdapter.getBluetoothLeScanner();
mBluetoothLeScanner.stopScan(mScanCallback);
}
if(newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.d(TAG,"ancs disconnected");
isConnected=false;
mConnectedGatt.disconnect();
mConnectedGatt.close();
mStateIntent.putExtra("state",Constants.DISCONNECTED);
sendBroadcast(mStateIntent);
mBinder.connectToGattServer();
}
}
@Override
public voidonServicesDiscovered(BluetoothGatt gatt, intstatus) {
Log.v(TAG," BluetoothGatt status: "+ status);
SystemClock.sleep(1000);
BluetoothGattService ancsService = gatt.getService(
UUID.fromString(service_ancs));
if(ancsService ==null) {
Log.d(TAG,"ANCS cannot find");
}else{
Log.d(TAG,"ANCS find");
mDataSourceChar= ancsService.getCharacteristic(
UUID.fromString(Constants.characteristics_data_source));
mPointControlChar= ancsService.getCharacteristic(
UUID.fromString(characteristics_control_point));
mNotificationSourceChar= ancsService.getCharacteristic(
UUID.fromString(Constants.characteristics_notification_source));
setNotificationEnabled(mDataSourceChar);
}
}
@Override
public voidonDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor descriptor,
intstatus) {
Log.v(TAG," BluetoothGatt status: "+ status);
// Notification source
if(descriptor.getCharacteristic()
.getUuid()
.equals(UUID.fromString(Constants.characteristics_data_source))) {
setNotificationEnabled(mNotificationSourceChar);
Log.d(TAG,"ancs data_source訂閱成功");
}
if(descriptor.getCharacteristic()
.getUuid()
.equals(UUID.fromString(
Constants.characteristics_notification_source))) {
Log.d(TAG,"ancs notification_source訂閱成功");
}
}
@Override
public voidonCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, intstatus) {
}
@Override
public voidonCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, intstatus) {
Log.v(TAG," BluetoothGatt status: "+ status);
Log.v(TAG,"onCharacteristicWrite");
if(characteristics_control_point.equals(characteristic.getUuid()
.toString())) {
Log.d(TAG,"control_point? Write successful");
}
}
@Override
public voidonDescriptorRead(BluetoothGatt gatt,BluetoothGattDescriptor descriptor,
intstatus) {
Log.d(TAG,"onDescriptorRead");
}
@Override
public voidonCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
if(Constants.characteristics_notification_source.equals(characteristic.getUuid()
.toString())) {
mCommonProcessor.init();
mAppNameProcessor.init();
Log.d(TAG,"notification_source Changed");
byte[] nsData = characteristic.getValue();
notification=newNotification(nsData);
Log.w(TAG,"nsData[0] = "+ nsData[0]);
Log.w(TAG,"nsData[0] & 0x02 = "+ (nsData[0] &0x02));
if((nsData[0] &0x02) >0) {
Log.v(TAG," > 0: "+notification.toString());
}else{
Log.v(TAG," <= 0: getMoreAboutNotification");
getMoreAboutNotification(nsData);
}
}
if(Constants.characteristics_data_source.equals(characteristic.getUuid()
.toString())) {
Log.i(TAG,"onCharacteristicChanged: "+ characteristic.getValue().length);
handleCharaData(characteristic.getValue());
}
}
}
private voidhandleCharaData(byte[] charaData) {
Log.v(TAG,"characteristics_data_source changed");
if(charaData ==null|| charaData.length==0) {
return;
}
// parse appId appTitle appMessage
if(bytes==null) {
Log.d(TAG,"bytes == null");
mCommonProcessor.processing(charaData);
if(mCommonProcessor.is_finish_processing()) {
notification.setPackageName(mCommonProcessor.get_ds_app_id());
notification.setTitle(mCommonProcessor.get_ds_title());
notification.setMessage(mCommonProcessor.get_ds_message());
Log.d(TAG,notification.toString());
mCommonProcessor=newCommonProcessor();
charaData =null;
if(notification.getPackageName() ==null||notification.getTitle() ==null||
notification.getMessage() ==null) {
mConnectedGatt.disconnect();
return;
}
getAppAttributes(notification.getPackageName());
}
}
// parse appName
if(bytes!=null&& charaData !=null) {
Log.d(TAG,"bytes != null");
mAppNameProcessor.setPackageLength(bytes.length);
mAppNameProcessor.processing(charaData);
if(mAppNameProcessor.is_finish_processing()) {
bytes=null;
notification.setAppName(mAppNameProcessor.get_ds_app_name());
Log.d(TAG,notification.toString());
mAppNameProcessor=newAppNameProcessor();
if(mOnReceiveNotificationListener!=null&?ification.getAppName() !=null
&?ification.getPackageName() !=null) {
mOnReceiveNotificationListener.OnReceiveNotification(notification);
}else{
mConnectedGatt.disconnect();
isConnected=false;
}
}
}
}
為了保證盡量收到數(shù)據(jù)并且能解析成功,那么只要數(shù)據(jù)解析異常就斷開ble重新訂閱ANCS;
如果哪位大神有好的辦法可以給指正一下O(∩_∩)O哈!