티스토리 뷰
flutter_blue | Flutter Package (pub.dev)
업데이트
블루투스(flutter pub add flutter_blue)설치
에러 메세지 : Expected to find project root in current working directory.
프로젝트폴더로 가서 실행해야됨
프로젝트폴더 크기가 약 650Mbyte(뭐가 이렇게 큰가?)
안드로이드 스튜디오에서
Build->flutter -> Build APK
에러 메세지 : uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:flutter_blue]
버젼19이상 사용해라.
android/app/build.gradle:
Android {
defaultConfig {
minSdkVersion: 19
소스파일에서 찾아서 변경 후 다시 빌드(위 코드에서 :은 빼야함)
android/app/src/main/AndroidManifest.xml
permission 등록
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<dict>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Need BLE permission</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Need BLE permission</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Need Location permission</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Need Location permission</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Need Location permission</string>
에러들...
빨간글씨(?)는 있지만, APK파일 생성은 되었다.
APK파일은 핸드폰에 넣고, 설치하면 동작이 가능하다.
구글플래이에 등록하여 배포도 가능하다.
안드로이드 가상머신에서 확인해보려면, android [xxxx]마우스 우클릭하고, 새창에서 확인해보면 된다.
(flutter는 안드로이드 코드를 생성하는 역할)
샘플코드 빌드
GitHub - pauldemarco/flutter_blue: Bluetooth plugin for Flutter
pauldemarco/flutter_blue
Warning: ����ġ ���� ���(URI: "", ����: "base-extension")�Դϴ�. �ʿ��� ��Ҵ� <{}codename>,<{}layoutlib>,<{}api-level>�Դϴ�.
lib/main.dart:57:20: Error: The getter 'subhead' isn't defined for the class 'TextTheme'.
- 'TextTheme' is from 'package:flutter/src/material/text_theme.dart' ('/D:/Flutter/packages/flutter/lib/src/material/text_theme.dart').
Try correcting the name to the name of an existing getter, or defining a getter or field named 'subhead'.
.subhead
^^^^^^^
SOLUTION
There are Two Solutions for this error
- Use Alternative Package
- Do some changes in .pub-cache
main.dart : subhead -> subtitle1
Text(
'Bluetooth Adapter is ${state != null ? state.toString().substring(15) : 'not available'}.',
style: Theme.of(context)
.primaryTextTheme
.subtitle1//20220328 .subhead
?.copyWith(color: Colors.white),
),
lib/widgets.dart:138:52: Error: The getter 'body1' isn't defined for the class 'TextTheme'.
- 'TextTheme' is from 'package:flutter/src/material/text_theme.dart' ('/D:/Flutter/packages/flutter/lib/src/material/text_theme.dart').
Try correcting the name to the name of an existing getter, or defining a getter or field named 'body1'.
style: Theme.of(context).textTheme.body1?.copyWith(
^^^^^
widgets.dart, widgets.dart파일에서
body1을 bodyText1으로 변경
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}',
//20220328 style: Theme.of(context).textTheme.body1?.copyWith(
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Theme.of(context).textTheme.caption?.color))
Text(
'0x${characteristic.uuid.toString().toUpperCase().substring(4, 8)}',
//20220328 style: Theme.of(context).textTheme.body1?.copyWith(
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Theme.of(context).textTheme.caption?.color))
Error: The getter 'body1' isn't defined for the class 'TextTheme'.
=> body1 -> bodyText1
Execution failed for task ':app:checkDebugAarMetadata'
=> compileSdkVersion 31, targetSdkVersion 31 이상
Device Manager에서 시뮬레이터를 켜야지 아래 목록에 시뮬레이터가 나옴.
android {
compileSdkVersion 31//20220328 compileSdkVersion 30
android {
compileSdkVersion 31//20220823 compileSdkVersion 30
실물 핸드폰으로 디버깅하려면,
핸드폰에서 "개발자옵션" 활성화 시키고,
USB 디버깅 : ON
Run, Debug star하면, apk 파일이 생성되고, 잠시후 핸드폰 앱이 자동 실행하면 된다.
√ Built build\app\outputs\flutter-apk\app-debug.apk.
Installing build\app\outputs\flutter-apk\app.apk...
(기다려..)
2번째 빌드시,
Target file "lib\main.dart" not found.
=> ??
This expression has a type of 'void' so its value can't be used.
=> 함수의 리턴값이 void라서, .xxx()를 할 수 없다는 말.
(C와 다른) DART class 문법
int get launchYear => launchDate?.year;
=> launchYear = get() { return launchDate?.year; } 와 동일한 표현
launchDate?.year; 에서 ? 는 launchDate 가 null 값이 아닐 때만 year 에 참조한다는 표현이다.
String? name; //name은 null값을 가질 수 있는 변수 임
int? get launchYear => launchDate?.year; //launchDate.year 값은 null일 수 있음
print('Spacecraft: $name'); //name변수값을 print. 문자열은 "..." 이나, '...' 모두 사용가능
- ?? : name이 null일 경우만 수행
- ? : name2가 null이 아닐 경우 수행
void main() {
String name;
print(name ?? 'Null일때만 실행됨.');
String name2 = 'ICECREAM';
print(name2?.toLowerCase()); // icecream
}
데이터 타입 검사 : is
int a = 2;
if (a is int)
{
print('int type');
}
else
{
print('not int type');
}
class 다운캐스팅
PointDetail p1 = PointDetail();
if (p1 is PointDetail)
{
PointDetail p2 = p1 as PointDetail;
}
var map = {
'key1': '1',
'key2': '2',
'key3': '3'
};
void main() {
List<Map<String, dynamic>> myProducts = [
{"name": "Shoes", "price": 100}, //name="Shoes"; price=100;
{"name": "Pants", "price": 50},
{"name": "Book", "price": 10},
{"name": "Lamp", "price": 40},
{"name": "Fan", "price": 200}
];
// Selling price from low to high
myProducts.sort((a, b) => a["price"].compareTo(b["price"]));
print('Low to hight in price: $myProducts');
// Selling price from high to low
myProducts.sort((a, b) => b["price"].compareTo(a["price"]));
print('High to low in price: $myProducts');
}
snapshot.data!
//StreamBuilder등으로 구성된 class만으로 구성된 코드에서 중간에 Sort삽입하는 방법
StreamBuilder<List<ScanResult>>(
stream: FlutterBlue.instance.scanResults,
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data!
.map(
(r) => ScanResultTile(
result: r,
onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
r.device.connect();
return DeviceScreen(device: r.device);
})),
),
).toList()..sort((a,b){return b.result.rssi-a.result.rssi;}),//2022032902 강한 신호부터 보이도록 정렬
'Flutter' 카테고리의 다른 글
flutter에서 StatelessWidget 화면 갱신 (0) | 2022.05.31 |
---|---|
flutter Dart - 포인터? 전역 함수에서 UI 제어하기 (0) | 2022.04.07 |
flutter : Scaffold - 넌 뭐냐? (0) | 2022.04.06 |
2022-flutter 설치(작성중) (0) | 2022.03.27 |
안드로이드, IOS 앱 개발 - Flutter (0) | 2022.03.21 |