flutter 네이버 지도
1. 플랫폼 등록
NAVER CLOUD PLATFORM
cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification
www.ncloud.com
1) 사용할 서비스 선택
2) 패키지명, 번들ID 추가
3) 인증 키 확인
2. 패키지 설치
flutter 3.10, dart 2.18.4 이상
android 5.1 이상, iOS 11.0 이상
flutter_naver_map | Flutter Package
Naver Map plugin for Flutter, which provides map service of Korea.
pub.dev
(해당 패키지에 Document가 잘 되어 있다.)
flutter_naver_map docs | flutter_naver_map
flutter_naver_map docs
note11.dev
3. 설정
Client ID를 지정하기 위한 설정이다.
아래 방법으로 플랫폼별로 지정해도 되지만
Document에서 main함수를 통해 NaverMap을 초기화할 때 Client ID를 지정하는 것을 권장하고 있다.
// 안드로이드 - AndroidManifest.xml
<application
<activity
...
</activity>
<-- 추가 -->
<meta-data
android:name="com.naver.maps.map.CLIENT_ID"
android:value="YOUR_CLIENT_ID" />
</application>
// ios - info.plist
<key>NMFClientId</key>
<string>YOUR_CLIENT_ID</string>
+ 안드로이드의 경우 최소 SDK버전을 맞춰준다.
// app > build.gradle
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.flutter_naver_map_test"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21 // <- 21로 맞춰주기
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
4. 지도 열기
void main() async {
// NaverMapSdk 초기화
WidgetsFlutterBinding.ensureInitialized();
await NaverMapSdk.instance.initialize(
clientId: 'YOUR_CLIENT_ID',
onAuthFailed: (ex) => log("인증 오류 ${ex.message}"),
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: NaverMap(), // NaverMap
);
}
}
5. 옵션
NaverMapViewOptions를 이용한다.
(* 네이버 지도 하단의 NAVER 로고를 가리면 안된다.)
1) 지도 처음 위치
NaverMap(
options: NaverMapViewOptions(
initialCameraPosition: NCameraPosition( // 지도 처음 위치
target: NLatLng(37.5667070936, 126.97876548263318),
zoom: 15,
bearing: 0,
tilt: 0
)
),
)
2) 줌 및 기울기 제한
NaverMap(
options: NaverMapViewOptions(
minZoom: 10, // default is 0
maxZoom: 16, // default is 21
maxTilt: 30, // default is 63
),
),
3) 내 위치 위젯
NaverMap(
options: NaverMapViewOptions(
locationButtonEnable: true // 내 위치 찾기 위젯이 하단에 나옴
),
),
위치 기능 사용 시 따로 위치 권한을 요청해야한다.
(위치 서비스가 휴대폰 설정에서 켜져있어야 요청이 된다.)
permission_handler | Flutter Package
Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
pub.dev
// AndroidManifest.xml 추가
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
// info.plist 추가
<key>NSLocationWhenInUseUsageDescription</key>
<string>Need location when in use</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Always and when in use!</string>
<key>NSLocationUsageDescription</key>
<string>Older devices need location.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Can I have location always?</string>
// Podfile 추가
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
# 위치 권한
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
]
end
# End of the permission_handler configuration
end
end
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
requestPermission();
super.initState();
}
// 위치 권한 요청
void requestPermission() async {
await Permission.location.request();
var status = await Permission.location.status;
log("status: $status");
if(status.isPermanentlyDenied) {
await openAppSettings();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: NaverMap(
options: NaverMapViewOptions(
initialCameraPosition: NCameraPosition( // 첫 로딩 포지션
target: NLatLng(37.5667070936, 126.97876548263318),
zoom: 15,
bearing: 0,
tilt: 0
),
locationButtonEnable: true,
),
onSymbolTapped: (symbolInfo) {
log("symbolInfo: ${symbolInfo.caption}");
},
onMapReady: (controller) {
log("준비완료!");
},
),
);
}
}