flutter how to fix permission handler error - flutter

I dont know how to resolve this red error part.
I copied this from internet then i got this error.
please help me to solve this.
This is my full code.
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:android_intent/android_intent.dart';
import 'package:geolocator/geolocator.dart';
class AskForPermission extends StatefulWidget {
#override
_AskForPermissionState createState() => _AskForPermissionState();
}
class _AskForPermissionState extends State<AskForPermission> {
final PermissionHandler permissionHandler = PermissionHandler();
Map<PermissionGroup, PermissionStatus>? permissions;
void initState() {
super.initState();
requestLocationPermission();
_gpsService();
}
Future<bool> _requestPermission(PermissionGroup permission) async {
final PermissionHandler _permissionHandler = PermissionHandler();
var result = await _permissionHandler.requestPermissions([permission]);
if (result[permission] == PermissionStatus.granted) {
return true;
}
return false;
}
/*Checking if your App has been Given Permission*/
Future<bool> requestLocationPermission({Function? onPermissionDenied}) async {
var granted = await _requestPermission(PermissionGroup.location);
if (granted!=true) {
requestLocationPermission();
}
debugPrint('requestContactsPermission $granted');
return granted;
}
/*Show dialog if GPS not enabled and open settings location*/
Future _checkGps() async {
if (!(await Geolocator.isLocationServiceEnabled())) {
if (Theme.of(context).platform == TargetPlatform.android) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Can't get gurrent location"),
content:const Text('Please make sure you enable GPS and try again'),
actions: <Widget>[
FlatButton(child: Text('Ok'),
onPressed: () {
final AndroidIntent intent = AndroidIntent(
action: 'android.settings.LOCATION_SOURCE_SETTINGS');
intent.launch();
Navigator.of(context, rootNavigator: true).pop();
_gpsService();
})],
);
});
}
}
}
/*Check if gps service is enabled or not*/
Future _gpsService() async {
if (!(await Geolocator.isLocationServiceEnabled())) {
_checkGps();
return null;
} else
return true;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Ask for permisions'),
backgroundColor: Colors.red,
),
body: Center(
child: Column(
children: <Widget>[
Text("All Permission Granted"),
],
))
);
}
}

I got the same problem - the code that worked with permission_handler ^8.0.0+2 didn't work anymore after I upgraded to ^8.3.0 - the code wouldn't compile, the Permission and the other classes where not "found" anymore (I use VS Code)
I fixed it by cleaning the pub cache:
flutter pub cache clean
and afterwards just get again the dependencies:
flutter pub get
PS: for upgrading to 8.3.0, I set targetSdkVersion and compileSdkVersion to 31 into build.gradle file

Install permission handler package from here. Then in your .dart file add import and call permission asking function somewhere. E.g. function like this asks for storage permission.
import 'package:permission_handler/permission_handler.dart';
Future<void> getStoragePermission() async {
if (await Permission.manageExternalStorage.request().isGranted) {
setState(() {});
} else if (await Permission.storage.request().isPermanentlyDenied) {
await openAppSettings();
} else if (await Permission.storage.request().isDenied) {
setState(() {});
}
}

