Can we insert two methods in void initState()? - google-maps

This is dumb question but just for the benefit of the doubt, can we insert two methods in a initState?
E.g:
_getCheckpoint1() async {
var permissions =
await Permission.getPermissionsStatus([PermissionName.Location]);
if (permissions[0].permissionStatus == PermissionStatus.notAgain) {
var askpermissions =
await Permission.requestPermissions([PermissionName.Location]);
} else {
routeCoordinates = await googleMapPolyline.getCoordinatesWithLocation(
origin: LatLng(3.082519, 101.592201),
destination: LatLng(3.083355, 101.589653),
// LatLng(3.082097, 101.585165),
mode: RouteMode.driving);
}
}
_getCheckPoint2() async {
var permissions =
await Permission.getPermissionsStatus([PermissionName.Location]);
if (permissions[0].permissionStatus == PermissionStatus.notAgain) {
var askpermissions =
await Permission.requestPermissions([PermissionName.Location]);
} else {
routeCoordinates = await googleMapPolyline.getCoordinatesWithLocation(
origin: LatLng(3.08171, 101.587507),
destination: LatLng(3.082519, 101.592201),
mode: RouteMode.driving);
}
}
#override
void initState() {
super.initState();
_getCheckpoint1();
_getCheckPoint2();
}
The reason I'm asking is because I want to generate two different polylines and merge them and form a loop of one big route of polyline through Google Maps plugin.
I need help
This is what I intend to do by adding the methods together in an initstate.
I need to construct a set of polylines just as illustrated in the picture

you can define an async function in initState but it should be void, not a future
like that :
void myFutureFunc() async {
await //My Future
}
you can define many functions as you like.

Related

Retrieve documentId from future

I have not been able to find an answer to my problem so I will ask here.
I created a document that contains one piece of data. Once that document is created I need to retrieve the id of that document so I can use that string to add to another document that will be created next. The code is below where I call the Future function "saveNewAgency" as well as the code for the Future function.
if (globals.newAgency == true) {
firestoreService.saveNewAgency(newAgency);
agentProvider.saveAgent();
globals.newAgency = false;
} else {
firestoreService.saveAgency(newAgency);
}
Future<String> saveNewAgency(Agency agency) async {
DocumentReference docRef = await _db
.collection('agency')
.add(agency.toMap())
.then((value) => value.id);
//globals.agencyId = docRef.id;
}
As you can see I tried to set a global variable inorder to get the documentId but that code never gets executed so I commented it out.
This is a small thing but it is just another step I have reached in my journey of learning flutter and firebase.
Thanks
String Id = _db .collection('agency').doc().id;
Future<String> saveNewAgency(Agency agency) async {
await _db
.collection('agency')
.doc(id)
.set(agency.toMap())
.then((value) => {
print(id);
});
}
Try this.
Future<String> saveNewAgency(Agency agency) async {
await _db
.collection('agency')
.add(agency.toMap())
.then((value) => {
globals.agencyId = value.id
});
}

Use data accross all components

Created a component where I call all my api's. How do I use that data across all my other components
export let resultData = axios
.get(`https://swapi.dev/api/people/1`) //used a dummy api to test
.then(({ data }) => data);
export default class CacheService {
static myInstance = null;
result = resultData;
static getInstance() {
if (CacheService.myInstance == null) {
CacheService.myInstance = new CacheService();
}
return this.myInstance;
}
findAll() {
console.log(this.result);
return this.result;
}
}
You have created a promise and assigned to resultData variable but its not actually resolved.
Either you can use await or use then to get the data.
let testData = await newData.findAll();
or
newData.findAll().then((data)=>{
testData = data;
});
You need to await for the axios to resolve.
async findAll() {
const actualResult = await this.result;
console.log(actualResult);
return actualResult;
}

Override Chrome Storage API

