direct location using google maps application - flutter

// custom function to locate the location to direct using google maps app
Future<void> openMap(List<CustAddressModel>latitude,longitude) async {
String googleUrl = 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude';
await canLaunchUrlString(googleUrl)
? await launchUrlString(googleUrl)
: throw 'Could not launch google map $googleUrl';
}
#override
void initState() {
// TODO: implement initState
super.initState();
custLocation();
}
}
Here i want to custom function openMap() where user can click button to direct the location using google maps app. Location 1 where the seller location i retrieve from database and the location 2 is customer location i retrieve from database also. Now i want to pass the lat and long from both location 1 and 2, so that user can direct to google maps app to direct to seller location

you can use the packege url_launcher and then add following code:
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:
onTap: () {
final snapshot = await Firestore.instance.collection("collectionName").document('docId').get();
final lat = snapshot.data['latitude'];
final long = snapshot.data['longitude'];
MapUtils.openMap(lat, long);
};
On iOS you need to do some extra steps is that, write following lines in info.plist file
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
</array>

Related

Flutter - Firebase Dynamic Link not Working while app is in kill mode

I have integrated Firebase Dynamic link in my Flutter application to open and navigate application users to specific screen in app.
For that first of all I have added below plugin in pubspec.yaml file:
firebase_dynamic_links: ^5.0.5
Then, I have created a separate class to handle related stuffs as below:
class DynamicLinkService {
late BuildContext context;
FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance;
Future<void> initDynamicLinks(BuildContext context) async {
this.context = context;
dynamicLinks.onLink.listen((dynamicLinkData) {
var dynamicLink=dynamicLinkData.link.toString();
if (dynamicLink.isNotEmpty &&
dynamicLink.startsWith(ApiConstants.baseUrl) &&
dynamicLink.contains("?")) {
//Getting data here and navigating...
...
...
...
}
}).onError((error) {
print("This is error >>> "+error.message);
});
}
}
Now, I am initialising Deep-link as below in my home_screen:
final DynamicLinkService _dynamicLinkService = DynamicLinkService();
and then calling below method in initState()
#override
void initState() {
SchedulerBinding.instance.addPostFrameCallback((_) async {
await _dynamicLinkService.initDynamicLinks(context);
});
}
This is working like a charm! when my application is in recent mode or in background mode.
But the issue is when the application is closed/Killed, clicking on dynamic link just open the app but could not navigate.
What might be the issue? Thanks in advance.
Let me answer my own question, It might be useful for someone!
So, In above code I forgot to add code to handle dynamic link while the app is in closed/kill mode.
We need to add this code separately:
//this is when the app is in closed/kill mode
final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
handleDynamicLink(initialLink);
}
So, final code looks like as below:
//this is when the app is in closed/kill mode
final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
handleDynamicLink(initialLink);
}
//this is when the app is in recent/background mode
dynamicLinks.onLink.listen((dynamicLinkData) {
handleDynamicLink(dynamicLinkData);
}).onError((error) {
print("This is error >>> "+error.message);
});
Its working like a charm now! That's All.

when on press on ElevatedButton I want open Routing applications. Flutter

I get current location and my destination in app, when on press on ElevatedButton I want open Routing applications like google maps or Waze in user mobile.
ElevatedButton(
onPressed: () {
},
),
how can I do that?
use this package and do it like this:
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.';
}
}
Its better to use this package like this:
Future<void> openMap(double latitude, double longitude) async {
String googleUrl = 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude';
var _params;
Uri googleUri = Uri.parse(googleUrl).replace(queryParameters: _params);
if (await canLaunchUrl(googleUri)) {
await launchUrl(googleUri);
} else {
throw 'Could not open the map.';
}
}

Flutter uni_links duplicate the app every time a link is clicked

I am implementing a password recovery function based on the url sent to the email. Opening the app based on that url was successful. But instead of directly opening the required page in the app that is in the background, it duplicates the app. Although it still leads me to the password recovery page, now there will be 2 same apps running side by side
Procedure
Enter your email to send the password reset link
Click submit
Open the email containing the recovery link
Duplicate the app and open a recovery password page
Things what happen
Splash screen, first page open in the app, I am trying to do as instructed from uni_links package but still no success. Currently the function getInitialLink has the effect of opening the app based on the recovery link
class SplashController extends GetxController {
final SharedPreferencesHelper _helper = Get.find<SharedPreferencesHelper>();
late StreamSubscription sub;
#override
void onReady() async {
super.onReady();
await checkToken();
}
Future<void> checkToken() async {
await Future.delayed(Duration(seconds: 3));
var token = _helper.getToken();
if (token == null) {
Get.offNamed(Routes.LOGIN);
} else {
Get.offNamed(Routes.MAIN);
}
}
#override
void onInit() {
super.onInit();
initUniLinks();
}
Future<Null> initUniLinks() async {
// Platform messages may fail, so we use a try/catch PlatformException.
try {
String? initialLink = await getInitialLink();
if (initialLink != null) {
print("okay man");
Get.toNamed(Routes.RECOVERY);
}
sub = getLinksStream().listen((link) {
}, onError: (err) {
});
} on PlatformException {
// Handle exception by warning the user their action did not succeed
// return?
}
}
}
I found the solution, actually this answer is already on Stackoverflow, and it's really simple.
In the AndroidManifest.xml file of the app. Find "android:launchMode" and change its old value to singleTask. And here is the result
android:launchMode="singleTask"

Using The Shared Preferences Package for Data Persistance

I am coding a relatively simple app where one can set an emergency contact and in case of emergency, a text is sent to the contact by the touch of a remote button (connected via Bluetooth.) I have used the package contact picker and it works perfectly. Now, the issue is that I'm trying to save the contact locally for when the app is relaunched. The set state line returns an error that I cannot set contact to type string.
final ContactPicker _contactPicker = new ContactPicker();
Contact _contact;
#override
void initState() {
getData();
}
getData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_contact = prefs.getString(_contact.toString());
});
}```
maybe u need to decode that string from prefs so that it can get converted in Contact instance.
this line prefs.getString(_contact.toString()) is returning string in $fullName: $phoneNumber this format
e.g.
var decodedList = prefs.getString('contact').split(" ");
setState(() {
_contact = Contact(fullName: decodedList.first, phoneNumber: decodedList[1]);
});

Get Package Name/ApplicationId in Other pages

I want to implement rate and share button in my app so I am using url_launcher and here I want to put url of my app.
Currently it is working as
url="https://play.google.com/store/apps/details?id=in.learncodeonline.lco";
but I want this type
url="https://play.google.com/store/apps/details?id={packageName}"
Just call this function with package Name
void shareAnyApp(String packageName) async {
var url = "https://play.google.com/store/apps/details?id=$packageName";
if (await canLaunch(url)) {
await launch(url);
}
}
To Get Current App Package use Package_info
PackageInfo packageInfo = await PackageInfo.fromPlatform();
shareAnyApp(packageInfo.packageName );