153 lines
4.9 KiB
Dart
153 lines
4.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
/// Service for managing blocked phone numbers
|
|
class BlockService {
|
|
static const String _blockedNumbersKey = 'blocked_numbers';
|
|
static const MethodChannel _channel = MethodChannel('com.example.block');
|
|
|
|
// Private constructor
|
|
BlockService._privateConstructor();
|
|
|
|
// Singleton instance
|
|
static final BlockService _instance = BlockService._privateConstructor();
|
|
|
|
// Factory constructor to return the same instance
|
|
factory BlockService() {
|
|
return _instance;
|
|
}
|
|
|
|
/// Block a phone number (syncs with system and app)
|
|
Future<bool> blockNumber(String phoneNumber) async {
|
|
try {
|
|
// First try to block in system
|
|
try {
|
|
await _channel.invokeMethod('blockNumber', {'number': phoneNumber});
|
|
} catch (e) {
|
|
debugPrint('Failed to block in system: $e');
|
|
}
|
|
|
|
// Always save to app storage as backup
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final blockedNumbers = prefs.getStringList(_blockedNumbersKey) ?? [];
|
|
|
|
// Don't add if already blocked
|
|
if (!blockedNumbers.contains(phoneNumber)) {
|
|
blockedNumbers.add(phoneNumber);
|
|
await prefs.setStringList(_blockedNumbersKey, blockedNumbers);
|
|
}
|
|
|
|
return true; // Return true if either system or app blocking succeeded
|
|
} catch (e) {
|
|
debugPrint('Error blocking number: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Unblock a phone number (syncs with system and app)
|
|
Future<bool> unblockNumber(String phoneNumber) async {
|
|
try {
|
|
// First try to unblock from system
|
|
try {
|
|
await _channel.invokeMethod('unblockNumber', {'number': phoneNumber});
|
|
} catch (e) {
|
|
debugPrint('Failed to unblock from system: $e');
|
|
}
|
|
|
|
// Always remove from app storage
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final blockedNumbers = prefs.getStringList(_blockedNumbersKey) ?? [];
|
|
|
|
if (blockedNumbers.contains(phoneNumber)) {
|
|
blockedNumbers.remove(phoneNumber);
|
|
await prefs.setStringList(_blockedNumbersKey, blockedNumbers);
|
|
}
|
|
|
|
return true;
|
|
} catch (e) {
|
|
debugPrint('Error unblocking number: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Check if a number is blocked (checks both system and app)
|
|
Future<bool> isNumberBlocked(String phoneNumber) async {
|
|
try {
|
|
// Check system first
|
|
try {
|
|
bool systemBlocked = await _channel.invokeMethod('isNumberBlocked', {'number': phoneNumber});
|
|
if (systemBlocked) return true;
|
|
} catch (e) {
|
|
debugPrint('Failed to check system blocked status: $e');
|
|
}
|
|
|
|
// Check app storage as fallback
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final blockedNumbers = prefs.getStringList(_blockedNumbersKey) ?? [];
|
|
return blockedNumbers.contains(phoneNumber);
|
|
} catch (e) {
|
|
debugPrint('Error checking if number is blocked: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Get all blocked numbers (merges system and app blocked numbers)
|
|
Future<List<String>> getBlockedNumbers() async {
|
|
try {
|
|
Set<String> allBlockedNumbers = {};
|
|
|
|
// Get system blocked numbers
|
|
try {
|
|
List<dynamic> systemBlocked = await _channel.invokeMethod('getBlockedNumbers');
|
|
allBlockedNumbers.addAll(systemBlocked.cast<String>());
|
|
} catch (e) {
|
|
debugPrint('Failed to get system blocked numbers: $e');
|
|
}
|
|
|
|
// Get app blocked numbers
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final appBlocked = prefs.getStringList(_blockedNumbersKey) ?? [];
|
|
allBlockedNumbers.addAll(appBlocked);
|
|
} catch (e) {
|
|
debugPrint('Failed to get app blocked numbers: $e');
|
|
}
|
|
|
|
return allBlockedNumbers.toList()..sort();
|
|
} catch (e) {
|
|
debugPrint('Error getting blocked numbers: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// Sync app blocked numbers with system blocked numbers
|
|
Future<void> syncWithSystem() async {
|
|
try {
|
|
// Get system blocked numbers
|
|
List<String> systemBlocked = [];
|
|
try {
|
|
List<dynamic> result = await _channel.invokeMethod('getBlockedNumbers');
|
|
systemBlocked = result.cast<String>();
|
|
} catch (e) {
|
|
debugPrint('Failed to get system blocked numbers for sync: $e');
|
|
return;
|
|
}
|
|
|
|
// Get app blocked numbers
|
|
final prefs = await SharedPreferences.getInstance();
|
|
List<String> appBlocked = prefs.getStringList(_blockedNumbersKey) ?? [];
|
|
|
|
// Merge them (system takes precedence)
|
|
Set<String> mergedBlocked = {...systemBlocked, ...appBlocked};
|
|
|
|
// Update app storage with merged list
|
|
await prefs.setStringList(_blockedNumbersKey, mergedBlocked.toList());
|
|
|
|
debugPrint('Synced ${mergedBlocked.length} blocked numbers with system');
|
|
} catch (e) {
|
|
debugPrint('Error syncing with system: $e');
|
|
}
|
|
}
|
|
}
|