Skip to content

Commit

Permalink
Merge pull request #34 from mario-bermonti:export-data
Browse files Browse the repository at this point in the history
Export-data
  • Loading branch information
mario-bermonti authored Jan 25, 2024
2 parents 9646598 + 50b8ef6 commit 1d34389
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mdigit_span_tasks">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:label="mdigit_span_tasks"
android:name="${applicationName}"
Expand Down
10 changes: 10 additions & 0 deletions lib/src/app_bar/app_bar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
import 'package:mdigit_span_tasks/src/export_data/view/export_button.dart';

final AppBar appBar = AppBar(
title: const Text('mDigitSpanTask'),
centerTitle: true,
actions: [
ExportButton(),
],
);
61 changes: 61 additions & 0 deletions lib/src/export_data/controller/data_exporter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'dart:io';

import 'package:cognitive_data/errors.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

class DataExporter {
final String dbName;
late final File db;
late final String dbPath;
late final File destinationFile;

DataExporter({required this.dbName});

/// Request storage permission
Future<void> requestPermission() async {
if (Platform.isAndroid) {
bool granted = await Permission.storage.request().isGranted;
if (!granted) {
throw PermissionNotGrantedException();
}
}
}

/// Get db from disk so it can be copied
/// It assumes the db is in the [getApplicationDocumentsDirectory] dir
/// with the name [dbName]. This method does not modify the original db.
Future<void> getDB() async {
final Directory dir = await getApplicationDocumentsDirectory();
dbPath = "${dir.path}/$dbName";
db = File(dbPath);
}

/// Get destination file on which to save the db copy.
/// The destination file will be in the `Download` folder and will have the
/// same name as the dbs.
/// Currently only android is supported.
Future<void> initDestinationFile() async {
Directory destinationDir = await _initDestinationDir();
final String destinationPath = '${destinationDir.path}/$dbName';
destinationFile = File(destinationPath);
}

/// Gets the directory to which the db will be exported.
/// Currently only android is supported and the destination dir is a
/// directory named `mDigitSpanTasks` in the android `Download` folder.
/// It creates the directory with its parent dirs if these do not exist.
Future<Directory> _initDestinationDir() async {
Directory downloadsDir =
Directory('/storage/emulated/0/Download/mDigitSpanTasks');
await downloadsDir.create(recursive: true);

return downloadsDir;
}

/// Create copy of db in the path specified by [destinationFile].
/// Does not alter the original db.
Future<void> copyDB() async {
await db.copy(destinationFile.path);
}
}
15 changes: 15 additions & 0 deletions lib/src/export_data/view/export_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
import 'package:mdigit_span_tasks/src/services/services/export_dbs.dart';

/// [ExportButton] Is used by the user to export the data from the app
class ExportButton extends StatelessWidget {
const ExportButton({super.key});

@override
Widget build(BuildContext context) {
return IconButton(
icon: const Icon(Icons.send_to_mobile),
onPressed: () async => await exportDBs(),
);
}
}
16 changes: 16 additions & 0 deletions lib/src/services/services/export_dbs.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:mdigit_span_tasks/src/export_data/controller/data_exporter.dart';

/// Export dbs to make them accessible to users
Future<void> exportDBs() async {
await _exportDB(dbName: 'ds_forward.sqlite3');
await _exportDB(dbName: 'ds_backwards.sqlite3');
}

/// Export the db specified in [dbName]
Future<void> _exportDB({required String dbName}) async {
DataExporter dataExporter = DataExporter(dbName: dbName);
await dataExporter.requestPermission();
await dataExporter.getDB();
await dataExporter.initDestinationFile();
await dataExporter.copyDB();
}
2 changes: 2 additions & 0 deletions lib/src/task_list/view/task_list_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mdigit_span_tasks/src/app_bar/app_bar.dart';
import 'task_buttons.dart';

class TaskListPage extends StatelessWidget {
Expand All @@ -7,6 +8,7 @@ class TaskListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBar,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies:
git:
url: https://github.com/mario-bermonti/cognitive_data.git
path_provider: ^2.0.15
permission_handler: ^10.4.5

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 1d34389

Please sign in to comment.