Skip to content

Commit

Permalink
MANAGE_EXTERNAL_STORAGE Permision deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyBasdfg authored and AnthonyBasdfg committed Jan 15, 2025
1 parent 94c9466 commit 4979863
Show file tree
Hide file tree
Showing 14 changed files with 462 additions and 505 deletions.
16 changes: 12 additions & 4 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:label="MoneyT"
Expand Down Expand Up @@ -35,6 +33,16 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- Agregar provider para compartir archivos -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
Expand All @@ -43,8 +51,8 @@
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="application/octet-stream" />
</intent>
</queries>
</manifest>
6 changes: 6 additions & 0 deletions android/app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="backup_files"
path="backups/" />
</paths>
27 changes: 14 additions & 13 deletions lib/core/di/injection_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../data/local/database.dart';
import '../../data/repositories/auth_repository_impl.dart';
import '../../data/repositories/backup_repository_impl.dart';
import '../../data/repositories/category_repository_impl.dart';
import '../../data/repositories/account_repository_impl.dart';
import '../../data/repositories/transaction_repository_impl.dart';
Expand All @@ -31,6 +30,7 @@ import '../../domain/usecases/transaction_usecases.dart';
import '../../presentation/providers/auth_provider.dart';
import '../../presentation/providers/drawer_provider.dart';
import '../l10n/language_manager.dart'; // Import LanguageManager
import '../../data/repositories/backup_repository_impl.dart' as backup_impl;

final getIt = GetIt.instance;