Please refer to below code
https://pub.dev/packages/permission_handler/install
permission_handler: ^5.0.1+1
import 'package:permission_handler/permission_handler.dart';
import 'package:google_fonts/google_fonts.dart';
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Color(0xfff00B074),
textTheme: const TextTheme(
bodyText1: TextStyle(
fontSize: 18.0,
fontFamily: 'Barlow-Medium',
color: Color(0xff464255)),
),
),
home: PermissionHandlerScreen(),
);
}
}
class PermissionHandlerScreen extends StatefulWidget {
#override
_PermissionHandlerScreenState createState() =>
_PermissionHandlerScreenState();
}
class _PermissionHandlerScreenState extends State<PermissionHandlerScreen> {
#override
void initState() {
super.initState();
permissionServiceCall();
}
permissionServiceCall() async {
await permissionServices().then(
(value) {
if (value != null) {
if (value[Permission.storage].isGranted &&
value[Permission.camera].isGranted &&
value[Permission.microphone].isGranted) {
/* ========= New Screen Added ============= */
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => SplashScreen()),
);
}
}
},
);
}
/*Permission services*/
Future<Map<Permission, PermissionStatus>> permissionServices() async {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
Permission.camera,
Permission.microphone,
//add more permission to request here.
].request();
if (statuses[Permission.storage].isPermanentlyDenied) {
openAppSettings();
setState(() {});
} else {
if (statuses[Permission.storage].isDenied) {
permissionServiceCall();
}
}
if (statuses[Permission.microphone].isPermanentlyDenied) {
openAppSettings();
setState(() {});
} else {
if (statuses[Permission.microphone].isDenied) {
permissionServiceCall();
}
}
if (statuses[Permission.camera].isPermanentlyDenied) {
openAppSettings();
setState(() {});
} else {
if (statuses[Permission.camera].isDenied) {
permissionServiceCall();
}
}
/*{Permission.camera: PermissionStatus.granted, Permission.storage: PermissionStatus.granted}*/
return statuses;
}
#override
Widget build(BuildContext context) {
permissionServiceCall();
return WillPopScope(
onWillPop: () {
SystemNavigator.pop();
},
child: Scaffold(
body: Container(
child: Center(
child: InkWell(
onTap: () {
permissionServiceCall();
},
child: Text("Click here to enable Enable Permission Screen")),
),
),
),
);
}
}
class SplashScreen extends StatelessWidget {
const SplashScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
SystemNavigator.pop();
},
child: Scaffold(
body: Center(
child: Text(
"Splash Screen",
),
),
),
);
}
}

Add permission_handler dependency in your pubspec.yaml file.
Try the flutter pub get command. If already done, then refer to this link about the permission handler package.

Related

App can't log back in when logging out using getx

