프로젝트 개요
안드로이드가 설치된 디바이스에 어플을 임베디드로 설치한다음 휴대폰 어플과 블루투스로 연동되어 화면 디스플레이, 녹음, 알람,경보 등 여러가지 유틸리티 기능이 있는 디바이스를 만드는 프로젝트 이다.
주요 기능
1. 블루투스 연동을 통한 기기간 상호작용
블루투스 연동을 통한 디바이스 기가와 유저기기의 상호작용을 골자로 한다.
원래 기획은 블루투스 연동을 통한 사진전송 및 음악재생등 여러가지 기능이 있었지만 IOS의 블루투스의 제한적 제재로 인하여 BLE 즉 저전력 블루투스 로만 통신이 가능했다. 따라서 저전력, 낮은 통신속도로도 가능한 비콘, 사진 변경, 알람등을 BLE 로 처리하고 사진 전송및 커스터마이징 등은 HTTP 통신으로 처리를 하였다.
음 복잡하지만 간략히 설명하자면
ble는 central과 peripheral로 나뉜다.
peripheral은 스마트워치나 이어폰 처럼 advertise 를 통해 연결요청을 한다. 그리고 central 은 하나의 폰처럼 스캔을 하여 기기에게 연결 요청을 하여 페어링 요청을 한다.
GATT server(slave) / GATT client(master)
BLE 장치가 연결된 이후 어떻게 서로 통신하는지에 대해 정의 한다. 하나의 프로토콜이라고 보면 된다.
일반적으로 peripheral 장치(센서장치)가 GATT server 역할을 한다. ATT lookup data, service, characteristic 에 대한 정의를 가지고 있습니다. GATT client(폰, 태블릿 등)에서 GATT server 로 데이터 요청을 보냄으로 시작된다.
모든 동작(transaction)은 GATT client 에서 시작되어 GATT server로 부터 응답을 받게 된다.
두 장치가 연결될 때 peripheral(센서장치) 은 연결간격(connection interval)을 전달을 한다. Central(폰)은 이 시간만큼 간격을 두고 새로운 데이터가 있는지 재연결을 시도할 수 있으나. 하지만 이것은 필수 사항은 아니다.
블루투스 관련 라이브러리가 많지만 peripheral 모드만 지원을 한다던지, 블루투스 스캔만 지원 한다.
결국 메소드 채널을 이용해 안드로이드 native 코드를 써서 gatt 서버 로직을 직접 구현 할수 밖에 없었다.
메소드 체널은 플러터에서 네이티브 코드를 생성 및 실행하고 그 결과값을 플러터 프레임워크에서 사용하는것이다.
즉 네이티브 코드를 실행하는것이다. 따라서 하나의 기능을 만들시 안드로이드, IOS 두가지 플랫폼의 코드를 알아야 될 필요가 있다.
이프로젝틑에서는 디바이스기기가 안드로이드라 다행히? 코틀린 코드만 작성하면되기에 코틀린 코드를 간략하게 소개하고자 한다.
https://docs.flutter.dev/platform-integration/platform-channels
Writing custom platform-specific code
Learn how to write custom platform-specific code in your app.
docs.flutter.dev
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 초기화 작업, 뷰 바인딩 등
}
override fun onStart() {
super.onStart()
// 액티비티가 사용자에게 보이기 직전에 호출
}
override fun onResume() {
super.onResume()
// 액티비티가 포그라운드에 진입하고 사용자와 상호작용 가능한 상태
}
override fun onPause() {
super.onPause()
// 액티비티가 포그라운드를 벗어날 때 호출
}
override fun onStop() {
super.onStop()
// 액티비티가 더 이상 사용자에게 보이지 않을 때 호출
}
override fun onDestroy() {
super.onDestroy()
// 액티비티가 완전히 종료되기 전에 호출
}
}
각 생명주기 함수의 주요 용도:
onCreate(): 액티비티 초기화, 레이아웃 설정
onStart(): 액티비티가 보이기 직전 준비 작업
onResume(): 사용자와 상호작용 시작, 리소스 획득
onPause(): 리소스 해제, 작업 중단
onStop(): 장기 실행 작업 중지, 리소스 해제
onDestroy(): 최종 정리 작업
즉 블루투스 기능을 구현한다면 다음과 같다.
onCreate()
블루투스 어댑터 초기화
필요한 권한 확인 및 요청
블루투스 서비스 바인딩 (서비스를 사용하는 경우)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
checkBluetoothPermissions()
bindBluetoothService()
}
onStart()
블루투스가 활성화되어 있는지 확인
필요한 경우 블루투스 활성화 요청
override fun onStart() {
super.onStart()
if (!bluetoothAdapter.isEnabled) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
}
onResume()
블루투스 디바이스 스캔 시작 (필요한 경우)
블루투스 연결 상태 리스너 등록
override fun onResume() {
super.onResume()
startBluetoothScan()
registerBluetoothStateReceiver()
}
그외 onPause(),onDestroy(), onStop() 등을 통해 블루투스 연결을 중지 및 종료 시키는 로직을 수행하면 된다.
2. 여러 유틸리티 기능( 주요 라이브러리 소개)
비콘 소개
여러 라이브러리중에 추천하는것
https://pub.dev/packages/flutter_beacon/versions
flutter_beacon package - All Versions
Pub is the package manager for the Dart programming language, containing reusable libraries & packages for Flutter and general Dart programs.
pub.dev
주의해야될점은 IOS에서는 uuid를 설정해줘야 한다. 따라서 비콘 등록 절차를 통해 내 비콘을 먼저 등록 후 조회하여야 한다.
// beacon streamReangin
FutureOr<void> _streamRangingEvent(StreamRangingEvent event, emit) async {
if (Platform.isIOS) {
// ios 에서는 uuid를 설정해줘야 근처 beacon을 조회해 줍니다.
state.regoin.add(Region(
identifier: 'Apple Airlocate',
proximityUUID: '7777772E-6B6B-6D63-6E2E-636F6D000001'));
} else {
// android 에서는 uuid가 없어도 근처 beacon을 조회해 줍니다.
state.regoin.add(Region(
identifier: '',
));
}
// beacon 설정 되어있는 beacon minor를 targetList저장 합니다.
List<dynamic> targetList =
state.registeredBeaconId.map((e) => e.beaconMinorId).toList();
// 근처에 beacon을 조회합니다.
flutterBeacon.ranging(state.regoin).listen((RangingResult result) {
result.beacons.forEach((element) {
// 근처에 중복된 beacon이 계속 나오는데 beacon minor를 중복된거는 없애주고 근처 비콘을 state.resultsList에 저장합니다.
if (!state.resultsList.contains(element.minor.toString())) {
state.resultsList.add(element.minor.toString());
state.resultsList.removeWhere((item) => targetList.contains(item));
}
});
});
}
알람
flutter_local_notifications
qrcode scanner
여러 qrcode 스캐너가 존재하지만 추천하는것은 qrcode scanner 이다. 그 이유는 다음글 참조..
https://dev1song.tistory.com/15
[Flutter] qr_code_scanner 소개 및 사용방법
서론 처음 플러터 개발을 시작했을 때 QR스캔이 필요해서 아무 패키지나 사용했다. '플러터 패키지니까 사용량 높은 아무거나 써도 Android/iOS 다 지원하겠지?' 대충 이런 생각이었다. 아니 그냥 iOS
dev1song.tistory.com
사진 커스터마이징 라이브러리
'프로젝트' 카테고리의 다른 글
[Web] Carmmunity-차량인증 소유주들의 커뮤니티 (0) | 2024.12.17 |
---|---|
[Web] Allotter-외주관리 플랫폼 (0) | 2024.12.17 |
[App] 푸드픽 (1) | 2024.12.13 |
[App] Konect App (0) | 2024.12.02 |
[Web] 관리자 페이지 (0) | 2024.12.02 |