How to get Downloads path in Flutter? - flutter

I am using the below code to get the path to Downloads folder:
final output = await getExternalStorageDirectory();
RegExp pathToDownloads = new RegExp(r'.+0\/');
final outputPath = '${pathToDownloads.stringMatch(output.path).toString()}Downloads';
The above code generates this string:
/storage/emulated/0/Downloads
But console says "No such file or directory". I created this path string because some answers on stack overflow mention that the above is the location of the downloads folder but it isn't. So what is the path to downloads folder on android and how to get access to it?

You can copy paste run full code below
The following example code write a text file to Downloads folder
Step 1: You can add WRITE_EXTERNAL_STORAGE to AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Step 2: Use package ext_storage https://pub.dev/packages/ext_storage and Request permission with https://pub.dev/packages/permission_handler 4.4.0
dependencies:
flutter:
sdk: flutter
ext_storage: any
permission_handler: 4.4.0
Step 4: Request permission
void requestPermission() {
PermissionHandler().requestPermissions([PermissionGroup.storage]);
}
Step 5: get Downloads folder with ExtStorage.getExternalStoragePublicDirectory
String path = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
working demo
full code
import 'package:flutter/material.dart';
import 'package:ext_storage/ext_storage.dart';
import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() async {
String path = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
print(path);
File file = await File('$path/counter.txt');
file.writeAsString('this is test');
setState(() {
_counter++;
});
}
void requestPermission() {
PermissionHandler().requestPermissions([PermissionGroup.storage]);
}
#override
void initState() {
requestPermission();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

You can get download path without any package. Try that:
Directory dir = Directory('/storage/emulated/0/Download');

Related

Flutter Google Oauth2 signIn how to get _idToken

I am currently working on flutter app and I need to integrate google login. I am using google cloud Oauth and so far I integrated google login. But the issue is in the success response from google the _idtoken is null. Why I don't get the _idtoken
I need the _idToken to authenticate user from backend. What should I do
Below is my main.dart file
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_application_2/api/google_signin_api.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
ElevatedButton(onPressed: signIn, child: const Text("Click"))
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Future signIn() async {
final user = await GoogleSignInApi.login();
//print(user.idtoken)
inspect(user);
}
}
Below is google_signin_api.dart file
import 'package:google_sign_in/google_sign_in.dart';
class GoogleSignInApi {
static final _googleSignIn = GoogleSignIn();
static Future<GoogleSignInAccount?> login() async {
return _googleSignIn.signIn();
}
}
this is the success response
enter image description here

Geolocation.getCurrentPosition from dart:html not working in release mode with NNBD enabled

Does anybody know why the Geolocation.getCurrentPosition() from dart:html doesn't work when running in release mode with sound null safety enabled (flutter run --release -d chrome)?
When making this call I do get an instance of Geoposition back but when I try to access one of it's members I get the following error message:
Uncaught TypeError: n.grq is not a function
at main.dart:39
at WD.a (async_patch.dart:316)
at WD.$2 (async_patch.dart:341)
at VR.$1 (async_patch.dart:292)
at UG.SB (zone.dart:1612)
at UG.ug (zone.dart:1611)
at Tf.$0 (future_impl.dart:118)
at Object.n3 (future_impl.dart:733)
at Y.ib (future_impl.dart:539)
at T7.$0 (future_impl.dart:577)
If I run the same code in debug (flutter run -d chrome or without NNBD flutter run -d chrome --release --no-sound-null-safety everything works fine). A simple App that reproduces this behaviour looks like this (it's a slightly changed version of the default Flutter counter template):
import 'dart:html' as html;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _position = "Unknown";
Future<void> _currentPosition() async {
final geolocation = html.window.navigator.geolocation;
final position = await geolocation.getCurrentPosition();
final latitude = position.coords?.latitude ?? 'n/a';
final longitude = position.coords?.longitude ?? 'n/a';
setState(() {
_position =
'Latitude: $latitude, Longitude: $longitude';
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Your current position is:',
),
Text(
'$_position',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _currentPosition,
tooltip: 'Current position',
child: Icon(Icons.location_on),
),
);
}
}
This turns out to be a bug in Dart. I have created a bug report which can be tracked here: https://github.com/dart-lang/sdk/issues/45562

Flutter get External Storage Directory and MediaStore with path_provider package