I getx to do google login but when I log out and log back in, it gives an error of null value at Mydashboard and stop at get_state, this delete my controller but don't create again.
My Root screen
class Root extends StatelessWidget {
const Root({super.key});
#override
Widget build(BuildContext context) {
Config().init(context);
return Scaffold(
body: GetBuilder<AuthController>(builder: (builder) {
return Center(
child: builder.isSignedIn.value ? MyDashBoard() : const LoginScreen(),
);
}),
);
}
}
and funtion logout
void signout() async {
try {
await auth.signOut();
await _googleSignIn.signOut();
displayName = '';
isSignedIn.value = false;
update();
Get.offAll(() => const Root());
} catch (e) {
Get.snackbar('Error occured!', e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: kBackgroundColor);
}
and here Debug Console
debugconsole
My dashboardbinding
class DashboarBindings extends Bindings {
#override
void dependencies() {
Get.lazyPut<DashBoarController>(() => DashBoarController());
Get.lazyPut<QrScannerScreenController>(() => QrScannerScreenController());
Get.lazyPut<TakePhotoScreenController>(() => TakePhotoScreenController());
Get.lazyPut<ReportScreenController>(() => ReportScreenController());
Get.lazyPut<TranslateController>(() => TranslateController());
}
}
and here my dashboar
dashboarscreen

How to move classes and functions to a separate file in Flutter/Dart?

Good day! I am new to Flutter/Dart. And the more I experiment, the bigger my main file gets. Obviously, I need a separate file in which I will store all the classes and functions that I will refer to in the future.
I have a separate screen with what I need. Here is its code:
//Internet route
class InternetRoute extends StatefulWidget {
const InternetRoute({Key? key}) : super(key: key);
#override
State<InternetRoute> createState() => _InternetRouteState();
}
class _InternetRouteState extends State<InternetRoute> {
bool ActiveConnection = false;
String T = "";
Future CheckUserConnection() async {
try {
final result = await InternetAddress.lookup('example.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
setState(() {
ActiveConnection = true;
T = "Turn off the data and repress again";
});
}
} on SocketException catch (_) {
setState(() {
ActiveConnection = false;
T = "Turn On the data and repress again";
showInternetDialog(context);
});
}
}
#override
void initState() {
CheckUserConnection();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("GeeksforGeeks"),
),
body: Column(
children: [
Text("Active Connection? $ActiveConnection"),
const Divider(),
Text(T),
OutlinedButton(
onPressed: () {
CheckUserConnection();
},
child: const Text("Check"))
],
),
);
}
}
//Alert Dialog about Internet connection
showInternetDialog(BuildContext context) {
// set up the button
Widget okButton = Center(
child: TextButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
},
),
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
// title: Text("My title"),
content: Text("Internet connection required"),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
I want to create a my classes.dart file that will gradually populate with the most commonly used things. In particular, I need class _InternetRouteState and showInternetDialog.
How to transfer them to a new file? I completely copied the code of that screen. Is it correct? Would that be enough to then refer to them in main.dart (after import)? Will all their variables be visible to my screens as well?
Edit 1. I don't know how I can move CheckUserConnection to my file. I mean I took the piece of code I needed and wrapped it in the CheckUserConnection class (in my separate file), but it doesn't work. What am I doing wrong?
class CheckUserConnection {
bool ActiveConnection = false;
String T = "";
Future CheckUserConnection() async {
try {
final result = await InternetAddress.lookup('example.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
setState(() {
ActiveConnection = true;
T = "Turn off the data and repress again";
});
}
} on SocketException catch (_) {
setState(() {
ActiveConnection = false;
T = "Turn On the data and repress again";
// showInternetDialog(context); //temporary
});
}
}
}
The Problems tab shows the following errors:
Constructors can't have a return type.
The modifier 'async' can't be applied to the body of a constructor.
The await expression can only be used in an async function.
The method 'setState' isn't defined for the type 'CheckUserConnection'.
The method 'setState' isn't defined for the type 'CheckUserConnection'.
Create a new dart file. Name it internet_dialog_handler.dart. Add this to the file
class InternetDialogHandler{
//Alert Dialog about Internet connection
showInternetDialog(BuildContext context) {
// set up the button
Widget okButton = Center(
child: TextButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
},
),
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
// title: Text("My title"),
content: Text("Internet connection required"),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
In internetRoute use this
//Internet route
class InternetRoute extends StatefulWidget {
const InternetRoute({Key? key}) : super(key: key);
#override
State<InternetRoute> createState() => _InternetRouteState();
}
class _InternetRouteState extends State<InternetRoute> {
bool ActiveConnection = false;
String T = "";
InternetDialogHandler _internetDialogHandler = InternetDialogHandler();
Future CheckUserConnection() async {
try {
final result = await InternetAddress.lookup('example.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
setState(() {
ActiveConnection = true;
T = "Turn off the data and repress again";
});
}
} on SocketException catch (_) {
setState(() {
ActiveConnection = false;
T = "Turn On the data and repress again";
//Use the variable here to access the method in that class
_internetDialogHandler.showInternetDialog(context);
});
}
}
#override
void initState() {
CheckUserConnection();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("GeeksforGeeks"),
),
body: Column(
children: [
Text("Active Connection? $ActiveConnection"),
const Divider(),
Text(T),
OutlinedButton(
onPressed: () {
CheckUserConnection();
},
child: const Text("Check"))
],
),
);
}
}
EDIT
class CheckUserConnection {
Future checkInternetAvailability() async {
try {
final result = await InternetAddress.lookup('example.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
return true;
}
} on SocketException catch (_) {
return false;
}
}
}
Use a different name for the method. Same name is used to defined the constructor of the class. Also make it work independent. Just return a true or false. Now to use this define a variable of type checkUserConnection
CheckUserConnection _checkUserConnection = CheckUserConnection();
bool _internetAvailable = await _checkUserConnection.checkInternetAvailability();
if(_internetAvailable)
{
//do something here;
} else{
//handle no internet here
}

Flutter background service in custome time fireing function

