Download image in mobile in flutter web - flutter

I created a flutter web app that creates an image and generates the base64 data. so I used AnchorElement in the HTML package to download the image to the client, it works on mac and windows but when I want to be downloaded on mobile nothing happen at all.
any clue?
code:
Future<void> downloadImage(Uint8List data8) async {
try {
final base64data = base64Encode(data8);
final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
a.download = 'image.jpg';
a.click();
a.remove();
} catch (e) {
print(e);
}
}

In general mobile apps need rights to access certain resource, e.g. access the network.
Search for entitlement on iOS like this and manifest on Android.
You need to set these rights in the iOS or Android project. Without this rights, access gets simply denied.

Related

Open another desktop app with admin privilages within Flutter Desktop app

I am using url launcher package to run another app using my flutter desktop app with the following code:
launchAutoCadApp() async {
SharedPreferencesManager prefs = SharedPreferencesManager();
final String filePath = (await prefs.getCUrl()).toString();
final Uri uri = Uri.file(filePath);
if (!File(uri.toFilePath()).existsSync()) {
throw Exception('$uri does not exist!');
}
if (!await launchUrl(uri)) { //This is where my another desktop app is being initiated
throw Exception('Could not launch $uri');
}
}
I want to initiate my another desktop app with admin privilages from my flutter desktop app i.e a popup should display like this before launching my app.
I have gone through this answer on stackoverflow, but this doesn't fullfil what I want.

Create a button to open app from flutter web

I would like to create an app in Flutter. The web version contains a button that should open version of android or IOS app according user platform if mobile version of app was installed (like an app install or open banner).
How should I detect is app installed in web flutter?
update:
I tried below code using import 'package:universal_html/html.dart' pakage:
window.location.href = (defaultTargetPlatform ==
TargetPlatform.android)
? 'https://play.google.com/store/apps/details?id=com.amazon.mShop.android.shopping'
: 'https://apps.apple.com/us/app/amazon-shopping/id297606951';
But this just open the store. I'm looking for a solution to open app directly if it was installed.
If this is fine for you, you can use an URL launcher. This way it opens the App store or play store and the user can either download the App or open it.
For Example flutter has a package that does most of this work:
https://github.com/Purus/launch_review
LaunchReview.launch(androidAppId: "yourpackagename", iOSAppId: "appid");
You just need to pass your package name and on ios your app ID
You could also use an URL Launcher:
https://pub.dev/packages/url_launcher
The code would be similar to this:
_launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
}
else {
throw 'Could not launch $url';
}
}
URL Example
try {
launch("market://details?id=" + appPackageName);
} on PlatformException catch(e) {
launch("https://play.google.com/store/apps/details?id=" + appPackageName);
} finally {
launch("https://play.google.com/store/apps/details?id=" + appPackageName);
}
Note this code needs to be adapted
Also see this tutorial for help: https://flutteragency.com/open-appstore-playstore-url-in-flutter/
Edit:
If you want to directly open another app you can use something like this:
https://pub.dev/packages/external_app_launcher/
flutter pub add external_app_launcher
The Code would look like this then:
await LaunchApp.openApp(
androidPackageName: 'net.pulsesecure.pulsesecure',
iosUrlScheme: 'pulsesecure://',
appStoreLink: 'itms-apps://itunes.apple.com/us/app/pulse secure/id945832041',// openStore: false
);
// Enter the package name of the App you want to open and for iOS add the URLscheme to the Info.plist file.
// The `openStore` argument decides whether the app redirects to PlayStore or AppStore.
// For testing purpose you can enter com.instagram.android
More infos regarding implementation and additional setup infos you can find here: https://pub.dev/packages/external_app_launcher in the Readme

Flutter - download files of any type on Android to external storage i.e. Downloads directory

