国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Android 4.0低功耗藍牙開發!

justCoding / 1857人閱讀

摘要:連接回調連接成功連接斷開改變當前狀態當服務發現之后回調這里四發現服務一個低功耗藍牙設備是有很多種服務的,就比如該設備的電量信息,設備的當前狀態比如血壓計是正在測量還是在等待測量有的設備支持歷史數據等等。

????公司開發任務是,將醫療設備通過藍牙集成到app中,在這開發中遇到了數不盡的坑.在此記錄一下做一個記錄,如果其他開發人員看見或許能提供一些幫助,如有不對,盡情指正,不勝感激!

??剛開始接觸的時候,被各種超長的API嚇到了,像:BluetoothGatt , BluetoothGattCharacteristic , BluetoothGattDescriptor 等等.而且還要做多連接,上位機一對多下位機.網上例子也是雜七雜八.看的頭暈.后來在老大的幫助下,漸漸明白許多,在此感謝老大.廢話到此結束,下面進入正題.

一、檢測本機是否支持藍牙

1. 判斷當前設備是否支持藍牙

BluetoothManager mBluetoothManager = (BluetoothManager) activity.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter adapter = mBluetoothManager.getAdapter();
if(adapter==null){    
   //系統不支持藍牙。
} 

2. 判斷當前設備是否支持低功耗藍牙BLE

boolean isSupportBle = activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);

3. 判斷藍牙是否開啟,開啟藍牙!

BluetoothManager mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter adapter = mBluetoothManager.getAdapter();

if(!adapter.isEnable){  //未開啟藍牙
    //申請開啟藍牙
    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(intent , request);
}
二、開始掃描周圍的藍牙設備
BluetoothAdapter adapter = mBluetoothManager.getAdapter();
adapter.startLeScan(callback); //掃描需要一個回調。

注意,掃描周圍藍牙是一個很耗電的過程,最好加上一個掃描時間。自動停止。

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
         adapter.stopLeScan(callback); //停止掃描
    }
},10000);//設置10秒鐘結束掃描
public BluetoothAdapter.LeScanCallback scanCallBack = new BluetoothAdapter.LeScanCallback() {
     @Override
     public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
           //這里注意,本人在開發中遇到的是 經常有的藍牙設備是沒有名字的, (device.getName == null)
           //不知道這是什么原因引起的,后來跟很多藍牙高手討論的是結果初步懷疑應該是芯片的問題
           //尤其是MTK的芯片經常出現這種問題,換了搭載高通和華為的芯片的設備就沒問題了。
           
     }
};
三、連接藍牙設備
BluetoothDevice remoteDevice = adapter.getRemoteDevice(address);
remoteDevice.connectGatt(context, true, mGattCallback);//參數1:上下文。
                                                       //參數2:是否自動連接(當設備可以用時)
                                                       //參數3:連接回調。

這里可能有些疑問就是,明明已經掃描到了,在回調中已經有了 BluetoothDevice 為何還要去 getRemoteDevice(address)?
那是因為,很多低功耗的設備開機時間是很少的,就拿我們公司開發的那個血壓計,他是開機才開啟藍牙,而測量完了之后過一段時間就會自動關閉。所以防止去連接設備的時候設備已經關機的情況。

連接回調

private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
       if (newState == BluetoothProfile.STATE_CONNECTED) {
                //連接成功
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                //連接斷開
        }
        changeStatus(newState);//改變當前狀態
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
         //當服務發現之后回調這里
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, 
    int status) {
    
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    
    }
};
四、發現服務

一個低功耗藍牙設備是有很多種服務的,就比如該設備的電量信息,設備的當前狀態(比如血壓計,是正在測量還是在等待測量)
有的設備支持歷史數據等等。這些都是在藍牙的服務當中。我們要去發現藍牙的服務!

這里很簡單就是一句話,在連接成功的回調中調用:

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
          //連接成功
          gatt.discoverServices();//開始發現設備的服務
    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
          //連接斷開
    }
    changeStatus(newState);//改變當前狀態
}

調用了之后會在 另一個回調中 回調回來。

     @Override
     public void onServicesDiscovered(BluetoothGatt gatt, int status) {
         //當服務發現之后回調這里
     }
五、數據交互

