반응형
유저에게 앱 권한 요청하기
- 모바일에서 유저의 모바일에 있는 데이터를 사용하기 위해선 권한 요청을 하게 되는데
- 권한 요청을 하기 위해선 패키지를 하나 설치해야 한다.
- 프로젝트에 있는 pubspec.yaml에서 dependencies 아래 부분에 permission_handler를 작성해주면 되는데 우선은 강사님과 버전을 맞추기 위해 아래와 같이 작성
dependencies: flutter: sdk: flutter permission_handler: ^8.3.0
- 이후 permission_handler 를 선택 후 전구를 클릭 하여
- Pub get을 클릭하면 설치가 된다.
- 다만 여기서 **A dependency may only have one source** 와 같은 에러가 발생하게 된다면
- 문제는 들여쓰기가 잘못되어있다는 점!
- 예시로 아래와 같이 작성하면 **위와 같이 들여쓰기**를 해주면 된다.
dependencies: flutter: sdk: flutter permission_handler: ^8.3.0
- 이후 main.dart 파일로 다시 돌아와서 상단에 import로 불러올 코드로
- import 'package:permission_handler/permission_handler.dart'; 를 작성해주면 된다.
- 그리고 Android 기기에 셋팅을 하겠다고 하면
- android 폴더에서 [gradle.properties](<http://gradle.properties>) 로 들어가서 아래의 코드처럼 작성되어 있는지 확인
org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true
- app 폴더의 build.gradle 파일로 들어가서 아래와 같이 코드가 작성되어 있는지 확인하기
- 숫자가 아닌 두 번째처럼 문자로 기입이 되어있다면 그냥 넘어가기
- android{ compileSdkVersion 31 }
- android{ compileSdkVersion flutter.compileSdkVersion }
- 숫자가 아닌 두 번째처럼 문자로 기입이 되어있다면 그냥 넘어가기
- app 폴더의 src 폴더에 있는 AndroidManifest.xml 파일을 클릭해서 코드 추가 하기
- 현재 아래는 CONTACTS에 대한 읽기, 쓰기 권한을 부여하는 것인데
- 나중에는 필요한 다른 기능들도 추가하면 권한을 요청할 수 있을 것!
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
- 이후 main.dart로 돌아와서 상단에 import 하기
… 이거 휴대폰에 적용하는거 보이려고 포맷도 하고 버전도 변경하게 난리를 피웠다가 하다보니 그냥 어찌어찌 되었는데… 그게 며칠 동안 이런건지…import 'package:permission_handler/permission_handler.dart';
- 유저에게 허락받는 방법
- 이제 permisson에 대한 셋팅을 완료했으니 함수를 작성해서 간단하게 요청하기
getPermission() async{ var status = await Permission.contacts.status; // 연락처 권한을 주었는지 대한 여부 if (status.isGranted) { print('허락됨'); } else if (status.isDenied) { print('허락됨'); Permission.contacts.request(); // 허락해달라고 팝업띄우는 코드 } }
- 이후 해당 함수는 연락처 앱에 들어갈 때 한 번만 요청을 하면 되기에 JavaScript의 useEffect 와 유사한 것으로 initState()가 있다
- initState는 init을 작성 후 자동완성하면 된다.
@override void initState() { // 위젯이 로드될 때 한번 실행 super.initState(); getPermission(); }
- 이후 재실행하게 되면 요청을 하게 되는데
- 여기서 조심해야할 부분은
- Android 11이상, IOS 환경에서는 거절을 2번 이상하게 되면 팝업이 더 이상 생성되지 않기에 조심해야 한다.
- 이유는 앱 정책상 사람들이 계속해서 거절하는 경우도 있는데 매번 거절을 하는 것 자체가 불편한 반복 경험을 발생하는 것이기에 그럴 듯?
- 그래서 만약 다시 문구를 발생시켜서 허락을 원한다면
- openAppSettings() 를 작성하게 해주면 셋팅을 다시 할 수 있게 설정 창으로 보내주게 된다.
@override void initState() { // 위젯이 로드될 때 한번 실행 super.initState(); getPermission(); openAppSettings(); }
- 여기서 조심해야할 부분은
- 마지막으로 지금까지의 main.dart 코드 전체
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(
MaterialApp(
home: MyApp()
)
);
}
class MyApp extends StatefulWidget {
MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
getPermission() async{
var status = await Permission.contacts.status; // 연락처 권한을 주었는지 대한 여부
if (status.isGranted) {
print('허락됨');
} else if (status.isDenied) {
print('허락됨');
Permission.contacts.request(); // 허락해달라고 팝업띄우는 코드
}
}
// @override
// void initState() { // 위젯이 로드될 때 한번 실행
// super.initState();
// // getPermission();
// openAppSettings();
// }
var a = 1;
var total = 3;
var person = [['메시', 0, '010-1234-5678'], ['날강두', 0, '010-1234-5678'], ['홀란', 0, '010-1234-5678']];
// var cnt = [0, 0, 0];
var title = 'Contact';
changeNumber(){
setState(() {
total++;
});
}
changeState(value){
setState(() {
person.add(value);
});
}
deleteState(idx){
setState(() {
person.removeAt(idx);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: (){
showDialog(context: context, builder: (context){
return Dialog(
child: Modal(state: title, changeNumber: changeNumber, changeState:changeState)
);
});
},
),
appBar: AppBar(title: Text(total.toString()),actions: [
IconButton(onPressed: (){
getPermission();
}, icon: Icon(Icons.contacts))
],),
body: ListView.builder(
itemCount: person.length,
itemBuilder: (c,i){
return ListTile(
leading: Text(person[i][1].toString()),
title: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(person[i][0].toString()),
Text(' '),
Text(person[i][2].toString()),
TextButton(onPressed: (){
deleteState(i);
}, child: Text('삭제'))
],
),
),
trailing: TextButton(
child: Text('좋아요'),
onPressed: (){
setState(() {
person[i][1] = (person[i][1] as int) +1;
});
},
),
);
}
),
);
}
}
class Modal extends StatelessWidget {
Modal({super.key, this.state, this.changeNumber, this.changeState});
final state;
final changeNumber;
var changeState;
var inputData = TextEditingController();
@override
Widget build(BuildContext context) {
return Container(
height: 400,
margin: EdgeInsets.fromLTRB(30, 0, 30, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.all(30),
child: Text(state, style: TextStyle(fontSize: 40, fontWeight: FontWeight.w900)),
),
Container(
margin: EdgeInsets.all(30),
child: TextField( controller: inputData, style: TextStyle(fontSize: 30),),
),
Container(
margin: EdgeInsets.all(30),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: TextButton(onPressed: (){
Navigator.pop(context);
}, child: Text('Cencel', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),)),
),
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: TextButton(onPressed: (){
if (inputData.text != ''){
changeState([inputData.text.toString(), 0, '010-1234-5678']);
Navigator.pop(context);
}
}, child: Text('OK', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),)),
),
],
),
)
],
),
);
}
}
'Flutter' 카테고리의 다른 글
[Flutter] null check 하는 법 & Android 앱으로 발행하기 (0) | 2023.08.07 |
---|---|
[Flutter] 휴대폰에 저장된 연락처 가져오는 법 & 타입 시스템 (0) | 2023.08.07 |
[Flutter] 자식 위젯이 부모 위젯의 state 사용 2 (0) | 2023.07.31 |
[Flutter] 자식 위젯이 부모 위젯의 state 사용 (0) | 2023.07.31 |
[Flutter] Dialog/모달창 만드는 법 & context (0) | 2023.07.31 |