본문으로 바로가기

[Android App] BLE GATT:: [3] Characteristic /Descriptor 출력하기

category Android_app 2023. 4. 27. 17:48

  :BLE GATT:: [2] 번 글 연속 강의  ==> [2]번 글 링크는 마지막에 넣었습니다.

   서비스 리스트를 출력했으니 다음으로 서비스 아래의

   특성(Chracteristic) 및 디스크립터를  출력해 보겠습니다.

 

목차

     

    ▶ UUID 는 가독성이 떨어지니 알려진 UUID는 문자열로 바꾸기위한 HashMap()을 새로 만들어 줍니다.

    class SampleGattAttributes {
        companion object {
            val attributes : HashMap<String, String>?
            init{
                attributes  = HashMap()
    
                // Gatt Services
                ~~ 중략 ~~
                attributes.put("00001800-0000-1000-8000-00805f9b34fb", "Generic Access")
    
                // Gatt Descriptors
                ~~ 중략 ~~
                attributes.put("00002902-0000-1000-8000-00805f9b34fb", "Client Characteristic Configuration");
    
                // Gatt Characteristics
                attributes.put("00002a00-0000-1000-8000-00805f9b34fb", "Device Name")
                attributes.put("00002a01-0000-1000-8000-00805f9b34fb", "Appearance")
                 ~~ 중략 ~~
            }
            fun lookup(uuid: String, defaultName: String): String? {
                val name = attributes?.get(uuid)
                return name ?: defaultName
            }
        }
    }

     

      기존 서비스  uuid 표시부분을 다음처럼 변경합니다.

        mBtGattServices!![serviceIndex].uuid}   <== 기존 서비스 uuid 표시 부분
     ==> 
        SampleGattAttributes.lookup(mBtGattServices!![serviceIndex].uuid.toString(),"unKnown")

     

    ▶ Characteristic 출력하기

      : Characteristic 을 얻기위해선 BluetoothGattService  클래스의  getCharacteristics() 메소드를 호출후

         리턴되는 List<BluetoothGattCharacteristic> 에서 한개씩 값을 읽어오면 됩니다.

    1> BluetoothGattService   ==> 기존에 구한 mBtGattServices 아래 [index] 사용해 구함.
         ==>  mBtGattServices!![serviceIndex]
    
    2> getCharacteristics 메서드 호출로 List<BluetoothGattCharacteristic> 구하기
       ==> mBtGattServices!![serviceIndex].characteristics
    
    3> List 컬렉션의 forEach{} 를 사용해 uuid 구하기
    mBtGattServices!![serviceIndex].characteristics.forEach {charac ->
        Text("${charac.uuid}",fontSize = 12.sp,)
    }

     

    디스크립터 출력하기

      : BluetoothGattCharacteristic 안의 getDescriptors()를 사용해 List<BluetoothGattDescriptor> 를 구한후

        사이즈 체킹후 BluetoothGattDescriptor를 한개씩 읽어 오면 됩니다.

    1> BluetoothGattCharacteristic 구하기
        mBtGattServices!![serviceIndex].characteristics.forEach { 
           charac ->               <--- 요기
            ....
        }
    
    2> List<BluetoothGattDescriptor> 구하기
    	val listDescriptor:List<BluetoothGattDescriptor> =charac.descriptors
    
    3> BluetoothGattDescriptor 출력하기
        if(listDescriptor.size >0){
            listDescriptor.forEach {
                Text(" ${it.uuid}",fontSize = 12.sp,)
            }
        }

     

    화면 출력 Composable 함수 

      : LazyColumn 과 AnimatedVisibility 함수를 사용했습니다.

    @Composable
    fun DisplayServiceList(){
        ~~ 중략 ~~
        Spacer(modifier = Modifier.size(50.dp))
        Text("  Service List", fontSize = 24.sp, color = Color.Red)
    
        LazyColumn {
            itemsIndexed(mBtGattServices!!){ serviceIndex , item ->
                var isExpanded by rememberSaveable { mutableStateOf(false) }
                val uuidSrcName =  SampleGattAttributes.lookup(mBtGattServices!![serviceIndex].uuid.toString(),"unKnown")
                Column(modifier = Modifier
                    .clickable {
                        isExpanded = !isExpanded
                    }
                ) {
                    Text("    ${uuidSrcName}", color = Color.Green)
                    if (uuidSrcName!!.compareTo("unKnown") == 0) {
                        Text("        ${mBtGattServices!![serviceIndex].uuid}", fontSize = 12.sp,)
                    }
                }
    
                AnimatedVisibility(visible = isExpanded) {
                    Column{
                        mBtGattServices!![serviceIndex].characteristics.forEachIndexed { chIndex, characs ->
                            val uuidCharacsName = SampleGattAttributes.lookup(characs.uuid.toString(),"unKnown")
                            if(uuidCharacsName!!.compareTo("unKnown")==0)
                                Text("            ${characs.uuid}",fontSize = 12.sp,)
                            else {
                                Text("      ${uuidCharacsName}",color=Color.Blue)
                                val listDescriptor:List<BluetoothGattDescriptor> =characs.descriptors
                                if(listDescriptor.size >0){
                                    listDescriptor.forEach {
                                        val uuidDescName = SampleGattAttributes.lookup(it.uuid.toString(),"unKnown")
                                        if(uuidDescName!!.compareTo("unKnown")==0){
                                            Text("           ${it.uuid}",fontSize = 12.sp,)
                                        }else
                                            Text("       ${uuidDescName}",color=Color.Gray)
                                    }
                                }
                            }
                        }
                    }
                }
    
                // use the material divider
                Divider(color = Color.Red, thickness = 1.dp)
                Spacer(modifier = Modifier.size(20.dp))
            }
        }
    }

     

     영상 첨부

     

     

     

    <정리>

     ▶ Characteristic / Descriptor 를 읽기위한 과정은 2가지만 알면 됩니다.

       → Characteristic 을 얻기위해 BluetoothGattService 의 getCharacteristics() 를 사용 하기

       → Descriptor 를 얻기위해 BluetoothGattCharacteristic 의 getDescriptors() 를 사용하기

     

       → 부수적으로 List<>  forEach{} 구문 사용하기

     

     

     ▶ 이전 글

    https://leevisual.tistory.com/225

     

    [Android App] BLE GATT:: [2] 서비스 리스트 출력하기

    BLE GATT:: [1] 번 글 연속 강의 ==> [1]번 글 링크는 마지막에 넣었습니다. : 이번에는 Gatt Server 와 연결이 수립된후 서비스 리스트를 검색해 화면에 출력을 해보겠습니다. 연결이 완료된지는 BluetoothGa

    leevisual.tistory.com

     

    반응형