這里是比較重要的地方,注意,每一個藍牙的通訊協議不通,有的設備是連接了之后不需要任何操作就等待藍牙設備上傳數據的,而有的設備是需要手動打開數據通道!或者發送指令給藍牙設備,每一個Gatt協議中有多個BluetoothGattService,而每個BluetoothGattService中又有多個BluetoothGattCharacteristic (我把它看做一個數據通道-_-!),而每一個BluetoothGattCharacteristic 的屬性是不同的,有的是可讀,有的是可寫,有的是可訂閱,所以一定不要搞混了,可以用UUID區分他們,這里大多數設備廠家都會給一份設備的通訊協議其中就有 哪一個UUID 代表什么。都會有說明。通過UUID 獲取到了對應的BluetoothGattCharacteristic 之后就可以判斷他的屬性是什么。

開啟數據通道

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
//服務發現方法回調。
  if (status == BluetoothGatt.GATT_SUCCESS) {
      BluetoothGattService service = gatt.getService(SERVICE_UUID); //通過廠家給的UUID獲取BluetoothGattService 
       if (service != null) {
           BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID);//同上
            if (characteristic != null &&
                 (characteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                   //通過判斷,打開Notification 通知,提醒。一般是設備測量完成了之后會發送對應的數據上來。
                   gatt.setCharacteristicNotification(characteristic, true);
                   
                   //在通過上面的設置返回為true之后還要進行下面的操作,才能訂閱到數據的上傳。下面是完整的訂閱數據代碼!
                   if(gatt.setCharacteristicNotification(characteristic, true)){
                            for(BluetoothGattDescriptor dp: characteristic.getDescriptors()){
                                if (dp != null) {
                                    if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
                                        dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                                    } else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
                                        dp.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                                    }
                                    gatt.writeDescriptor(dp);
                                }
                            }
                        }
            }
       }
   }
 }

像設備發送指令
??一般向設備發送什么指令在通訊協議上面也是有的,都是發送一個byte[]數組,每一位代表什么協議里面都是不同的。例如:一個測量溫度的設備,他當前是華氏度的單位,我們可以給他發送一個指令讓他把單位更換成攝氏度:

private void changeMonitorMod(BluetoothGatt gatt, byte[] buffer) {
   if (gatt != null && gatt != null) {
       BluetoothGattService writeService = gatt.getService(MYUUID);
       if (writeService == null) {
              return;
       }
   }

    BluetoothGattCharacteristic writeCharacteristic = writeService.getCharacteristic(MYWRITECHARACTERISTIC);
    if (writeCharacteristic == null) {
          return;
    }
    
    writeCharacteristic.setValue(buffer);
    //上面的buffer數組中裝的就是指令,多長? 每一位上面的數字代表什么意思在協議中查看!
    gatt.writeCharacteristic(writeCharacteristic);//像設備寫入指令。
          
}

不要忘了,要在清單文件中AndroidManifest.xml 聲明權限哦。



關于一些坑:

很多廠家很坑爹,給的文檔水的要命,第一時間要看看文檔詳細不詳細,如果沒有文檔至少也要給個Demo.

注意設備的開機時間,自動關機時間,對狀態的保存。

很多設備在自動關機之后的回調是很慢的,甚至設備關機10秒之后才會回調到連接狀態的回調方法中。

關于手動設置斷開 gatt.disConnect() 這個方法,我試過了,調用之后確實會立即回調到對應的狀態方法中,但是實際上物理上的連接是還沒有斷開的。物理上的連接斷開之后還會再次回調到方法中。這是一個比較漫長的回調,區別與設備,不通設備的機制不一樣,有的快,有的慢。

??好了,差不多就這么多,寫的匆忙,如果有哪里不對,輕噴,還請大佬們指正。謝啦!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66441.html

相關文章

  • 2017年云巴產品更新合集

    摘要:更新修正協議下默認關閉時會取消訂閱本次訂閱的所有物聯網整體方案篇年,云巴利用實時跨平臺雙向物聯網云端系統的產品優勢,積極迎接物聯網新時代,為客戶定制物聯網整體解決方案。 SDK 篇 Android SDK 更新 ·Android Release 1.8.5在demo中去除掉小米、華為平臺的jar包,讓用戶自行下載 ·Android SDK 1.8.6對新版華為推送做了適配。 JavaS...

    Airmusic 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<