I need to open and save simple text files that may be on the device. For example in Documents, Downloads, etc. Wherever files are available for other programs, in android terminology it is "External Storage"
path_provider provides several methods. One of them getExternalStorageDirectory(). The android documentation says:
This method was deprecated in API level 29. To improve user privacy,
direct access to shared/external storage devices is deprecated. When
an app targets Build.VERSION_CODES.Q link
If I use methods path_provider
getExternalStorageDirectory() → /storage/emulated/0/Android/data/myapp.name/files
getApplicationDocumentsDirectory() → /data/user/0/myapp.name/app_flutter
getExternalStorageDirectories(type: StorageDirectory.documents) return List which contains
/storage/emulated/0/Android/data/myapp.name/files/Documents
/storage/1CEE-4019/Android/data/myapp.name/files/Documents
On my android emulator (Api 30) real external documents are located at
/storage/emulated/0/Documents
/storage/emulated/0/Download
How can I access them? As I understand it, there are no alternatives forpath_provider
you va use external_path package
You can copy paste run full code below
You can use package https://pub.dev/packages/ext_storage
code snippet
String pathDownload = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
print(pathDownload);
String pathDoc = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOCUMENTS);
print(pathDoc);
output
I/flutter ( 7361): /storage/emulated/0/Download
I/flutter ( 7361): /storage/emulated/0/Documents
full code
import 'package:flutter/material.dart';
import 'package:ext_storage/ext_storage.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() async {
String pathDownload = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
print(pathDownload);
String pathDoc = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOCUMENTS);
print(pathDoc);
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

How can I play local mp3 on flutter web?

I try a lot packages, but no one can play a mp3 file from local file...
users can chiose a file from systerm
_myFile = await FilePickerCross.importFromStorage(
type: FileTypeCross.audio,
);
then , how can i play it on flutter web page ?
usually crash:
Error: NotSupportedError: Failed to load because no supported source was found.
at Object.createErrorWithStack (http://localhost:62567/dart_sdk.js:4352:12)
at Object._rethrow (http://localhost:62567/dart_sdk.js:38191:16)
at async._AsyncCallbackEntry.new.callback (http://localhost:62567/dart_sdk.js:38185:13)
at Object._microtaskLoop (http://localhost:62567/dart_sdk.js:38017:13)
at _startMicrotaskLoop (http://localhost:62567/dart_sdk.js:38023:13)
at http://localhost:62567/dart_sdk.js:33520:9
like this https://github.com/florent37/Flutter-AssetsAudioPlayer/issues/383
so can any way to play local mp3 file on flutter web?
You can use audioplayers package.
To play audio from local file :
AudioPlayer audioPlayer = AudioPlayer();
playLocal() async {
int result = await audioPlayer.play(localPath, isLocal: true);
}
For a detailed info please take a look at package documentation:
https://pub.dev/packages/audioplayers
You can copy paste run full code below
The following demo code has well tested on flutter web
you can use package https://pub.dev/packages/soundpool and call _soundpool.loadAndPlayUint8List(_myFile.toUint8List());
code snippet
Soundpool _soundpool;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
_soundpool = Soundpool();
...
FilePickerCross _myFile = await FilePickerCross.importFromStorage(
type: FileTypeCross.audio,
);
_soundpool.loadAndPlayUint8List(_myFile.toUint8List());
full code
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:soundpool/soundpool.dart';
Soundpool _soundpool;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
_soundpool = Soundpool();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() async {
FilePickerCross _myFile = await FilePickerCross.importFromStorage(
type: FileTypeCross.audio,
);
_soundpool.loadAndPlayUint8List(_myFile.toUint8List());
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

get local time for different location in flutter

is there a simple way to get time for a different location than the current location in flutter ?
for example the current location is set to Japan,Tokyo and I want the time in Turkey, Istanbul from the system itself not from API
You can copy paste run full code below
You can use package https://pub.dev/packages/timezone
Step 1: download 2019c.tzf from https://github.com/srawlins/timezone/tree/master/lib/data
Step 2: put 2019c.tzf to assets directory
Step 3: Edit pubspec.yaml
working demo
code snippet
void main() async {
WidgetsFlutterBinding.ensureInitialized();
var byteData = await rootBundle.load('assets/2019c.tzf');
initializeDatabase(byteData.buffer.asUint8List());
runApp(MyApp());
}
...
final detroit = getLocation('America/Detroit');
final us = getLocation('US/Pacific');
final tokyo = getLocation('Asia/Tokyo');
nowDetroit = new TZDateTime.now(detroit);
nowUs = new TZDateTime.now(us);
nowTokyo = TZDateTime.now(tokyo);
full code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:timezone/timezone.dart';
import 'package:timezone/standalone.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
var byteData = await rootBundle.load('assets/2019c.tzf');
initializeDatabase(byteData.buffer.asUint8List());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
TZDateTime nowDetroit;
TZDateTime nowUs;
TZDateTime nowTokyo;
void _incrementCounter() {
final detroit = getLocation('America/Detroit');
final us = getLocation('US/Pacific');
final tokyo = getLocation('Asia/Tokyo');
nowDetroit = new TZDateTime.now(detroit);
nowUs = new TZDateTime.now(us);
nowTokyo = TZDateTime.now(tokyo);
_counter++;
setState(() {
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(' America/Detroit ${nowDetroit.toString()}'),
Text(' US/Pacific ${nowUs.toString()}'),
Text(' Asia/Tokyo ${nowTokyo.toString()}'),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}