I'm able to load file from my code. But the problem is, how to load the file from online server which is from this link- https://freevpn.gg/c/59.139.187.41/udp
My current code is-
var contennt=await rootBundle.loadString('assets/vpnconfig.ovpn');
You could use flutter cache manager to download the file and then read it. https://pub.dev/packages/flutter_cache_manager
String url = 'your_link';
final file = await DefaultCacheManager().getSingleFile(url);
var content = await file.readAsString();
dependencies:
flutter_filereader: ^2.2.0
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_filereader_example/file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
Permission.storage.request();
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String taskId;
Map<String, String> iosfiles = {
"docx": "assets/files/docx.docx", // IOS test
"doc": "assets/files/doc.doc", // IOS test
"xlsx": "assets/files/xlsx.xlsx", // IOS test
"xls": "assets/files/xls.xls", // IOS test
"pptx": "assets/files/pptx.pptx", // IOS test
"ppt": "assets/files/ppt.ppt", // IOS test
"pdf": "assets/files/pdf.pdf", // IOS test
"txt": "assets/files/txt.txt", // IOS test
"jpg": "assets/files/jpg.jpg", //
"jpeg": "assets/files/jpeg1.jpeg", //
"png": "assets/files/png.png", //
};
Map<String, String> androidfiles = {
"docx": "assets/files/docx.docx", // android test
"doc": "assets/files/doc.doc", // android test
"xlsx": "assets/files/xlsx.xlsx", // android test
"xls": "assets/files/xls.xls", // android test
"pptx": "assets/files/pptx.pptx", // android test
"ppt": "assets/files/ppt.ppt", // android test
"pdf": "assets/files/pdf.pdf", // android test
"txt": "assets/files/txt.txt" // android test
};
Map<String, String> files;
#override
void initState() {
if (Platform.isAndroid) {
files = androidfiles;
} else {
files = iosfiles;
}
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('File Reader'),
),
body: ListView.builder(
itemBuilder: (ctx, index) {
return item(files.keys.elementAt(index), files.values.elementAt(index));
},
itemCount: files.length,
),
);
}
item(String type, String path) {
return GestureDetector(
onTap: () {
onTap(type, path);
},
child: Container(
alignment: Alignment.center,
height: 50,
margin: EdgeInsetsDirectional.only(bottom: 5),
color: Colors.blue,
child: Center(
child: Text(
type,
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
);
}
onTap(String type, String assetPath) async {
String localPath = await fileLocalName(type, assetPath);
if (!await File(localPath).exists()) {
if (!await asset2Local(type, assetPath)) {
return;
}
}
Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
return FileReaderPage(
filePath: localPath,
);
}));
}
fileLocalName(String type, String assetPath) async {
String dic = await _localSavedDir() + "/filereader/files/";
return dic + base64.encode(utf8.encode(assetPath)) + "." + type;
}
fileExists(String type, String assetPath) async {
String fileName = await fileLocalName(type, assetPath);
if (await File(fileName).exists()) {
return true;
}
return false;
}
asset2Local(String type, String assetPath) async {
if (Platform.isAndroid) {
if (!await Permission.storage.isGranted) {
debugPrint("没有存储权限");
return false;
}
}
File file = File(await fileLocalName(type, assetPath));
if (await fileExists(type, assetPath)) {
await file.delete();
}
await file.create(recursive: true);
//await file.create();
debugPrint("文件路径->" + file.path);
ByteData bd = await rootBundle.load(assetPath);
await file.writeAsBytes(bd.buffer.asUint8List(), flush: true);
return true;
}
_localSavedDir() async {
Directory dic;
if (defaultTargetPlatform == TargetPlatform.android) {
dic = await getExternalStorageDirectory();
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
dic = await getApplicationDocumentsDirectory();
}
return dic.path;
}
}
Related
When I try to pull data from the jsonplaceholder API and put it on the screen, I don't have any problems, but when I try to change the data in this link (https://reqres.in/api/users?page=2 ) on the reqres.io site with the same codes, only by changing the API and model, the text no data appears on the screen. I'm getting it can you help me ?
My project with JsonPlaceHolder
main.dart
import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() =\> runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State\<Home\> createState() =\> \_HomeState();
}
class \_HomeState extends State\<Home\> {
List\<JsonModel\>? \_postItems;
bool \_isLoading = false;
String? \_errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future\<void\> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (\_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (\_postItems == null || \_postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: \_postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(\_postItems!\[index\].name),
);
},
);
}
}
}`
api_service.dart
`import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<JsonModel>?> fetchApi() async {
final res = await Dio().get("https://jsonplaceholder.typicode.com/users");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!;
if (data is List) {
return data.map((e) =\> JsonModel.fromMap(e)).toList();
}
}
return <JsonModel>[];
}
}
`
conclusion
conclusion
My project with reqres.in
main.dart
`import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() =\> runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<ReqresModel>? _postItems;
bool _isLoading = false;
String? _errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (_postItems == null || _postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: _postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(\_postItems!\[index\].data\[index\].firstName),
);
},
);
}
}
}`
api_servise.dart
`import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<ReqresModel>?> fetchApi() async {
final res = await Dio().get("https://reqres.in/api/users?page=2");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!;
if (data is List) {
return data.map((e) => ReqresModel.fromMap(e)).toList();
}
}
return <ReqresModel>[];
}
}`
conclusion
conclusion
**Thank you **
I sent the API using Postman, there was no problem, I don't think the problem was caused by the API, sorry for my bad English
Change your api_service.dart for reqres.in project with following code.
First api which returns List directly, but second api which return Json which has data as List
Edited
main.dart
import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<ReqresModel>? _postItems;
bool _isLoading = false;
String? _errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (_postItems == null || _postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: _postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_postItems![index].firstName),//Updated here
);
},
);
}
}
}
api_service.dart
import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<ReqresModel>?> fetchApi() async {
final res = await Dio().get("https://reqres.in/api/users?page=2");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!['data'];//Updated here
if (data is List) {
return data.map((e) => ReqresModel.fromMap(e)).toList();
}
}
return <ReqresModel>[];
}
}
ReqresModel - should be updated
//Updated here
class ReqresModel {
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
ReqresModel(
{this.id, this.email, this.firstName, this.lastName, this.avatar});
ReqresModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
}
I'm working with SfMaps syncfusion map and when I try to load geojson data from the local assets folder using the MapShapeSource.asset() property and everything works fine. But I'm having problems when I want to load geojson data as a result from api calling (GET / POST) using the http package flutter.
// Function to load data json from API
Future<void> loadGeojsonDataFromAPI() async {
setState(() => loading = true);
try {
final response = await http.post(
Uri.parse("some url"),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: body);
if (response.statusCode >= 400) {
throw Exception('statusCode=${response.statusCode}');
}
setState(() {
loading = false;
data = jsonDecode(response.body);
});
} catch (e) {
setState(() => loading = false);
debugPrint("Error load data: $e");
return;
}
}
// Loadjson data from API in Map Shape Source.network() but not sure how to do it
dataSource = MapShapeSource.network(
'url',
shapeDataField: 'name',
);
I believe this can be solved using MapShapeSource.network(), but am still confused about how to use it.
any kind of help is very much appreciated
You can load the area shape JSON data from the web/network using the MapShapeSource.network() constructor available in the maps widget. We have shared the user guide documentation and sample below for your reference.
UG, https://help.syncfusion.com/flutter/maps/getting-started#from-network
Code snippet:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Syncfusion Flutter Maps',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Syncfusion Flutter Maps'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late MapShapeSource _dataSource;
late List<IndiaMap> _mapDetails;
Future<bool> _fetchNetworkJsonDetails() async {
if (_mapDetails.isNotEmpty) {
return true;
}
final http.Response response = await http
.get(Uri.tryParse('https://api.npoint.io/b127f79b6e9c883d0aba')!);
if (response.statusCode == 200) {
Map<String, dynamic> responseJson = json.decode(response.body);
List<dynamic> countriesCoordinates = responseJson['features'];
for (int i = 0; i < countriesCoordinates.length; i++) {
Map<String, dynamic> data = countriesCoordinates[i]['properties'];
IndiaMap mapDetail = IndiaMap.fromJsonMap(data);
_mapDetails.add(mapDetail);
}
_dataSource = MapShapeSource.network(
'https://api.npoint.io/b127f79b6e9c883d0aba',
shapeDataField: 'name',
dataCount: _mapDetails.length,
primaryValueMapper: (index) => _mapDetails[index].state,
);
return true;
} else {
throw Exception('Failed to load JSON');
}
}
#override
void initState() {
_mapDetails = [];
super.initState();
}
#override
void dispose() {
_mapDetails.clear();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: FutureBuilder(
future: _fetchNetworkJsonDetails(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
color: const Color.fromRGBO(15, 59, 177, 0.5),
strokeColor: Colors.white,
strokeWidth: 0.5,
),
],
),
);
} else {
return const Center(child: CircularProgressIndicator());
}
}),
);
}
}
class IndiaMap {
late String state;
late String country;
IndiaMap(this.state, this.country);
IndiaMap.fromJsonMap(Map data) {
state = data['name'];
country = data['admin'];
}
}
I have code that I use to write data to a file (such as global settings for an application). I write down the data and see. But the problem is that I do not understand how to take these mini data from another page. For example I wrote the word "Test" and I want and I want to assign that word to some variable in another page. I will be grateful for your help. Here is my code:
import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Reading and Writing to Storage",
home: Home(
storage: Storage(),
),
);
}
}
class Home extends StatefulWidget {
final Storage storage;
Home({Key key, #required this.storage}) : super(key: key);
#override
HomeState createState() => HomeState();
}
class HomeState extends State<Home> {
TextEditingController controller = TextEditingController();
String state;
Future<Directory> _appDocDir;
#override
void initState() {
super.initState();
widget.storage.readData().then((String value) {
setState(() {
state = value;
});
});
}
Future<File> writeData() async {
setState(() {
state = controller.text;
controller.text = '';
});
return widget.storage.writeData(state);
}
void getAppDirectory() {
setState(() {
_appDocDir = getApplicationDocumentsDirectory();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reading and Writing Files'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('${state ?? "File is Empty"}'),
TextField(
controller: controller,
),
RaisedButton(
onPressed: writeData,
child: Text('Write to File'),
),
RaisedButton(
child: Text("Get DIR path"),
onPressed: getAppDirectory,
),
FutureBuilder<Directory>(
future: _appDocDir,
builder:
(BuildContext context, AsyncSnapshot<Directory> snapshot) {
Text text = Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
text = Text('Path: ${snapshot.data.path}');
} else {
text = Text('Unavailable');
}
}
return new Container(
child: text,
);
},
)
],
),
),
);
}
}
class Storage {
Future<String> get localPath async {
final dir = await getApplicationDocumentsDirectory();
return dir.path;
}
Future<File> get localFile async {
final path = await localPath;
return File('$path/db.txt');
}
Future<String> readData() async {
try {
final file = await localFile;
String body = await file.readAsString();
return body;
} catch (e) {
return e.toString();
}
}
Future<File> writeData(String data) async {
final file = await localFile;
return file.writeAsString("$data");
}
}
And scrin:
You can pass the value to other page using Navigator and parameter.
class NewScreen extends StatelessWidget {
final String data;
NewScreen({this.data});
...
}
When you move to 'NewScreen' by using Navigator at your 'Home' page,
pass the data what you transfer.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewScreen(data: 'Test'),
),
);
I have added some routes to my flutter app so that when a specific link is pressed a specific page will be opened
This is the source code of the main page
import 'dart:convert';
import 'package:admob_flutter/admob_flutter.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:catcher/catcher.dart';
import 'package:dynamic_theme/dynamic_theme.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:videos/c.dart';
import 'package:flutter/foundation.dart';
import 'package:videos/post.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'database/database.dart';
import 'database/database/mobile.dart' as mobile;
import 'src/app_route.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
FirebaseAdMob.instance.initialize(appId: APP_ID);
Admob.initialize(APP_ID);
await AndroidAlarmManager.initialize();
CatcherOptions debugOptions =CatcherOptions(DialogReportMode(), [kIsWeb?ConsoleHandler(): EmailManualHandler(["ahmad.rajab#windowslive.com"])]);
CatcherOptions releaseOptions = CatcherOptions(DialogReportMode(), [
kIsWeb?ToastHandler():EmailManualHandler(["ahmad.rajab#windowslive.com"])
]);
Catcher(MyApp(), debugConfig: debugOptions, releaseConfig: releaseOptions);
}
class MyApp extends StatefulWidget{
#override
State<StatefulWidget> createState()=>MyAppState();
}
class MyAppState extends State<MyApp> {
static Future configureDatabase()async{
/*database = await openDatabase(DATABASE_NAME, version: DATABASE_VERSION,
onCreate: (Database db, int version) async {
await db.execute('create table $WATCHED_VIDEOS ($VIDEO_ID text,$REACHED_SECOND integer default 0,$NOTE text)');
await db.execute('create table $TABLE_FAVORITE_VIDEOS ($VIDEO_TITLE text,$VIDEO_ID text,$VIDEO_DESCRIPTION text,$VIDEO_THUMBURL text)');
await db.execute('create table $CHANNELS ($ID integer ,$NAME text,$LINK text, $PICTURE_LINK text,$VIEWED integer default 0,$GET_NOTIFICATIONS integer default 1,$LAST_VIDEO_TITLE text)');
},
onUpgrade: (db, oldVersion, newVersion)async {
var tableColumns= await db.query('PRAGMA table_info($WATCHED_VIDEOS)');
bool noteColumnExists=false;
for(int c=0;c<tableColumns.length;c++){
if(tableColumns[c]['name'].toString()==NOTE)noteColumnExists=true;
}
if(!noteColumnExists) await db.execute('alter table $WATCHED_VIDEOS add $NOTE text');
},);
*/
}
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
#override
void initState() {
super.initState();
initialiseNotification();
initialiseTimeZone();
showDailyReminderNotification();
configureDailyNewVideosFitch();
}
void configureDailyNewVideosFitch()async{
await AndroidAlarmManager.periodic(const Duration(days: 1),DAILY_NEW_VIDEOS_FETCH_ALARAM_ID , ()async{
Database d=RepositoryProvider.of<Database>(context);
List<Channel>subscribedChannels=await (d.select($ChannelsTable(d))..where((tbl) => tbl.getNotifications.equals(1))).get();
String channelsIds='';
for(int i=0;i<subscribedChannels.length;i++)channelsIds+=subscribedChannels[i].link+"/";
Map<String,String> map=Map();
map['channels']=channelsIds;
Post p=Post(context,'getVideosFromTime.php',map);
await p.fetchPost();
if(p.connectionSucceed){
dynamic resultJson=json.decode(p.result);
if(resultJson['result']=='success'){
for(int i=0;i<resultJson['data'].length;i++){
dynamic videoJson=resultJson['data'][i];
await flutterLocalNotificationsPlugin.show(videoJson['id'], videoJson['channelName'], videoJson['title'],
NotificationDetails(
android: AndroidNotificationDetails(
APP_NAME,
APP_NAME, NEW_VIDEO_AVAILABLE,
icon: '#mipmap/ic_launcher',
ticker: videoJson['title']
),
),
payload:'/watch?v='+videoJson['videoId']
);
}
}
}
},rescheduleOnReboot: true);
}
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
void showDailyReminderNotification()async{
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(APP_NAME,
APP_NAME, 'dailyReminder'+APP_NAME,
icon: '#mipmap/ic_launcher',
ticker: TIME_TO_LEARN);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.periodicallyShow(DAILY_REMINDER_NOTIFICATION_ID, TIME_TO_LEARN,
TIME_TO_LEARN_DESCRIPTION, RepeatInterval.daily, platformChannelSpecifics,
androidAllowWhileIdle: false);
}
void initialiseTimeZone()async{
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(await FlutterNativeTimezone.getLocalTimezone()));
}
void initialiseNotification()async{
flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
/*onDidReceiveLocalNotification: onDidReceiveLocalNotification*/);
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
await flutterLocalNotificationsPlugin.cancel(DAILY_REMINDER_NOTIFICATION_ID);
}
Future selectNotification(String payload) async {
if(payload!=null)Navigator.pushNamed(context, payload);
}
#override
Widget build(BuildContext context) {
return DynamicTheme(
defaultBrightness: Brightness.light,
data: (brightness) => ThemeData(
primarySwatch: PRIMARY_COLOR,
brightness: brightness
),
themedWidgetBuilder: (context, data) {
return RepositoryProvider<Database>(
create:(context)=>mobile.constructDb() ,
child: BlocProvider(
create: (context){
//final db = RepositoryProvider.of<Database>(context);
//return AppBloc(db);
},
child: MaterialApp.router(
//title: 'Books App',
theme: data,
routerDelegate: _routerDelegate,
routeInformationParser: _routeInformationParser,
)
)
);
}
);
}
}
MobileAdTargetingInfo targetingInfo = MobileAdTargetingInfo(
// ignore: deprecated_member_use
gender: MobileAdGender.unknown,
childDirected: true
);
class AdmobAdd extends StatelessWidget{
#override
Widget build(BuildContext context) {
return !PRO?AdmobBanner(
adUnitId: kReleaseMode?BANNER_AD_UNIT_ID:BannerAd.testAdUnitId,
adSize: AdmobBannerSize.BANNER,
):Container();
}
}
InterstitialAd myInterstitial = InterstitialAd(
adUnitId: InterstitialAd.testAdUnitId,
targetingInfo: targetingInfo,
);
this is the source code of the routes configuration file
import 'package:catcher/catcher.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:videos/home.dart';
import 'package:videos/video.dart';
class AppRouteInformationParser extends RouteInformationParser<AppRoutePath> {
#override
Future<AppRoutePath> parseRouteInformation(
RouteInformation routeInformation) async {
final uri = Uri.parse(routeInformation.location);
// Handle '/'
if (uri.pathSegments.length == 0) {
return AppRoutePath.home();
}
// Handle '/watch?v=fsdfsdfsd
if (uri.pathSegments.length == 1) {
if (!uri.pathSegments[0].startsWith('/watch?')) return AppRoutePath.unknown();
if(uri.pathSegments[0].startsWith('/watch?v=')){
var videoId=uri.queryParameters['v'];
return AppRoutePath.video(videoId);
/*var remaining = uri.pathSegments[1];
var id = int.tryParse(remaining);
if (id == null) return AppRoutePath.unknown();
return AppRoutePath.details(id);*/
}
}
// Handle unknown routes
return AppRoutePath.unknown();
}
#override
RouteInformation restoreRouteInformation(AppRoutePath path) {
if (path.isUnknown) {
return RouteInformation(location: '/404');
}
if (path.isHomePage) {
return RouteInformation(location: '/');
}
if(path.isVideoPage){
return RouteInformation(location: '/watch?v=${path.id}');
}
if (path.isDetailsPage) {
return RouteInformation(location: '/book/${path.id}');
}
return null;
}
}
class AppRouterDelegate extends RouterDelegate<AppRoutePath>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<AppRoutePath> {
final GlobalKey<NavigatorState> navigatorKey;
//Book _selectedBook;
bool show404 = false;
String videoId;
/*List<Book> books = [
Book('Stranger in a Strange Land', 'Robert A. Heinlein'),
Book('Foundation', 'Isaac Asimov'),
Book('Fahrenheit 451', 'Ray Bradbury'),
];*/
AppRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();
AppRoutePath get currentConfiguration {
if (show404) {
return AppRoutePath.unknown();
}
if(videoId!=null) return AppRoutePath.video(videoId);
/*return _selectedBook == null
? AppRoutePath.home()
: AppRoutePath.details(books.indexOf(_selectedBook));*/
return AppRoutePath.home();
}
#override
Widget build(BuildContext context) {
return Navigator(
key: Catcher.navigatorKey,
pages: [
MaterialPage(
key: ValueKey('Home'),
child: MyHomePage()
),
if (show404)
MaterialPage(key: ValueKey('Unknown'), child: UnknownScreen())
else if(videoId!=null) VideoPageRoute(videoId: videoId)
/*else if (_selectedBook != null)
BookDetailsPage(book: _selectedBook)*/
],
onPopPage: (route, result) {
if (!route.didPop(result)) {
return false;
}
// Update the list of pages by setting _selectedBook to null
//_selectedBook = null;
videoId=null;
show404 = false;
notifyListeners();
return true;
},
);
}
#override
Future<void> setNewRoutePath(AppRoutePath path) async {
if (path.isUnknown) {
//_selectedBook = null;
videoId=null;
show404 = true;
return;
}
/*if (path.isDetailsPage) {
if (path.id < 0 || path.id > books.length - 1) {
show404 = true;
return;
}
_selectedBook = books[path.id];
} else {
_selectedBook = null;
}*/
show404 = false;
}
void videoNotFound(){
videoId=null;
show404=true;
notifyListeners();
}
/*void _handleBookTapped(Book book) {
_selectedBook = book;
notifyListeners();
}*/
}
class AppRoutePath {
final String id;
final bool isUnknown;
AppRoutePath.home()
: id = null,
isUnknown = false;
AppRoutePath.details(this.id) : isUnknown = false;
AppRoutePath.video(this.id): isUnknown=false;
AppRoutePath.unknown()
: id = null,
isUnknown = true;
bool get isHomePage => id == null;
bool get isDetailsPage => id != null;
bool get isVideoPage => id!=null;
}
/*class BooksListScreen extends StatelessWidget {
final List<Book> books;
final ValueChanged<Book> onTapped;
BooksListScreen({
#required this.books,
#required this.onTapped,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
for (var book in books)
ListTile(
title: Text(book.title),
subtitle: Text(book.author),
onTap: () => onTapped(book),
)
],
),
);
}
}
*/
/*class BookDetailsScreen extends StatelessWidget {
final Book book;
BookDetailsScreen({
#required this.book,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (book != null) ...[
Text(book.title, style: Theme.of(context).textTheme.headline6),
Text(book.author, style: Theme.of(context).textTheme.subtitle1),
],
],
),
),
);
}
}
*/
class UnknownScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('404!'),
),
);
}
}
The problem is that I have several screens that has no specific url and I do not want to provide them with routes, I want simply to use Navigator.push()
That is working fine, but when pressing the back button or when I use Navigator.pop() the app closes entirely instead of navigating back to the previous page
How can I use Navigator.pushNamed only for named routes and use Navigator.push for other pages without causing the problem to occur
Thanks in advance
In my flutter app, I store some images in cache directory and some files in application document directory, now I want to add possibility to my users to delete the cache dir and app dir,
How can I achieve this?
You need path_provider package
Then try this code:
Future<void> _deleteCacheDir() async {
final cacheDir = await getTemporaryDirectory();
if (cacheDir.existsSync()) {
cacheDir.deleteSync(recursive: true);
}
}
Future<void> _deleteAppDir() async {
final appDir = await getApplicationSupportDirectory();
if(appDir.existsSync()){
appDir.deleteSync(recursive: true);
}
}
This code may help you :
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(
MaterialApp(
title: 'Reading and Writing Files',
home: FlutterDemo(storage: CounterStorage()),
),
);
}
class CounterStorage {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/counter.txt');
}
Future<int> readCounter() async {
try {
final file = await _localFile;
// Read the file
String contents = await file.readAsString();
return int.parse(contents);
} catch (e) {
// If encountering an error, return 0
return 0;
}
}
Future<File> writeCounter(int counter) async {
final file = await _localFile;
// Write the file
return file.writeAsString('$counter');
}
}
class FlutterDemo extends StatefulWidget {
final CounterStorage storage;
FlutterDemo({Key key, #required this.storage}) : super(key: key);
#override
_FlutterDemoState createState() => _FlutterDemoState();
}
class _FlutterDemoState extends State<FlutterDemo> {
int _counter;
#override
void initState() {
super.initState();
widget.storage.readCounter().then((int value) {
setState(() {
_counter = value;
});
});
}
Future<File> _incrementCounter() {
setState(() {
_counter++;
});
// Write the variable as a string to the file.
return widget.storage.writeCounter(_counter);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Reading and Writing Files')),
body: Center(
child: Text(
'Button tapped $_counter time${_counter == 1 ? '' : 's'}.',
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Also, you can find very helpful document here:
https://github.com/flutter/samples/blob/master/INDEX.md