Reputation: 1088
I am new to flutter and trying to get current location lat and long from my mobile app, for that I am using location 1.4.1, and also found this example which I mentioned in the below link, I did how exactly how they mentioned step by step process but still its throwing errors.
Exception has occurred.
PlatformException(PERMISSION_DENIED, The user explicitly denied the use of location services for this app or location services are currently disabled in Settings., null)
This is the exception I am getting when I run my code, but there is a try catch for PlatformException in that example.I got stuck here, please help me out and thanks.
My AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.latlong">
<!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="lat_long"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
main.dart:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:location/location.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
Map<String, double> _startLocation;
Map<String, double> _currentLocation;
StreamSubscription<Map<String, double>> _locationSubscription;
Location _location = new Location();
bool _permission = false;
String error;
bool currentWidget = true;
Image image1;
@override
void initState() {
super.initState();
initPlatformState();
_locationSubscription =
_location.onLocationChanged().listen((Map<String,double> result) {
setState(() {
_currentLocation = result;
});
});
}
// Platform messages are asynchronous, so we initialize in an async method.
initPlatformState() async {
Map<String, double> location;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
_permission = await _location.hasPermission();
location = await _location.getLocation();
error = null;
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
} else if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
error = 'Permission denied - please ask the user to enable it from the app settings';
}
location = null;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
//if (!mounted) return;
setState(() {
_startLocation = location;
});
}
@override
Widget build(BuildContext context) {
List<Widget> widgets;
if (_currentLocation == null) {
widgets = new List();
} else {
widgets = [
new Image.network(
"https://maps.googleapis.com/maps/api/staticmap?"+
"center=${_currentLocation["latitude"]},${_currentLocation["longitude"]}"+
"&zoom=18&size=640x400&key=xxxxxxxxxxx")
];
}
widgets.add(new Center(
child: new Text(_startLocation != null
? 'Start location: $_startLocation\n'
: 'Error: $error\n')));
widgets.add(new Center(
child: new Text(_currentLocation != null
? 'Continuous location: $_currentLocation\n'
: 'Error: $error\n')));
widgets.add(new Center(
child: new Text(_permission
? 'Has permission : Yes'
: "Has permission : No")));
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('Location plugin example app'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: widgets,
)));
}
}
and my pubspec.yaml :
name: lat_long
description: A new Flutter project.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
location: ^1.4.1
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.io/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.io/custom-fonts/#from-packages
Upvotes: 1
Views: 22432
Reputation: 9
Please do not forget to check if you activated the geolocalisation on the phone
Upvotes: 0
Reputation: 51
I was facing the same problem with few android devices. But I have found a soution for it -
All you need to do is set the value of Geolocator()..forceAndroidLocationManager = true.
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager = true;
Upvotes: 5
Reputation: 166
I noticed that you added both the ACCESS_FINE_LOCATION
and ACCESS_COARSE_LOCATION
permissions to your Android manifest file. You are expected to use one or the other but not both. See the docs.
Upvotes: 1
Reputation: 103
I was having a similar issue, then i found that it is a compilation issue, and the app had already denied to use location services, you need to run the following command in the terminal, then you app will ask you again if you want to use location services:
flutter clean
Upvotes: 2
Reputation: 3449
You just had the wrong order of things as you were trying to access the location/permissions before you actually got them.
Remove the onLocationChanged()
subscription from your initState()
and change your try
statement in your initPlatformState()
to this:
try {
location = await _location.getLocation();
_permission = await _location.hasPermission();
_locationSubscription =
_location.onLocationChanged().listen((Map<String,double> result) {
setState(() {
_currentLocation = result;
});
});
error = null;
}
Note the swapping of you getting the location and checking if you have permission lines.
Edit: added full code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:location/location.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
Map<String, double> _startLocation;
Map<String, double> _currentLocation;
StreamSubscription<Map<String, double>> _locationSubscription;
Location _location = new Location();
bool _permission = false;
String error;
bool currentWidget = true;
Image image1;
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
initPlatformState() async {
Map<String, double> location;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
location = await _location.getLocation();
_permission = await _location.hasPermission();
_locationSubscription =
_location.onLocationChanged().listen((Map<String,double> result) {
setState(() {
_currentLocation = result;
});
});
error = null;
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
} else if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
error = 'Permission denied - please ask the user to enable it from the app settings';
}
location = null;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
//if (!mounted) return;
setState(() {
_startLocation = location;
});
}
@override
Widget build(BuildContext context) {
List<Widget> widgets;
if (_currentLocation == null) {
widgets = new List();
} else {
widgets = [
new Image.network(
"https://maps.googleapis.com/maps/api/staticmap?"+
"center=${_currentLocation["latitude"]},${_currentLocation["longitude"]}"+
"&zoom=18&size=640x400&key=AIzaSyBw_T2wCQGqWBEdF4UzMAuoQX_DCemYpQw")
];
}
widgets.add(new Center(
child: new Text(_startLocation != null
? 'Start location: $_startLocation\n'
: 'Error: $error\n')));
widgets.add(new Center(
child: new Text(_currentLocation != null
? 'Continuous location: $_currentLocation\n'
: 'Error: $error\n')));
widgets.add(new Center(
child: new Text(_permission
? 'Has permission : Yes'
: "Has permission : No")));
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('Location plugin example app'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: widgets,
)));
}
}
Upvotes: 2