Just about any mobile app framework seems to have the ability to download files to the "Downloads" directory, except for Flutter. Or is it just me?
Since Android SDK 29 it appears Flutter (Android) has taken the direction of only allowing files to be downloaded to the scoped application directory or the application's temporary cache directory. I could be totally wrong on this, which is why I am posting on SO, in the hopes I am.
You can download on Android, but the problem is you would have to write a tutorial for a user to try to find anything you downloaded because of where you can download files in Flutter. Either to the inaccessible except by app applications directory or the impossible to find application temp cache directory.
First question, why is there not a simple way to gain permission and download files on Android to the Downloads or media directory? Or better yet a dialog where the user can pick where they want to download files. I get security but Slack app does it somehow.
On Slack's app I can download a file and it will save to Downloads. Not a big deal.
There is lots of advice on SO about flutter packages that are outdated:
ext_storage is outdated and even if you could get the downloads directory path you couldn't write to it just using Flutter/Dart.
image_gallery_saver appears to have found a work around to this limitation, but it only works for certain file types. E.g. it won't work with audio files for some reason.
downloads_path_provider same issue as bullet 1 and it is no longer maintained anyway.
path_provider has a getExternalStorageDirectory() function. You'd assume it would return external storage options on Android, but all it currently returns are the application document directory (not accessible to users outside the app) and the temp application cache directory, which is impossible for a user to find without a tutorial.
Just reference the path to emulated storage /storage/emulated/0/Download does not work Oct. 30, 2021. No permission to write even if you have been granted storage permission.
Flutter needs to be able to download files on Android to the Downloads or media directories. There are plenty of legit reasons that you might download a file from a Flutter app that needs to be accessible in external storage that is public and can easily be found through Android's Files app.
Anyway, what options does a Flutter dev have here Oct. 2021 to save files on Android to the Downloads directory??? Btw, just a default on iOS.
Right now, it appears on Android the best option for Flutter devs is to use a something like url_launcher and craft a url that forces a download, which will in turn access the browser's download manager. Is the best scenario for Android right now?
Finally, I love Flutter, but this particular area seems to be needing some love so Flutter devs don't fall behind other frameworks out there.
For Oct 2021 Flutter it turns out there is a great solution for this for Android. The missing package I needed was the flutter_file_dialog package, which is using Kotlin to add the needed programming to save files wherever the Flutter app user wants to on their Android device, including Downloads.
Packages I used:
path_provider
flutter_file_dialog
dio
permission_handler
flash (alerting library for when device storage permission is blocked)
For android the flow is:
Make sure you have storage permission first.
I'm using GCS and Firebase so I create short lived secure url to private content. Code not included.
Using path_provider getTemporaryDirectory() get the application's scoped cache directory path.
With Dio save the short lived url to temp cache
Then finally, using flutter_file_dialog open a save to dialog and allow the user where they would like to save their downloaded file to.
Code snippets to see flow:
try {
/// Verify we have storage permissions first.
/// Code snippet showing me calling my devicePermissions service provider
/// to request "storage" permission on Android.
await devicePermissions
.storagePermissions()
.then((granted) async {
/// Get short lived url from google cloud storage for non-public file
final String? shortLivedUrl...
if (shortLivedUrl == null) {
throw Exception('Could not generate a '
'downloadable url. Please try again.');
}
final String url = shortLivedUrl;
print(url);
/// Get just the filename from the short lived (super long) url
final String filename =
Uri.parse(url).path.split("/").last;
print('filename: $filename');
Directory? directory;
if (Platform.isIOS) {
directory = await getDownloadsDirectory();
print(directory?.path);
} else if (Platform.isAndroid) {
/// For Android get the application's scoped cache directory
/// path.
directory = await getTemporaryDirectory();
}
if (directory == null) {
throw Exception('Could not access local storage for '
'download. Please try again.');
}
print(
'Temp cache save path: ${directory.path}/$filename');
/// Use Dio package to download the short lived url to application cache
await dio.download(
url,
'${directory.path}/$filename',
onReceiveProgress: _showDownloadProgress,
);
/// For Android call the flutter_file_dialog package, which will give
/// the option to save the now downloaded file by Dio (to temp
/// application cache) to wherever the user wants including Downloads!
if (Platform.isAndroid) {
final params = SaveFileDialogParams(
sourceFilePath: '${directory.path}/$filename');
final filePath =
await FlutterFileDialog.saveFile(params: params);
print('Download path: $filePath');
}
});
} on DevicePermissionException catch (e) {
print(e);
await OverlayMessage.showAlertDialog(
context,
title: 'Need Storage Permission',
message: devicePermissions.errorMessage,
barrierDismissible: true,
leftAction: (context, controller, setState) {
return TextButton(
child: Text('Cancel'),
onPressed: () async {
controller.dismiss();
},
);
},
rightAction: (context, controller, setState) {
return TextButton(
child: Text('Open App Settings'),
onPressed: () async {
controller.dismiss();
Future.delayed(Duration.zero, () async {
/// Using permission_handler package we can easily give
/// the user the option to tap and open settings from the
/// app and manually allow storage.
await devicePermissions.openManualAppSettings();
});
},
);
},
);
} catch (e) {
print(e.toString());
}

How to make a webserver in a flutter app?

I want to make a webserver locally on the flutter android app that can serve a website. Like that i can connect from any computer using the android device's local IP and the website will appear in the browser.
If you are familiar with Airdroid, it has this feature and i want apply it to my app.
My question is: Is this possible using dart code or do i need to use MethodChannel with existing android libraries? If so what is the best one out there that i can use?
It is possible to do. Take a look at the http_server library that was developed by the Dart team.
Here is a code snippet to get you going.
HttpServer.bind('0.0.0.0', 8080).then((server) {
server.transform(HttpBodyHandler()).listen((HttpRequestBody body) async {
switch (body.request.uri.toString()) {
case '/':
String _content = await _loadStatic('index.html');
body.request.response.statusCode = 200;
body.request.response.headers.set("Content-Type", "text/html; charset=utf-8");
body.request.response.write(_content);
body.request.response.close();
break;
default:
body.request.response.statusCode = 404;
body.request.response.write('Not Found');
body.request.response.close();
}
});
});

How can I read a QR Code from a image in flutter using proper package?

I am building an app using flutter where I want to scan an image(that includes QR image). I am using packages available to read QR codes, but not working for me. Is there any package/solution to read a QR code from an image?
I Tried package:
qr_code_tools: ^0.0.6
Future _getPhotoByGallery() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
String path = image.path;
decode(path);
}
Future decode(String path) async {
print(path);
String data = await QrCodeToolsPlugin.decodeFrom(path);
setState(() {
_data = data;
});
}
I expect the output of QRCode from the selected image of Gallery.
But getting error here:
QrCodeToolsPlugin.decodeFrom(path);//Null, Null something
Even without providing the permission to your external storage, you can still access the gallery as the gallery is native to your device. However, your application will not be able to access the file that the gallery returns since it does not have the necessarry permission. To be sure, go to your app info and see whether the permission for the external storage was given. It is highly probable that you haven't given the permission to access the external storage. There are packages that allow you to check whether a permission was granted and one of them is permission_handler. So whenever you try to access your storage, check the permission first before accessing the gallery.
I might be wrong though.