I should implement feature which should fires function in every 10 seconds in the the background and I had tried out work manager but it minimal time is 15 min but I want 10 seconds and I cant find any packages or good example for it ,
dependencies:
flutter_background_service: ^0.2.4
Example:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
initializeService();
runApp(MyApp());
}
Future<void> initializeService() async {
final service = FlutterBackgroundService();
await service.configure(
androidConfiguration: AndroidConfiguration(
// this will executed when app is in foreground or background in separated isolate
onStart: onStart,
// auto start service
autoStart: true,
isForegroundMode: true,
),
iosConfiguration: IosConfiguration(
// auto start service
autoStart: true,
// this will executed when app is in foreground in separated isolate
onForeground: onStart,
// you have to enable background fetch capability on xcode project
onBackground: onIosBackground,
),
);
}
// to ensure this executed
// run app from xcode, then from xcode menu, select Simulate Background Fetch
void onIosBackground() {
WidgetsFlutterBinding.ensureInitialized();
print('FLUTTER BACKGROUND FETCH');
}
void onStart() {
WidgetsFlutterBinding.ensureInitialized();
final service = FlutterBackgroundService();
service.onDataReceived.listen((event) {
if (event!["action"] == "setAsForeground") {
service.setForegroundMode(true);
return;
}
if (event["action"] == "setAsBackground") {
service.setForegroundMode(false);
}
if (event["action"] == "stopService") {
service.stopBackgroundService();
}
});
// bring to foreground
service.setForegroundMode(true);
Timer.periodic(Duration(seconds: 1), (timer) async {
if (!(await service.isServiceRunning())) timer.cancel();
service.setNotificationInfo(
title: "My App Service",
content: "Updated at ${DateTime.now()}",
);
service.sendData(
{"current_date": DateTime.now().toIso8601String()},
);
});
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String text = "Stop Service";
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Service App'),
),
body: Column(
children: [
StreamBuilder<Map<String, dynamic>?>(
stream: FlutterBackgroundService().onDataReceived,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
final data = snapshot.data!;
DateTime? date = DateTime.tryParse(data["current_date"]);
return Text(date.toString());
},
),
ElevatedButton(
child: Text("Foreground Mode"),
onPressed: () {
FlutterBackgroundService()
.sendData({"action": "setAsForeground"});
},
),
ElevatedButton(
child: Text("Background Mode"),
onPressed: () {
FlutterBackgroundService()
.sendData({"action": "setAsBackground"});
},
),
ElevatedButton(
child: Text(text),
onPressed: () async {
final service = FlutterBackgroundService();
var isRunning = await service.isServiceRunning();
if (isRunning) {
service.sendData(
{"action": "stopService"},
);
} else {
service.start();
}
if (!isRunning) {
text = 'Stop Service';
} else {
text = 'Start Service';
}
setState(() {});
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
FlutterBackgroundService().sendData({
"hello": "world",
});
},
child: Icon(Icons.play_arrow),
),
),
);
}
}
you can use background_fetch, it a good lib for this propose.

How to keep asking location permission as long as the status is not granted-Flutter