I would like to override chrome.storage.local.set in order to log the value of a storage key when the Chrome Storage API is called:
var storage_local_set = chrome.storage.local.set;
chrome.storage.local.set = function(key, value) {
console.log(key);
storage_local_set(key);
}
But I get Illegal invocation: Function must be called on an object of type StorageArea when storage_local_set(key) gets called. How can I store the data after logging the key?
For chrome.storage.sync.set this is what I tried based on the solution given:
const api = chrome.storage.sync;
const { set } = api;
api.set = function (data, callback) {
console.log(data);
set.apply(api, arguments);
};
But this is not hooking the API
You need to use .call() or .apply() to provide this object:
storage_local_set.apply(this, arguments);
The parameters in your override don't match the documentation though. If you want to match the documentation then do it like this:
const api = chrome.storage.local;
const { set } = api;
api.set = function (data, callback) {
console.log(data);
set.apply(api, arguments);
};
And if you want to change the signature to separate key and value:
const api = chrome.storage.local;
const { set } = api;
api.set = (key, value, callback) => {
console.log(key, value);
set.call(api, {[key]: value}, callback);
};

Flutter Deeplink to Google maps and Waze

I'm implementing a deeplink to a navigation app (like Google Maps or Waze) from a flutter app. I don't have problems doing so for either Google Maps or Waze, my problem is that if I configure the link for Google Maps, the user can still choose to open it in Waze, but obviously no navigation is started since parameters are different.
Is there a way to limit users choice on the app to use? Or is it possible to use a different link depending on which app the user chooses to open? Or even better, is there a universal link for navigation that works on both apps?
You can force to open the selected application using a Universal link (iOS) / App link (Android) and it should force the selected app to be opened. Of course, If the application you want to launch is not found in the device it will open it in the browser.
Here I assume that you are using latitude and longitude to navigate to the place but you can easily adjust it to something else.
I am also using the url_launcher to launch the links.
void launchWaze(double lat, double lng) async {
var url = 'waze://?ll=${lat.toString()},${lng.toString()}';
var fallbackUrl =
'https://waze.com/ul?ll=${lat.toString()},${lng.toString()}&navigate=yes';
try {
bool launched =
await launch(url, forceSafariVC: false, forceWebView: false);
if (!launched) {
await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
}
} catch (e) {
await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
}
}
void launchGoogleMaps(double lat, double lng) async {
var url = 'google.navigation:q=${lat.toString()},${lng.toString()}';
var fallbackUrl =
'https://www.google.com/maps/search/?api=1&query=${lat.toString()},${lng.toString()}';
try {
bool launched =
await launch(url, forceSafariVC: false, forceWebView: false);
if (!launched) {
await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
}
} catch (e) {
await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
}
}
You also need to add the following to your Info.plist file:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
<string>waze</string>
</array>
Updating to the url_launcher last version
import 'package:url_launcher/url_launcher.dart' as url_launcher;
...
Future<void> launchWazeRoute(double lat, double lng) async {
var url = 'waze://?ll=${lat.toString()},${lng.toString()}';
var fallbackUrl =
'https://waze.com/ul?ll=${lat.toString()},${lng.toString()}&navigate=yes';
try {
bool launched = false;
if (!kIsWeb) {
launched = await url_launcher.launchUrl(Uri.parse(url));
}
if (!launched) {
await url_launcher.launchUrl(Uri.parse(fallbackUrl));
}
} catch (e) {
await url_launcher.launchUrl(Uri.parse(fallbackUrl));
}
}
Future<void> launchGoogleMaps(double lat, double lng) async {
var url = 'google.navigation:q=${lat.toString()},${lng.toString()}';
var fallbackUrl =
'https://www.google.com/maps/search/?api=1&query=${lat.toString()},${lng.toString()}';
try {
bool launched = false;
if (!kIsWeb) {
launched = await url_launcher.launchUrl(Uri.parse(url));
}
if (!launched) {
await url_launcher.launchUrl(Uri.parse(fallbackUrl));
}
} catch (e) {
await url_launcher.launchUrl(Uri.parse(fallbackUrl));
}
}
You also need to put it on info.plist file:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
<string>waze</string>
</array>

Open Google Maps app if available with flutter

