How do I use a method defined in another code section in the same file?
import 'package:flutter/material.dart';
import 'package:flutter_web3/flutter_web3.dart';
class MetamaskProvider extends ChangeNotifier {
static const operationChain = 4;
String currentAddress = '';
int currentChain = -1;
bool get isEnabled => ethereum != null;
bool get isInOperatingChain => currentChain == operationChain;
bool get isConnected => isEnabled && currentAddress.isNotEmpty;
Future<void> connect() async {
if (isEnabled) {
final accs = await ethereum!.requestAccount();
if (accs.isNotEmpty) currentAddress = accs.first;
currentChain = await ethereum!.getChainId();
notifyListeners();
}
void clear() {
currentAddress = '';
currentChain = -1;
}
}
init() {
if (isEnabled) {
ethereum!.onAccountsChanged((accounts) {
clear();
});
ethereum!.onAccountsChanged((accounts) {
clear();
});
}
}
}
error thrown when trying to use the "clear" method: The method 'clear' isn't defined for the type 'MetamaskProvider'.
You have to move the method clear() from connect() method to outside of it. Then, you will be able to access clear() inside init().
class MetamaskProvider extends ChangeNotifier {
static const operationChain = 4;
String currentAddress = '';
int currentChain = -1;
bool get isEnabled => ethereum != null;
bool get isInOperatingChain => currentChain == operationChain;
bool get isConnected => isEnabled && currentAddress.isNotEmpty;
void clear() {
currentAddress = '';
currentChain = -1;
}
Future<void> connect() async {
if (isEnabled) {
final accs = await ethereum!.requestAccount();
if (accs.isNotEmpty) currentAddress = accs.first;
currentChain = await ethereum!.getChainId();
notifyListeners();
}
}
init() {
if (isEnabled) {
ethereum!.onAccountsChanged((accounts) {
clear();
});
ethereum!.onAccountsChanged((accounts) {
clear();
});
}
}
}
I am currently making a maps page and I need to get the user's current location and pass it into google maps. I am using GetX. However I am currently getting an error about type 'Future<dynamic>' is not a subtype of type 'LatLng' and I do not know what to do to fix this. Essentially I just want to get the user's location and pass it in to a GoogleMap as initial camera position.
Here is my controller:
class LocationController extends GetxController {
static LocationController instance = Get.find();
#override
void onReady() {
super.onReady();
getlocation();
}
getlocation() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
await Geolocator.openLocationSettings();
return Future.error("location service is not enabled");
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
//do stuff here
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
//stuff
return Future.error("location permissions denied");
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error("location permissions permanently denied");
}
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
//position stream?
}
}
This is the code for the map page:
class MapPage extends StatefulWidget {
const MapPage({super.key});
#override
State<MapPage> createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: locationController.getlocation(), zoom: 16),
minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
zoomGesturesEnabled: true,
cameraTargetBounds: CameraTargetBounds(
LatLngBounds(
northeast: LatLng(43.7970928, -79.3067414),
southwest: LatLng(43.592580, -79.483674),
),
),
),
),
],
),
);
}
}
try this
// create a class for location also handle permission
class PermissionToUser {
static Future permissionForLocation() async {
final request = await [Permission.location].request();
log(request[Permission.location].toString());
final status = await Permission.location.status;
if (status.isDenied) {
request;
return false;
} else if (status.isRestricted) {
request;
return false;
} else if (status.isLimited) {
request;
return false;
} else {
return true;
}
}
static Future<Position>? determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
}
}
As per use on the controller
class LocationController extends GetxController {
/// Declare the postion also the lat long just for example
late Position? posinitial;
final lat = 0.0.obs, lng = 0.0.obs;
#override
void onInit() async {
/// Run through here
await PermissionToUser.permissionForLocation().then((value) async {
posinitial = await PermissionToUser.determinePosition();
}).whenComplete(() {
getPositionData();
});
super.onInit();
}
getPositionData() async{
// try to log the data if its not empty
if (posinitial != null) {
log("${posinitial!.latitude}",name:"latitude");
log("${posinitial!.longitude}",name:"longtitude");
/// just pass this to ui to use
lat(posinitial!.latitude);
long(posinitial!.longitude);
}
}
}
as for the googgle map you can call the postion
posinitial != null ?
GoogleMap(
initialCameraPosition: CameraPosition(
/// you can use the lat long that was declared on the controller
/// anyways many ways to do it.
target: LatLng(controller.posinitial!.latitude, controller.posinitial!.longitude), zoom: 16),
minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
zoomGesturesEnabled: true,
cameraTargetBounds: CameraTargetBounds(
LatLngBounds(
northeast: LatLng(43.7970928, -79.3067414),
southwest: LatLng(43.592580, -79.483674),
),
),
) : const SizedBox.shrink(),
I think you should create a seperate variable like this :
In controller, I created a Position type var myLocation and storing my location in it.
static LocationController instance = Get.find();
late Position myLocation;
#override
void onInit() {
super.onInit();
getlocation();
}
getlocation() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
await Geolocator.openLocationSettings();
return Future.error("location service is not enabled");
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
//do stuff here
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
//stuff
return Future.error("location permissions denied");
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error("location permissions permanently denied");
}
myLocation = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
//position stream?
}
and the GoogleMap widget should be like:
GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(
locationController.myLocation.latitude,
locationController.myLocation.longitude ),
zoom: 16),
minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
zoomGesturesEnabled: true,
cameraTargetBounds: CameraTargetBounds(
LatLngBounds(
northeast: LatLng(43.7970928, -79.3067414),
southwest: LatLng(43.592580, -79.483674),
),
),
Future<bool> checkConnection() async {
var connectivityResult = await (Connectivity().checkConnectivity());
bool connOk = false;
if (connectivityResult == ConnectivityResult.mobile) {
bool ii = await checkConnectionWithUrl();
if (ii == true) {
connOk = true;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
bool ii = await checkConnectionWithUrl();
if (ii == true) {
connOk = true;
}
} else if (connectivityResult == ConnectivityResult.ethernet) {
bool ii = await checkConnectionWithUrl();
if (ii == true) {
connOk = true;
}
} else if (connectivityResult == ConnectivityResult.bluetooth) {
bool ii = await checkConnectionWithUrl();
if (ii == true) {
connOk = true;
}
} else {
connOk = false;
}
return connOk;
}
Future<bool> checkConnectionWithUrl() async {
bool response = false;
while (true) {
var checkin = await client.get(Uri.https('www.google.com', '/'));
if (checkin.statusCode == 200) {
response = true;
break;
} else {
sleep(const Duration(milliseconds: 500));
}
}
return response;
}
Stream checkStream() async* {
dynamic result = false;
while (true) {
try {
result = await checkConnection();
} catch (error) {
result = false;
} finally {
yield result;
}
await Future.delayed(const Duration(seconds: 1));
}
}
I am making a app. And I want to learn multi threading in dart. The above function what it will do is it look for wifi state every second and update the Ui. But when I run the function it will drop frams in ui. So I what to run it in a diffrent thread. can i do it.
---My main goal ---
I want to run this function in a different thread how do I do it
I'm using geolocator and google_maps_flutter in my app to get user location, passing by getPositionStream.
The Map is the first screen of the app, and when I get user location it work fine, and the camera of the map zoom correctly.
But the user can login to his account, and it's recreated the Map. And my problem is here. When the login is done, my stream with my new location is not listen :/ I need to reload the app for that
My function in my viewModel
final Stream<Position>? stream = await _locationService.getLocation();
if (stream != null) {
stream.listen((location) async {
final newLocation =
CameraPosition(target: LatLng(location.latitude, location.longitude), zoom: 15);
if (controllerCompleter != null) {
final GoogleMapController controller = await controllerCompleter.future;
controller.animateCamera(CameraUpdate.newCameraPosition(newLocation));
}
});
}
In the locationService:
Future<Stream<Position>?> getLocation() async {
bool _serviceEnabled;
LocationPermission _permissionGranted;
_serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!_serviceEnabled) {
return null; // Use France's GPS coordinates by default
}
_permissionGranted = await Geolocator.checkPermission();
if (_permissionGranted == LocationPermission.denied) {
_permissionGranted = await Geolocator.requestPermission();
if (_permissionGranted == LocationPermission.denied ||
_permissionGranted == LocationPermission.deniedForever) {
return null; // Use France's GPS coordinates by default
} else {
return Geolocator.getPositionStream(locationSettings: locationSettings);
}
} else {
return Geolocator.getPositionStream(locationSettings: locationSettings);
}
}
If anyone have an idea of what I'm doing wrong.
Thanks in advance
I am new to flutter, I want to check whether the internet is available or not and based on the condition, the screen has to change. I have written the code below (screen switch is working properly), but I am not able to get bool output(internet). When I removed the Future in check internet class, it throws an error. Can you please solve the issue:
class _ScreenState extends State<ChannelScreen> {
bool isInternet;
bool result;
#override
void initState() {
// TODO: implement initState
result = check();
super.initState();
}
#override
Widget _buildChild() {
print ("The output “);
print (result);
if (result != Null && result == true) {
// if internet is ON
return Container();
}
//if internet is off
return Container();
}
Widget build(BuildContext context) {
return new Container(child: _buildChild());
}
}
Future<bool> check() async{
var connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.mobile) {
print ("******* Mobile is ON ******");
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
print ("******* Wifi is ON ******");
return true;
}
print ("No connectivity");
return false;
}
You can use StreamBuilder
StreamBuilder(
stream: Connectivity().onConnectivityChanged,
builder: (context, snapshot) {
// Use this to avoid null exception
if (snapshot.connectionState == ConnectionState.none) {
return CircularProgressIndicator();
} else {
ConnectivityResult result = snapshot.data;
// Check Connectivity result here and display your widgets
if(ConnectivityResult.none) {
yourWidgetForNoInternet();
} else {
yourWidgetForInternet();
}
}
},
)
bool hasInternet = false, isChecking = true;
#override
void initState() {
super.initState();
check();
}
#override
Widget build(BuildContext context) {
return Container(
child: isChecking
? ListTile(
leading: CircularProgressIndicator(), title: Text('Checking...'))
: hasInternet
? ListTile(title: Text('Your widget here...'))
: ListTile(
leading: Icon(Icons.info),
title: Text('No Internet Conncetion')));
}
check() async {
var connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.mobile) {
print("******* Mobile is ON ******");
setState(() {
isChecking = false;
hasInternet = true;
//navigate to another screen.....
});
} else if (connectivityResult == ConnectivityResult.wifi) {
print("******* Wifi is ON ******");
setState(() {
isChecking = false;
hasInternet = true;
//navigate to another screen.....
});
} else {
setState(() {
isChecking = false;
hasInternet = false;
});
}
}
There is a plugin to use connectivity:
https://pub.dev/packages/connectivity#-readme-tab-
I use following code to check whether the internet is connected or not
static Future<bool> checkInternetConnectivity() async {
bool isConnected;
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
isConnected = true;
}
} on SocketException catch (_) {
isConnected = false;
}
return isConnected;
}