I am trying to ask location permission of user in my project apps, so after user denied the permission I would like to keep showing pop up to ask location permission whenever user try to access a menu. I success to do that by using this function
trial() async {
await Permission.locationAlways.request();
print(Permission.locationAlways.status.then((value) {
print("value:$value");
}));
}
but the problem is.. after the status is PermissionStatus.permanentlyDenied the pop up to ask location permission is stop showing. Is there a way to always ask permission as long as the permission is not granted or a way to open up setting of location permission?
you can use the permission_handler 8.3.0 package.
and use as:
if (await Permission.locationAlways.request().isGranted) {
print(Permission.locationAlways.status.then((value) {
print("value:$value");
}));
}
more details on: permission_handler
implementation on: implementation on
Please refer to below code
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Color(0xfff00B074),
textTheme: const TextTheme(
bodyText1: TextStyle(
fontSize: 18.0,
fontFamily: 'Barlow-Medium',
color: Color(0xff464255)),
),
),
home: PermissionHandlerScreen(),
);
}
}
class PermissionHandlerScreen extends StatefulWidget {
#override
_PermissionHandlerScreenState createState() =>
_PermissionHandlerScreenState();
}
class _PermissionHandlerScreenState extends State<PermissionHandlerScreen> {
#override
void initState() {
super.initState();
permissionServiceCall();
}
permissionServiceCall() async {
await permissionServices().then(
(value) {
if (value != null) {
if (value[Permission.location].isGranted ) {
/* ========= New Screen Added ============= */
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => SplashScreen()),
);
}
}
},
);
}
/*Permission services*/
Future<Map<Permission, PermissionStatus>> permissionServices() async {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
//add more permission to request here.
].request();
if (statuses[Permission.location].isPermanentlyDenied) {
await openAppSettings().then(
(value) async {
if (value) {
if (await Permission.location.status.isPermanentlyDenied == true &&
await Permission.location.status.isGranted == false) {
// openAppSettings();
permissionServiceCall(); /* opens app settings until permission is granted */
}
}
},
);
} else {
if (statuses[Permission.location].isDenied) {
permissionServiceCall();
}
}
/*{Permission.camera: PermissionStatus.granted, Permission.storage: PermissionStatus.granted}*/
return statuses;
}
#override
Widget build(BuildContext context) {
permissionServiceCall();
return WillPopScope(
onWillPop: () {
SystemNavigator.pop();
},
child: Scaffold(
body: Container(
child: Center(
child: InkWell(
onTap: () {
permissionServiceCall();
},
child: Text("Click here to enable Enable Permission Screen")),
),
),
),
);
}
}
class SplashScreen extends StatelessWidget {
const SplashScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
SystemNavigator.pop();
},
child: Scaffold(
body: Center(
child: Text(
"Splash Screen",
),
),
),
);
}
}

How to get state changed value after widget build?

I have simple application where I work with user location. On first app open I will ask from user to allow location and then save to var. But when I try check inside widget location allow status it is return old value instance of changed value.
Code
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:yandex_mapkit/yandex_mapkit.dart';
import 'package:permission_handler/permission_handler.dart';
class PlacesListScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return _Map();
}
}
class _Map extends StatefulWidget {
#override
_MapState createState() => _MapState();
}
class _MapState extends State<_Map> {
YandexMapController controller;
PermissionStatus _permissionStatus = PermissionStatus.undetermined;
#override
void initState() {
super.initState();
_requestPermission();
}
Future<void> _requestPermission() async {
Map<Permission, PermissionStatus> permissions =
await [Permission.location].request();
setState(() {
_permissionStatus = permissions[Permission.location];
});
}
void _showMessage(BuildContext context, Text text) {
final ScaffoldState scaffold = Scaffold.of(context);
scaffold.showSnackBar(
SnackBar(
content: text,
action: SnackBarAction(
label: 'OK', onPressed: scaffold.hideCurrentSnackBar),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App Name'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: null,
),
],
),
body: Text('App Content'),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () async {
if (_permissionStatus == PermissionStatus.granted) {
await Future.wait([
controller.moveToUser(),
controller.showUserLayer(
iconName: 'lib/assets/arrow.png',
arrowName: 'lib/assets/user_location1.png',
accuracyCircleFillColor: Colors.green.withOpacity(0.5),
)
]);
} else {
_showMessage(context, const Text('Permission Denied'));
}
},
child: Icon(Icons.place, color: Colors.white),
backgroundColor: Colors.green,
heroTag: 'showUserLocation',
),
],
),
);
}
}
Using FloatingActionButton I tried check Permission status in my code. But my var _permissionStatus doesn't updated when user allowed location. How to fix this problem and get changed value from state?
You can use this package: https://pub.dev/packages/location
and then you can read the permission status:
Location location = new Location();
PermissionStatus _permissionGranted;
_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.granted) {
return;
}
}
another way:
location.hasPermision().then(PermissionStatus status){
if (_permissionGranted == PermissionStatus.denied){
location.requestPermission().then((PermissionStatus requestStatus){
// save the value
}
);
}
});
You need to know when user grand the permission then you know it, you must use the wrap your widget with FocusScope like this:
first define this:
final _focusNode = FocusScopeNode();
then wrap it with this:
return FocusScope(
node: _focusNode,
child: WillPopScope(
onWillPop: () async {
_requestPermission();
},.....