Expand Down Expand Up @@ -59,7 +59,19 @@ Future<void> initializeDependencies() async {
getIt.registerSingleton<TransactionDao>(database.transactionDao);
getIt.registerSingleton<ContactDao>(database.contactDao);

// Services
// First register BackupRepository
getIt.registerSingleton<BackupRepository>(
backup_impl.BackupRepositoryImpl(database: getIt<AppDatabase>()),
);

// Then register services that depend on repositories
getIt.registerLazySingleton<BackupService>(
() => BackupService(
getIt<BackupRepository>(),
getIt<SharedPreferences>(),
),
);

getIt.registerLazySingleton<SyncService>(
() => SyncService(
auth: getIt<FirebaseAuth>(),
Expand All @@ -72,13 +84,6 @@ Future<void> initializeDependencies() async {
() => SyncManager(getIt<SyncService>()),
);

getIt.registerLazySingleton<BackupService>(
() => BackupService(
database: getIt<AppDatabase>(),
prefs: getIt<SharedPreferences>(),
),
);

// Repositories
getIt.registerSingleton<TransactionRepository>(
TransactionRepositoryImpl(getIt<TransactionDao>()),
Expand All @@ -99,10 +104,6 @@ Future<void> initializeDependencies() async {
ContactRepositoryImpl(getIt<ContactDao>()),
);

getIt.registerSingleton<BackupRepository>(
BackupRepositoryImpl(getIt<BackupService>()),
);

getIt.registerSingleton<AuthRepository>(
AuthRepositoryImpl(
auth: getIt<FirebaseAuth>(),
Expand Down
2 changes: 2 additions & 0 deletions lib/core/l10n/translations/base_translations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ abstract class BaseTranslations {
String get notFound => 'Not Found';
String get required => 'This field is required';
String get invalidAmount => 'Invalid amount';
String get restore => 'Restore';

// Login
String get signIn => 'Sign In';
Expand Down Expand Up @@ -307,6 +308,7 @@ abstract class BaseTranslations {
notFound;
required;
invalidAmount;
restore;

// Auth errors
invalidCredentials;
Expand Down
58 changes: 58 additions & 0 deletions lib/core/l10n/translations/languages/en_translations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -516,4 +516,62 @@ class EnTranslations extends BaseTranslations {

@override
String getText(String key) => key;

// Backup related
@override
String get backup => 'Backup';

@override
String get backups => 'Backups';

@override
String get createBackup => 'Create Backup';

@override
String get restoreBackup => 'Restore Backup';

@override
String get deleteBackup => 'Delete Backup';

@override
String get noBackups => 'No backups available';

@override
String get backupCreated => 'Backup created successfully';

@override
String get backupRestored => 'Backup restored successfully';

@override
String get backupDeleted => 'Backup deleted successfully';

@override
String get backupError => 'Error during backup operation';

@override
String get restoreBackupConfirmation => 'Are you sure you want to restore this backup? Current data will be replaced.';

@override
String get deleteBackupConfirmation => 'Are you sure you want to delete this backup?';

@override
String get backupSettings => 'Backup Settings';

@override
String get backupDirectory => 'Backup Directory';

@override
String get changeDirectory => 'Change Directory';

@override
String get resetDirectory => 'Reset Directory';

@override
String get backupDirectoryUpdated => 'Backup directory updated';

@override
String get backupDirectoryReset => 'Backup directory reset to default';

@override
String get restore => 'Restore';
}
21 changes: 21 additions & 0 deletions lib/core/l10n/translations/languages/es_translations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,24 @@ class EsTranslations extends BaseTranslations {
@override
String get deleteBackupConfirmation => '¿Está seguro de eliminar este respaldo?';

@override
String get backupSettings => 'Configuración de Respaldos';

@override
String get backupDirectory => 'Directorio de Respaldos';

@override
String get changeDirectory => 'Cambiar Directorio';

@override
String get resetDirectory => 'Restablecer Directorio';

@override
String get backupDirectoryUpdated => 'Directorio de respaldo actualizado';

@override
String get backupDirectoryReset => 'Directorio de respaldo restablecido a predeterminado';

@override
String get settings => 'Configuración';

Expand Down Expand Up @@ -610,4 +628,7 @@ class EsTranslations extends BaseTranslations {

@override
String get syncNever => 'Nunca';

@override
String get restore => 'Restaurar';
}
6 changes: 6 additions & 0 deletions lib/data/local/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class AppDatabase extends _$AppDatabase {
TransactionDao get transactionDao => TransactionDao(this);
ContactDao get contactDao => ContactDao(this);

Future<String> getDatabasePath() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'app_database.sqlite'));
return file.path;
}

@override
MigrationStrategy get migration => MigrationStrategy(
onCreate: (Migrator m) async {
Expand Down
82 changes: 71 additions & 11 deletions lib/data/repositories/backup_repository_impl.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,89 @@
import 'dart:io';
import '../services/backup_service.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:file_picker/file_picker.dart';
import '../local/database.dart';
import '../../domain/repositories/backup_repository.dart';

class BackupRepositoryImpl implements BackupRepository {
final BackupService _backupService;
final AppDatabase database;

BackupRepositoryImpl(this._backupService);
BackupRepositoryImpl({required this.database});

Future<Directory> get _backupDirectory async {
final appDir = await getApplicationDocumentsDirectory();
final backupDir = Directory('${appDir.path}/backups');
if (!await backupDir.exists()) {
await backupDir.create(recursive: true);
}
return backupDir;
}

@override
Future<File> createBackup() async {
final backupDir = await _backupDirectory;
final timestamp = DateTime.now().millisecondsSinceEpoch;
final backupFile = File('${backupDir.path}/backup_$timestamp.db');

// Copiar la base de datos actual
final dbPath = await database.getDatabasePath();
final currentDb = File(dbPath);
await currentDb.copy(backupFile.path);

return backupFile;
}

@override
Future<String> createBackup() async {
return await _backupService.createBackup();
Future<void> shareBackup(File backupFile) async {
await Share.shareXFiles([XFile(backupFile.path)]);
}

@override
Future<void> restoreBackup(String backupPath) async {
await _backupService.restoreBackup(backupPath);
Future<File?> importBackup() async {
try {
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['db'],
);

if (result != null) {
final backupDir = await _backupDirectory;
final importFile = File(result.files.single.path!);
final newPath = '${backupDir.path}/${result.files.single.name}';
return await importFile.copy(newPath);
}
return null;
} catch (e) {
rethrow;
}
}

@override
Future<List<FileSystemEntity>> listBackups() async {
return await _backupService.listBackups();
Future<List<File>> listBackups() async {
final backupDir = await _backupDirectory;
return backupDir
.listSync()
.whereType<File>()
.where((file) => file.path.endsWith('.db'))
.toList();
}

@override
Future<void> restoreBackup(File backupFile) async {
final dbPath = await database.getDatabasePath();
final currentDb = File(dbPath);

// Cerrar la conexión con la base de datos
await database.close();

// Copiar el backup sobre la base de datos actual
await backupFile.copy(currentDb.path);
}

@override
Future<void> deleteBackup(String backupPath) async {
await _backupService.deleteBackup(backupPath);
Future<void> deleteBackup(File backupFile) async {
if (await backupFile.exists()) {
await backupFile.delete();
}
}
}
Loading

0 comments on commit 4979863

Please sign in to comment.