I'm trying to detect whether Google Maps app is installed on iOS, and if so, launch it, if not, launch Apple Maps. Here is what I have so far, but on my phone with Google Maps installed, it isn't detecting it and launching appropriately.
Any ideas?
import 'package:url_launcher/url_launcher.dart';
_launchMaps() async {
String googleUrl =
'comgooglemaps://?center=${trip.origLocationObj.lat},${trip.origLocationObj.lon}';
String appleUrl =
'https://maps.apple.com/?sll=${trip.origLocationObj.lat},${trip.origLocationObj.lon}';
if (await canLaunch("comgooglemaps://")) {
print('launching com googleUrl');
await launch(googleUrl);
} else if (await canLaunch(appleUrl)) {
print('launching apple url');
await launch(appleUrl);
} else {
throw 'Could not launch url';
}
}
I pulled the url scheme from here: How would I be able to open google maps when I press a button in my app?
you can install the packege url_launcher and use the code down below:
import 'package:url_launcher/url_launcher.dart';
class MapUtils {
MapUtils._();
static Future<void> openMap(double latitude, double longitude) async {
String googleUrl = 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude';
if (await canLaunch(googleUrl)) {
await launch(googleUrl);
} else {
throw 'Could not open the map.';
}
}
}
Now you can open google maps in your app just call this method:
MapUtils.openMap(-3.823216,-38.481700);
I found my issue: this needs to be in the plist file. The code in the question above is fine. (The SO answer referenced in the question only mentioned the "comgooglemaps" string.)
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
</array>
Docs: https://developers.google.com/maps/documentation/ios-sdk/start#step_7_declare_the_url_schemes_used_by_the_api
Do it this way
Full code is given below
static void navigateTo(double lat, double lng) async {
var uri = Uri.parse("google.navigation:q=$lat,$lng&mode=d");
if (await canLaunch(uri.toString())) {
await launch(uri.toString());
} else {
throw 'Could not launch ${uri.toString()}';
}
}
1) in pubspec.yaml
dependencies:
flutter:
sdk: flutter
...
url_launcher: ^5.7.8
2) Import wherever you want to use
import 'package:url_launcher/url_launcher.dart';
3) final you call
onPressed: () {
navigateTo(location.lat, location.lng);
},
If you don't have the actual latlong, you can simply pass an address to Google Maps.
void launchMap(String address) async {
String query = Uri.encodeComponent(address);
String googleUrl = "https://www.google.com/maps/search/?api=1&query=$query";
if (await canLaunch(googleUrl)) {
await launch(googleUrl);
}
}
Of course, the more information you have in the address, the more accurate the search will be. Exactly the same as looking for something on the actual Google Maps page or app.
By the way, you need to url-encode the address before adding it to the URL, to support special characters like spaces. It's only needed for iOS, but hey, we want to develop for all environments out there.
using url launcher
in yaml file: url_launcher: ^5.0.2 last
then you can use this method to open google maps centered to the provided lat and long
more info to maps intent from docs [here][2]
launchMap({String lat = "47.6", String long = "-122.3"}) async{
var mapSchema = 'geo:$lat,$long';
if (await canLaunch(mapSchema)) {
await launch(mapSchema);
} else {
throw 'Could not launch $mapSchema';
}
}
If you want to navigate with directions you can just create a url with source and destination co-ordinates and other coordinates to add as stops.
Steps:
Install url_launcher plugin
write a code like below.
_launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
const url ='https://www.google.com/maps/dir/?api=1&origin=43.7967876,-79.5331616&destination=43.5184049,-79.8473993&waypoints=43.1941283,-79.59179|43.7991083,-79.5339667|43.8387033,-79.3453417|43.836424,-79.3024487&travelmode=driving&dir_action=navigate';
_launchURL(url);
static Future<void> openMap(BuildContext context, double lat, double lng) async {
String url = '';
String urlAppleMaps = '';
if (Platform.isAndroid) {
url = 'https://www.google.com/maps/search/?api=1&query=$lat,$lng';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch $url';
}
} else {
urlAppleMaps = 'https://maps.apple.com/?q=$lat,$lng';
url = 'comgooglemaps://?saddr=&daddr=$lat,$lng&directionsmode=driving';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else if (await canLaunchUrl(Uri.parse(urlAppleMaps))) {
await launchUrl(Uri.parse(urlAppleMaps));
} else {
throw 'Could not launch $url';
}
}
}
import 'package:url_launcher/url_launcher.dart';
static void launchMapsUrl(
sourceLatitude,
sourceLongitude,
destinationLatitude,
destinationLongitude) async {
String mapOptions = [
'saddr=$sourceLatitude,$sourceLongitude',
'daddr=$destinationLatitude,$destinationLongitude',
'dir_action=navigate'
].join('&');
final url = 'https://www.google.com/maps?$mapOptions';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
} }
Here you can use this function directly and pass the required parameters and also import this package https://pub.dev/packages/url_launcher/
As follow-up to Roc Boronat's post, the following code can be used for launching the platform specific map application.
Future<void> launchMapUrl(String address) async {
String encodedAddress = Uri.encodeComponent(address);
String googleMapUrl = "https://www.google.com/maps/search/?api=1&query=$encodedAddress";
String appleMapUrl = "http://maps.apple.com/?q=$encodedAddress";
if (Platform.isAndroid) {
try {
if (await canLaunch(googleMapUrl)) {
await launch(googleMapUrl);
}
} catch (error) {
throw("Cannot launch Google map");
}
}
if (Platform.isIOS) {
try {
if (await canLaunch(appleMapUrl)) {
await launch(appleMapUrl);
}
} catch (error) {
throw("Cannot launch Apple map");
}
}
For more information regarding the query parameters in Apple Maps URL, please visit this link.
Edit (7th Aug, 2022): This code will work upto version 6.0.20 of the url_launcher plugin. I could not get it to work after this version as I was getting an ERR_UNKNOWN_URL_SCHEME error when trying to launch Google Maps using canLaunchUrl and launchUrl methods using the versions of the plugin above 6.0.20 and 6.0.20. It works only with the deprecated methods (canLaunch and launch). Just a heads up if anyone wants to try this code snippet.
with 'url_launcher 6.1.0' + physical address instead of lat & lon,
void _pushMap(String address) async {
String query = Uri.encodeComponent(address);
String googleUrl = "google.navigation:q=$query";
Uri googleUri = Uri.parse(googleUrl);
if (await canLaunchUrl(googleUri)) {
await launchUrl(googleUri);
}
}
This will send an implicit Intent to open related apps including google maps.
Haven't tested on iOS devices.
tldr: I think there's an error in the library and canLaunch sometimes returns false even if the url can be launched.
I was trying to open a google maps link (https://goo.gl/maps/mHGzrGUhUHrQByAm8) the same way I do for another link from my app, but for whatever reason canLaunch always returned false.
So now I launch in a try catch block to make sure it doesn't crash my app, and it's working.
try {
launch(url);
} catch (error, stack) {
// log error
}
you can install the packege url_launcher and use the code down below:
This is the latest code as per
url_launcher: 6.1.6
canLaunch();
launch(); these methods has been deprecated now.
class GoogleMapUtils {
GoogleMapUtils._();
static Future<void> openMapApp(double latitude, double longitude) async {
Uri googleUrl = Uri.parse('https://www.google.com/maps/search/?api=1&query=$latitude,$longitude');
if (await canLaunchUrl(googleUrl)) {
await launchUrl(googleUrl);
} else {
throw 'Unable open the map.';
}
}
}
Use plugin:
intent: ^1.4.0
Try the following code:
static void navigateTo(double lat, double lng) async {
var uri = Uri.parse("google.navigation:q=$lat,$lng&mode=c");
android_intent.Intent()
..setAction(android_action.Action.ACTION_VIEW)
..setData(uri)
..setPackage("com.google.android.apps.maps")
..startActivity().catchError((e) => print(e));
}
Note: Only works on Android devices
Install url_launcher package
use the below function
void launchMap() async {
Uri googleUrl = Uri.parse('https://www.google.com/maps/search/?api=1&query=Googleplex');
if (await canLaunchUrl(googleUrl)) {
await launchUrl(googleUrl, mode:LaunchMode.externalApplication);
}
}
Using url luncher with navigation open by default.
Sample code - if app installed it will open in app otherwise open in any browser
///launch map
Future<void> openMap(double latitude, double longitude) async {
String mapUrl = '';
if (Platform.isIOS) {
mapUrl =
'https://maps.apple.com/?daddr=$latitude,$longitude';
} else {
mapUrl =
'https://www.google.com/maps/dir/?api=1&destination=$latitude,$longitude&travelmode=driving';
}
if (await canLaunchUrl(Uri.parse(mapUrl))) {
await launchUrl(Uri.parse(mapUrl),mode: LaunchMode.externalApplication);
} else {
throw 'Could not open the map.';
}
}
if you like to open google map in apple devices add this code in info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
</array>
<key>LSApplicationQueriesSchemes</key>
For other queries
Google url params example
https://www.google.com/maps/dir/?api=1
&origin=$latitude,$longitude
&destination=$latitude,$longitude
&travelmode=driving
&dir_action=navigate
Apple
q= query
saddr = starting point for directions
daddr = destination point for directions
dirflg = The transport type