์์น ๊ถํ์ด ๋ถ์ฌ๋ ํ ํ์ฌ ์์น๋ฅผ ๊ฐ์ ธ์ค๋ ค๊ณ ์๋ํ๊ณ ์์น ์๋น์ค๋ ํ์ฑํ๋์ด ์์ง๋ง getCurrentPosition
๊ฐ ํธ์ถ๋ ๋ LocationServiceDisabledException
๋ฐ์์ต๋๋ค.
try {
final enabled = await Geolocator.isLocationServiceEnabled();
print("enabled $enabled"); // true
final permission = await Geolocator.checkPermission();
print("permission $permission"); // whileInUse
final position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.medium,
); // throw exception here
} catch (e) {
// i got `LocationServiceDisabledException` here
}
๊ด๋ จ๋ ๋ชจ๋ ๊ถํ์ด ๋ถ์ฌ๋๊ณ Android์ ๋ชจ๋ ๊ตฌ์ฑ์ด ์๋ฃ๋ฉ๋๋ค.
๋ฒ์ : 6.1.5
ํ๋ซํผ:
๋์ผํ ์ค๋ฅ๊ฐ ์์ง๋ง LocationAccuracy
๋ฅผ ๊ธฐ๋ณธ๊ฐ์์ ๋ค๋ฅธ ๊ฒ์ผ๋ก ๋ณ๊ฒฝํ ๋๋ง ๋ฐ์ํฉ๋๋ค.
StreamSubscription _streamSubscription = Geolocator.getPositionStream(
// desiredAccuracy: LocationAccuracy.medium, <-- LocationServiceDisabledException error if I use a different accuracy
distanceFilter: 500
).listen(_listenData)..onError((e, stk) => print(e));
์ด ๋ฌธ์ ๋ฅผ ์กฐ์ฌํ๊ณ ์์ง๋ง ์ฌํํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค. ๋ค์ ์ง๋ฌธ์ ๋ตํ๊ณ ์ด ๋ฌธ์ ๋ฅผ ๋๋ฒ๊น ํ๋ ๋ฐ ๋์์ ์ค ์ ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋๋ก ํผ๋๋ฐฑ์ ๊ธฐ๋ค๋ฆฌ๊ฒ ์ต๋๋ค.
๋ด๊ฐ ํ ๋ ๊ฐ์ Unhandled Exception: The location service on the device is disabled.
์ป์์ต๋๋ค.
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
ํด๋น ์ฑ์ ์์น ์๋น์ค๊ฐ ํ์ฑํ๋ ๊ฒฝ์ฐ์๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
๋๋ ๊ทธ๊ฒ์ ์๋ํ๊ณ ๊ทธ๊ฒ์ ์ค๊ฐ ์ ํ๋๋ก ์๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ค์ ์์๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
๋์ผํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ผ๋ฉฐ ์ด๋ค ์ค์ ์์๋ ์๋ํ์ง ์์ต๋๋ค. ์์น๊ฐ ํญ์ ์ผ์ ธ ์๋ ์๋ฎฌ๋ ์ดํฐ์ ์ค์ ์ฅ์น ๋ชจ๋์์ ํ ์คํธ๋์์ต๋๋ค.
์ต๊ณ ์ ์ ํ์ฑ๋ง์ ์ถ๊ตฌํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ฌ๋๋ค์๊ฒ๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
๋ ๋ง์ ํผ๋๋ฐฑ์ ์ ๊ณตํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ฐ๋ฆฌ๋ ํ์ฌ ๊ทธ๊ฒ์ ์กฐ์ฌํ๊ณ ์์ง๋ง ์ฌ์ ํ ๊ทธ๊ฒ์ ์ฌํํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ํน์ ์ค์ ์ด ํ์ฑํ/๋นํ์ฑํ๋๋ ๊ฒ๊ณผ ๊ด๋ จ์ด ์์ ์ ์์ต๋๋ค.
์๊ฒ๋๋ฉด ๋น์ฐํ ์๋ ค๋๋ฆฌ๊ฒ ์ต๋๋ค. ๊ทธ ๋์ ์ฐ๋ฆฌ๋ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ํด ์ด๋ ค ์์ต๋๋ค(์ฆ, ์ด๊ฒ์ ๋ชจ๋ Android API์์ ๋ฐ์ํฉ๋๊น ์๋๋ฉด Android 10์์๋ง ๋ฐ์ํฉ๋๊น).
๋๋ ๊ฐ์ ์ค๋ฅ๊ฐ ์์ต๋๋ค. https://prnt.sc/vr3glj
์ฅ์น๊ฐ ๋คํธ์ํฌ(WIFI ๋๋ ๋ชจ๋ฐ์ผ)์ ์ฐ๊ฒฐ๋์ด ์์ง ์๊ณ ๊ฑด๋ฌผ ์์ ์๋ ๊ฒฝ์ฐ์๋ง ๋์ผํ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค(์: GPS ์ฐ๊ฒฐ ๋ถ๋).
ํ์ฌ ์คํธ๋ฆผ ์ค์ :
StreamSubscription<Position> positionStream = Geolocator.getPositionStream(
desiredAccuracy: LocationAccuracy.best, distanceFilter: 0)
.listen((Position position) {}
AndroidManifest.xml: <!--Location-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
์ฅ์น ์์น ์ค์ : ๋์ ์ ํ๋(GPS, Wi-Fi, Bluetooth ๋ฐ ๋ชจ๋ฐ์ผ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์น ํ์ธ)
ํธ์ง: ๋ฌผ๋ฆฌ์ ์ฅ์น ์ฌ์ฉ
@seb3n ๊ฐ์ฌํฉ๋๋ค ์ด๊ฒ์ ๋งค์ฐ ์ ์ฉํ ์ ๋ณด์ ๋๋ค. ๋๋ ์ด๊ฒ์ด ๋์๊ฒ ๊ณ์ํ ๋ฌด์ธ๊ฐ๋ฅผ ์ค ๊ฒ์ด๋ผ๊ณ ํ์ ํ๋ค.
๋ ๋ง์ ํผ๋๋ฐฑ์ ์ ๊ณตํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ฐ๋ฆฌ๋ ํ์ฌ ๊ทธ๊ฒ์ ์กฐ์ฌํ๊ณ ์์ง๋ง ์ฌ์ ํ ๊ทธ๊ฒ์ ์ฌํํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ํน์ ์ค์ ์ด ํ์ฑํ/๋นํ์ฑํ๋๋ ๊ฒ๊ณผ ๊ด๋ จ์ด ์์ ์ ์์ต๋๋ค.
์๊ฒ๋๋ฉด ๋น์ฐํ ์๋ ค๋๋ฆฌ๊ฒ ์ต๋๋ค. ๊ทธ ๋์ ์ฐ๋ฆฌ๋ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ํด ์ด๋ ค ์์ต๋๋ค(์ฆ, ์ด๊ฒ์ ๋ชจ๋ Android API์์ ๋ฐ์ํฉ๋๊น ์๋๋ฉด Android 10์์๋ง ๋ฐ์ํฉ๋๊น).
@mvanbeusekom Android 9์์ ๋์ผํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
E/flutter (31570): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: The location service on the device is disabled.
E/flutter (31570): #0 MethodChannelGeolocator._handlePlatformException (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:192:9)
E/flutter (31570): #1 MethodChannelGeolocator.getCurrentPosition (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:121:7)
E/flutter (31570): <asynchronous suspension>
E/flutter (31570): #2 Geolocator.getCurrentPosition (package:geolocator/geolocator.dart:258:35)
isLocationServiceEnabled๊ฐ true์
๋๋ค.
์ํธ
bool isLocationServiceEnabled =
await Geolocator.isLocationServiceEnabled();
AppLog.d(isLocationServiceEnabled);
if (isLocationServiceEnabled) {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
return {"position": position.toString()};
}
position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.medium,
forceAndroidLocationManager: true)
.timeout(Duration(seconds: 10));
์ด ์ฝ๋ ์กฐ๊ฐ์ ์ ์๊ฒ ํจ๊ณผ์ ์ด์์ต๋๋ค.
์ด๊ฒ์ ์ต์ํ์ ์ฌํ ๊ฐ๋ฅํ ์ค๋ฅ๋ฅผ ์์ฑํ๋ ค๋ ์๋์ ๋๋ค.
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
<strong i="6">@override</strong>
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: SafeArea(
child: Scaffold(body: GeoLocatorWidget()),
));
}
}
class GeoLocatorWidget extends StatefulWidget {
const GeoLocatorWidget({
Key key,
}) : super(key: key);
<strong i="7">@override</strong>
_GeoLocatorWidgetState createState() => _GeoLocatorWidgetState();
}
class _GeoLocatorWidgetState extends State<GeoLocatorWidget> {
StreamSubscription<Position> _streamSubscription;
String message = 'empty';
<strong i="8">@override</strong>
void initState() {
super.initState();
_streamSubscription = Geolocator.getPositionStream(
//desiredAccuracy: LocationAccuracy.medium,
distanceFilter: 500)
.listen(_onData, onError: _onError);
}
void _onData(Position position) {
ScaffoldState _scaffoldKey = Scaffold.of(context, nullOk: true);
if ((_scaffoldKey?.mounted ?? false)) _scaffoldKey.hideCurrentSnackBar();
setState(() {
message = 'latitude: ${position.latitude}, longitude: ${position.longitude}';
});
}
void _onError(dynamic error) {
bool geoService = error is LocationServiceDisabledException ||
error is PermissionDeniedException;
ScaffoldState _scaffoldKey = Scaffold.of(context, nullOk: true);
if (!(_scaffoldKey?.mounted ?? false)) return;
_scaffoldKey.hideCurrentSnackBar();
_scaffoldKey.showSnackBar(SnackBar(
content: Text('$error'),
duration: const Duration(minutes: 2),
action: geoService
? SnackBarAction(
label: 'Change',
onPressed: () async {
if (error is LocationServiceDisabledException) {
bool locationEnabled =
await Geolocator.isLocationServiceEnabled();
if (!locationEnabled) await Geolocator.openLocationSettings();
else setState(() {
message = '''
locationService is enabled but the error says
its of type LocationServiceDisabledException anyway :(
''';
});
} else await Geolocator.openAppSettings();
},
)
: null,
));
}
<strong i="9">@override</strong>
void dispose() {
_streamSubscription?.cancel();
super.dispose();
}
<strong i="10">@override</strong>
Widget build(BuildContext context) {
return Center(
child: Text(message),
);
}
}
AndroidManifest์ ๋ชจ๋ ๊ถํ ์ถ๊ฐ
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
LocationServiceDisabledException
)์ ์ค๋ต๋ฐ ์์
๋ฒํผ "๋ณ๊ฒฝ"์ด ์๋ ์ค๋ต๋ฐ๊ฐ ํ์๋ฉ๋๋ค.LocationServiceDisabledException
์ ํ์ ์ค๋ฅ๋ผ๋ ํ์ฑํ๋์ด ์์ผ๋ฉด Geolocator.openLocationSettings();
์ด๊ธฐ๋ฅผ ์๋ํฉ๋๋ค. ์ด ์ค๋ ๋์ ๋ฌธ์ ) ๊ทธ๋ฐ ๋ค์ ํ์ฑํ๋์์์ ์๋ฆฌ๋ ํ๋ฉด ํ
์คํธ๋ฅผ ๋ณ๊ฒฝํ๋ฉด ์ค์ ๋ก ์๋ฌด ๊ฒ๋ ํ ์ ์์ต๋๋ค.<strong i="5">@override</strong>
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.paused:
if (_streamSubscription != null) {
_streamSubscription.cancel();
_streamSubscription = null;
}
break;
case AppLifecycleState.resumed:
_streamSubscription ??= Geolocator.getPositionStream(
//desiredAccuracy: LocationAccuracy.medium,
distanceFilter: 500).listen(_onData, onError: _onError);
break;
default:
break;
}
}
์ฌ์ฉ์๊ฐ "๋ณ๊ฒฝ" ๋ฒํผ์ ํญํ๊ณ ์์น ์๋น์ค ์ค์ ์ผ๋ก ๋ฆฌ๋๋ ์ ๋๊ณ ์ด๋ฅผ ์ผ๊ณ ์ฑ์ผ๋ก ๋์๊ฐ๋ฉด ์ ๋๋ก ์๋ํ์ง๋ง ์ฌ์ฉ์๊ฐ ์ํ ํ์์ค(์คํธ๋ฆผ ๊ทธ ํ์ ๊ฐ ๋ฐํ์ ์ค์งํฉ๋๋ค).
๋ค๋ฅธ ์์ด๋์ด๋ cancelOnError: true
๋ฐ HandleError
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์คํธ๋ฆผ์ ์ผ๋ถ ์ค๋ฅ๋ฅผ ๊ฐ๋ก์ฑ๊ณ ๊ทธ๋ค์ง ์ค์ํ์ง ์์ง๋ง(์ฒ๋ฆฌํ ์ ์๋ ๊ฒ) LocationServiceDisabledException
๋ฐํํ๊ธฐ ๋๋ฌธ์ ์คํธ๋ฆผ์ ๋ซ๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๊ฒ์
๋๋ค. HandleError
๋ฅผ ์ธ์ , ์ธ์ ์ฐ๋ฉด ์ ๋๋์ง ๋ถ๊ฐํ๊ธฐ ์ด๋ ค์์.
Android 8.0.0์ด ์๋ก ์ค์น๋ ์ค์ ๊ธฐ๊ธฐ์์ ๋ ๋ค๋ฅธ ํ ์คํธ๋ฅผ ํ์ต๋๋ค.
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.$accuracy$,
).timeout(Duration(seconds: 10));
๊ฐ $accuracy$ ๊ฐ์ ๋ํ ๊ฒฐ๊ณผ:
| $์ ํ๋$ | ๊ฒฐ๊ณผ |
|----------|----------------------------- ------|
| ์ต์ | ์๊ฐ ์ด๊ณผ ์์ธ |
| ๋ฎ์ | ์์น ์๋น์ค ๋นํ์ฑํ ์์ธ |
| ๋งค์ฒด | ์์น ์๋น์ค ๋นํ์ฑํ ์์ธ |
| ๋์ | ์๊ฐ ์ด๊ณผ ์์ธ |
| ์ต๊ณ | ์์น ์๋น์ค ๋นํ์ฑํ ์์ธ |
| ๋ฒ ์คํธํฌ๋ด๋น๊ฒ์ด์
| ํ์์์ ์์ธ |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
๊ธฐ๊ธฐ ์์น ์ค์ : ๋์ ์ ํ๋(GPS, Wi-Fi ๋ฐ ๋ชจ๋ฐ์ผ ๋คํธ์ํฌ ์ฌ์ฉ)
์์ดํ์ด: ์ฐ๊ฒฐ๋จ
VPN: ์์
GPS ์ ํธ ๊ฐ๋: ํ๋ด์ธ์
์์น ์ ๋ณด: ์ผ์ง
์ต๊ทผ ์์น ์์ฒญ: Geolocation API๋ฅผ ํธ์ถํ ์ฑ ํ์
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํ๋ geolocator ํ๋ฌ๊ทธ์ธ ๋ฒ์ 6.1.10์ ๋ฐฉ๊ธ ์ถ์ํ์ต๋๋ค.
Android์์ onLocationAvailability
์ฝ๋ฐฑ ๋ฉ์๋๋ ์์น ์๋น์ค๊ฐ ๋นํ์ฑํ๋์์ ๋ ๋ฟ๋ง ์๋๋ผ ์์น๋ฅผ ์ฌ์ฉํ ์ ์๋ค๊ณ ์์ฃผ ๋ณด๊ณ ํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ ๋ฏธ์ธ ์กฐ์ ํ์ผ๋ฉฐ ๋ ์ด์ ์๋ชป๋ LocationServiceDisabledException
์์ธ๊ฐ ๋ฐ์ํ์ง ์์์ผ ํฉ๋๋ค.
๋ฌธ์ ๋ฅผ ๋ณด๊ณ ํ๊ณ , ๋ช ํํ ํ๊ณ , ์ฌํํ๋ ๋ฐ ๋์์ ์ฃผ์ ๋ชจ๋ ๋ถ๋ค๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
๋๋ ๊ฐ์ ์ค๋ฅ๊ฐ ์์ต๋๋ค. ๋๋ xiaomi Redmi Note 8์์ ๊ทธ๊ฒ์ ์ฌํํ์ง๋ง huawei p20 lite์์๋ ์ ์๋ํฉ๋๋ค.
xiaomi์์ ์๋น์ค๊ฐ ๋นํ์ฑํ๋๋ฉด ๋ค์ ๋ฉ์๋๊ฐ true๋ฅผ ๋ฐํํ๊ณ huawei์์์ ๋ง์ฐฌ๊ฐ์ง๋ก false๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค.
ํ๋ฌ๊ทธ์ธ ๋ฒ์ : geolocator: ^6.1.13
Geolocator.isLocationServiceEnabled()๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
@sejr1996 ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก Nokia 3.1(android 9), Galaxy A10s(android 10) ๋ฒ์ 6.1.13์์ ๋์ผํ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ์ต๋๋ค.
The location service on the device is disabled.
at MethodChannelGeolocator._handlePlatformException(MethodChannelGeolocator.java:192)
at MethodChannelGeolocator.<fn>(MethodChannelGeolocator.java:171)
@sejr1996 ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก Nokia 3.1(android 9), Galaxy A10s(android 10) ๋ฒ์ 6.1.13์์ ๋์ผํ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ์ต๋๋ค.
The location service on the device is disabled. at MethodChannelGeolocator._handlePlatformException(MethodChannelGeolocator.java:192) at MethodChannelGeolocator.<fn>(MethodChannelGeolocator.java:171)
๋๋ ๋๊ฐ์ด ๋ฐ๊ณ ์๋ค
๋๋ ๊ทธ๊ฒ์ด ์ด๋ฏธ ํด๊ฒฐ๋์๋ค๊ณ ๋ฏฟ์ต๋๋ค. ์๋น์ค ์์น๋ฅผ ์์ ํ๊ธฐ ์ํ ๋ง์ง๋ง ์๋จ์ ์์น ํจํค์ง๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ์๋ก์ด ๋ฒ์ ์ geolocator ํจํค์ง๊ฐ ์์ต๋๋ค. ์์น ๊ถํ์ด ๋จผ์ ์ค๊ณ ์๋น์ค ์์น๊ฐ ๋ฐ๋ฆ ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํ๋ geolocator ํ๋ฌ๊ทธ์ธ ๋ฒ์ 6.1.10์ ๋ฐฉ๊ธ ์ถ์ํ์ต๋๋ค.
Android์์
onLocationAvailability
์ฝ๋ฐฑ ๋ฉ์๋๋ ์์น ์๋น์ค๊ฐ ๋นํ์ฑํ๋์์ ๋ ๋ฟ๋ง ์๋๋ผ ์์น๋ฅผ ์ฌ์ฉํ ์ ์๋ค๊ณ ์์ฃผ ๋ณด๊ณ ํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ ๋ฏธ์ธ ์กฐ์ ํ์ผ๋ฉฐ ๋ ์ด์ ์๋ชป๋LocationServiceDisabledException
์์ธ๊ฐ ๋ฐ์ํ์ง ์์์ผ ํฉ๋๋ค.๋ฌธ์ ๋ฅผ ๋ณด๊ณ ํ๊ณ , ๋ช ํํ ํ๊ณ , ์ฌํํ๋ ๋ฐ ๋์์ ์ฃผ์ ๋ชจ๋ ๋ถ๋ค๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค.