flutter_downloader auto open file when complete - flutter

so I'm trying to work with download manager in flutter using flutter_downloader package. I manage to make my app download the file I wanted. How can I make my app more advance ? I wanted my app to be able to open the downloaded file automatically when the download is done.
Another question is, if I already download the file first time how can I make the button trigger to open the file location rather than downloading the file again ?
Here's my current code:
TextButton(
child: Text(
ticketData['file_attachment_map'][index]['name'],
style: primaryColor600Style.copyWith(fontSize:14.sp),
),
onPressed: () async {
final permissionStatus = await Permission.storage.request();
if (permissionStatus.isGranted) {
final externalDir = await getExternalStorageDirectory();
final taskId =await FlutterDownloader.enqueue(
url: ticketData['file_attachment_map']
[index]['url'],
savedDir:externalDir!.path,
showNotification:true,
openFileFromNotification:true,
);
} else {
print('Permission denied');
}
},
),

Use open_file package after downloaded
if(taskId != null){
await OpenFile.open(filePath);
}
}
And you can check file exist before download file
import 'dart:io';
File("path/to/file").exists()

As a complement to #Xuann Thucc answer, you can use the open_filex which is a fork of open_file but is better maintained and fixes many issues with the original lib.
import 'package:open_filex/open_filex.dart';
// in async function
await OpenFilex.open(filePath);

Related

How to send user out of the application - To a specific directory path

I have a specific path where user files are exported under the following path:
e.g : /storage/emulated/0/Android/data/com.example.app_name/files
However the problem is not how generate the path but how to do this redirection (open the folder where the file is stored).
I've tried to use the plugin url_launcher but apparently it doesn't work.I tried to launch this path as url:
code example :
FlatButton(
onPressed: () async{
// _localPath returns /storage/emulated/0/Android/data/com.example.app_name/files
final path = await _localPath;
if (await canLaunch(path)) {
await launch(path);
} else {
throw 'Could not launch $path';
}
},
child: Text('Navigate to App storage Folder'),
),
The user exported the data as csv file and he want to use that file.
The expected result : user will be redirected to the path (folder files) and exit the Flutter application.
PS : I'm targeting only Android Platform.
I seem to have found a solution for your question with a package called open_file.
You can simply point to the path you want to open and it will ask the OS for the app you want to use to handle files or use what is set as your default.
Basic code example:
class OpenDirectoryPath extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('Open path'),
onPressed: () {
_openPath('/storage/emulated/0/Download/');
},
),
);
}
void _openPath(String path) async {
OpenFile.open(path);
}
}
(tested in Android)

mailto: link for Flutter for Web

The url_launcher package (https://pub.dev/packages/url_launcher) doesn't seem to work for Flutter for Web. The following code prints "test url1" but nothing happens afterwards.
How can I implement mailto: like functionality in Flutter for Web which causes the default email app to open with a prepopulated 'to:' email address?
FlatButton(
onPressed: _mailto, //() => {},
padding: EdgeInsets.all(3.0),
child: _contactBtn(viewportConstraints),
)
_mailto() async {
const url = 'mailto:support#email.com?subject=Product Inquiry&body=';
print("test url1");
if (await canLaunch(url)) {
print("test url2");
await launch(url);
} else {
print("test url3");
throw 'Could not launch $url';
}
}
After experimenting a little I found a way to make url_launcher work with web.
Don't use canLaunch(url). Instead, just use launch(url), but wrap it in try-catch block. This way you should be safe and the email link will work. For catch you can just copy the email to clipboard and notify the user about that with a snackbar or smth. Probably not the best solution, but a good one, till we get something better.
Here is the sample code, so that you see what I mean:
void _launchMailClient() async {
const mailUrl = 'mailto:$kEmail';
try {
await launch(mailUrl);
} catch (e) {
await Clipboard.setData(ClipboardData(text: '$kEmail'));
_emailCopiedToClipboard = true;
}
}
import 'package:mailto/mailto.dart';
// For Flutter applications, you'll most likely want to use
// the url_launcher package.
import 'package:url_launcher/url_launcher.dart';
// ...somewhere in your Flutter app...
launchMailto() async {
final mailtoLink = Mailto(
to: ['to#example.com'],
cc: ['cc1#example.com', 'cc2#example.com'],
subject: 'mailto example subject',
body: 'mailto example body',
);
// Convert the Mailto instance into a string.
// Use either Dart's string interpolation
// or the toString() method.
await launch('$mailtoLink');
}

Flutter - How to check is the app has a new version?

I create an app with Flutter. I need to force users to update the app when I upload a new version. I try this package, but I think that it doesn´t work. In the documentation, we can read that we can verify the version with this code.
Container(
margin: EdgeInsets.fromLTRB(12.0, 0.0, 12.0, 0.0),
child: UpgradeCard();
)
The problem is: I need to check the version in *'initState', not in Scaffold. So what is the right way to check the version on the app start?
I recommend trying out the Firebase Remote Config and update the minimum required version there. It's not a good practice to force update app on every update in the store. Also, some users can see the updated version in given store later than others. This is just how Google Play and AppStore work.
Thus, when you really need to force update the application you can increment the parameter on Firebase e.g. a day after update in the store.
Simple code to trigger the dialog can look as following:
Future<bool> checkUpdates() async {
await remoteConfig.fetch();
await remoteConfig.activateFetched();
final requiredBuildNumber = remoteConfig.getInt(Platform.isAndroid
? 'requiredBuildNumberAndroid'
: 'requiredBuildNumberIOS');
final currentBuildNumber = int.parse(packageInfo.buildNumber);
return currentBuildNumber < requiredBuildNumber;
}
This requires package_info package to be added as well as firebase_remote_config.
To open the app in the store you need to use url_launcher package and just pass URL to your app.
you can call https://itunes.apple.com/lookup?bundleId=$id or https://play.google.com/store/apps/details?id=$id to receive the newest app version available on the stores.
i can recommend this package to do this: https://pub.dev/packages/new_version
You can check your app version like
#override
void initState() {
super.initState();
Timer(
Duration(seconds: 3), // put your stuff here
() => Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => LoginScreen())));}
and presume one thing this code must be in spalsh screen or home screen
and there you can check app version forcefully stop any app which is belonged old version
Try out the in app update package- https://pub.dev/packages/in_app_update which works on Android and for iOS, try- https://pub.dev/packages/upgrader.
Use this package -> new_version
It's awesome & easy :)
///initialize your variable
final newVersion = NewVersion(
iOSId: 'com.google.Vespa',
androidId: 'com.google.android.apps.cloudconsole',
);
//and use this inside of your widget or controller
#override
Widget build(BuildContext context) {
newVersion.showAlertIfNecessary(context: context);
return Container();
}
If you just want the current version number from the App Store and Play Store. You can use the upgrader package API like this:
import 'dart:developer';
import 'dart:io';
import 'package:html/dom.dart';
import 'package:upgrader/upgrader.dart';
Future<String?> getStoreVersion(String myAppBundleId) async {
String? storeVersion;
if (Platform.isAndroid) {
PlayStoreSearchAPI playStoreSearchAPI = PlayStoreSearchAPI();
Document? result = await playStoreSearchAPI.lookupById(myAppBundleId, country: 'US');
if (result != null) storeVersion = PlayStoreResults.version(result);
log('PlayStore version: $storeVersion}');
} else if (Platform.isIOS) {
ITunesSearchAPI iTunesSearchAPI = ITunesSearchAPI();
Map<dynamic, dynamic>? result =
await iTunesSearchAPI.lookupByBundleId(myAppBundleId, country: 'US');
if (result != null) storeVersion = ITunesResults.version(result);
log('AppStore version: $storeVersion}');
} else {
storeVersion = null;
}
return storeVersion;
}
EDIT: If your app is NOT available on the US App Store or Play Store, you need to change the country code.

How do I open instagram from flutter app?

I want to transite to Instagram profile, when I am tapping on button. I use this library url_launcher. But there I can use only Web Browser for this. What will I do, in order to reach my goal?
To open Native and WebView Instagram:
Add to your iOS/Runner/Info.plist:
<key>LSApplicationQueriesSchemes</key>
<array>
...
<string>instagram</string>
</array>
Install url_launcher ( https://pub.dev/packages/url_launcher )
Import
import 'package:url_launcher/url_launcher.dart';
Create some method like this;
Inside Widget for example:
_launchInstagram() async {
const nativeUrl = "instagram://user?username=severinas_app";
const webUrl = "https://www.instagram.com/severinas_app/";
if (await canLaunch(nativeUrl)) {
await launch(nativeUrl);
} else if (await canLaunch(webUrl)) {
await launch(webUrl);
} else {
print("can't open Instagram");
}
}
Well, I don't know if it's too late, but this works for me using the url_launcher library (tested on android only):
var url = 'https://www.instagram.com/<INSTAGRAM_PROFILE>/';
if (await canLaunch(url)) {
await launch(
url,
universalLinksOnly: true,
);
} else {
throw 'There was a problem to open the url: $url';
}
2022 update:
_launchInstagram() async {
var nativeUrl = "instagram://user?username=balkan.exe";
var webUrl = "https://www.instagram.com/balkan.exe";
try {
await launchUrlString(nativeUrl, mode: LaunchMode.externalApplication);
} catch (e) {
print(e);
await launchUrlString(webUrl, mode: LaunchMode.platformDefault);
}
}
I am not sure if you can launch the profile activity, unless you know the name (which might change in the future). But, if you can try launching the app by using Intent plugin:
Try adding the Intent plugin:
https://pub.dev/packages/intent
Add intent in you in your pubspec.yaml file.
You can call the specific app with the package name (in this case Instagram).
Intent()
..setAction(Action.ACTION_SHOW_APP_INFO)
..putExtra(Extra.EXTRA_PACKAGE_NAME, "instagram package name")
..startActivity().catchError((e) => print(e));
You can also make use Android flutter plugin for Intent:
https://pub.dev/packages/android_intent
This will support for Android :
Use it by specifying action, category, data and extra arguments for the intent. It does not support returning the result of the launched activity
For IOS url_launcher plugin can be used for deep linking
You can create a platform channel and use the intent to achieve that or use social_share package.
Install url_launcher ( https://pub.dev/packages/url_launcher )
They now have a mode parameter, which you set to LaunchMode.externalApplication;
Call it with the regular https url, if they have the app installed it will open the app, otherwise it will open in Safari. Don't worry about doing an app link and a website url, the package and the OS handle it accordingly.
For example, here are my links in our About section of the app to our socials..
SettingsListTileModel(
// This can be any website's url that has a corresponding app, we us it with Twitter, Facebook, Instagram, and Youtube.
onTap: () => launchUrl(
Uri.parse('https://www.instagram.com/forwheel_app/'),
mode: LaunchMode.externalApplication,
),
title: Text(
'Instagram',
style: context.bodyLarge),
),
trailing: Icon(
FontAwesomeIcons.squareArrowUpRight,
),
),

How to launch whatsapp and facebook messenger window from Flutter to point to a specific contact?

Using url_launcher I can open phone to call a number.
var phone = "+123456789";
launch("tel://$phone");
How can I do the same for facebook messenger and whatsapp?
I found the solution.
To open whatsapp:
var whatsappUrl ="whatsapp://send?phone=$phone";
await canLaunch(whatsappUrl)? launch(whatsappUrl):print("open whatsapp app link or do a snackbar with notification that there is no whatsapp installed");
To open messenger or facebook:
First get shortened url
If your facebook profile is facebook.com/yourName
facebook url would be fb.me/yourName and messenger url would be m.me/yourName
then you do
launch("http://$messengerUrl");
Facebook website will automatically open the link in the app even though it goes trough URL browser. If there is no app installed, it will go to the app/play store
To open WhatsApp you can use this plugin: https://pub.dartlang.org/packages/flutter_launch
1. Add this to your package's pubspec.yaml file:
dependencies:
flutter_launch: "^0.3.0"
2. Install it
$ flutter packages get
3. Import it
import 'package:flutter_launch/flutter_launch.dart';
4. Example:
await FlutterLaunch.launchWhatsapp(phone: "5534992019999", message: "Hello");
Complete example: https://pub.dartlang.org/packages/flutter_launch#-installing-tab-
Import package url_launcher:
url_launcher: ^6.0.3
Import dependency:
import 'package:url_launcher/url_launcher.dart';
Put your url:
const _url = 'https://api.whatsapp.com/...';
Create your function:
void _launchURL() async => await canLaunch(_url)
? await launch(_url) : throw 'Not found $_url';
Use, por example in Button:
FloatingActionButton(
onPressed: _launchURL,
...
),
This works for me! :D
we can use the flutter package https://pub.dev/packages/url_launcher
For sending with number and text --->
whatsapp://send?phone=XXXXXXXXX&text=Hellothere!
For sending only text --->
https://api.whatsapp.com/send?text=Hellothere!
You can use Flutter URL lanucher plugin to launch whatsapp app. There you need to add conditions for android and iphone. You can read complete Flutter tutorial here.
for android
var whatsappURl_android = "whatsapp://send?phone="+whatsapp+"&text=hello";
for iphone
var whatappURL_ios ="https://wa.me/$whatsapp?text=${Uri.parse("hello")}";
first detect the phone OS version - android OR iOS
if(Platform.isIOS){
// for iOS phone only
if( await canLaunch(whatappURL_ios)){
await launch(whatappURL_ios, forceSafariVC: false);
}else{
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: new Text("whatsapp no installed")));
}
}else{
// android , web
if( await canLaunch(whatsappURl_android)){
await launch(whatsappURl_android);
}else{
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: new Text("whatsapp no installed")));
}
}
import 'package:url_launcher/url_launcher.dart';
void _contactViaWhatsApp(context) async {
String whatsAppUrl = "";
String phoneNumber = 'your-phone-number';
String description = "your-custom-message";
if (Platform.isIOS) {
whatsAppUrl =
'whatsapp://wa.me/$phoneNumber/?text=${Uri.parse(description)}';
} else {
whatsAppUrl =
'https://wa.me/+$phoneNumber?text=${Uri.parse(description)}';
}
if (await canLaunch(whatsAppUrl)) {
await launch(whatsAppUrl);
} else {
final snackBar = SnackBar(
content: Text("Install WhatsApp First Please"),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}