167 lines
4.7 KiB
Dart
167 lines
4.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
void main() {
|
|
runApp(const IcingDialerApp());
|
|
}
|
|
|
|
class IcingDialerApp extends StatefulWidget {
|
|
const IcingDialerApp({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<IcingDialerApp> createState() => _IcingDialerAppState();
|
|
}
|
|
|
|
class _IcingDialerAppState extends State<IcingDialerApp> {
|
|
// This channel must match the one in MainActivity.kt.
|
|
static const platform = MethodChannel('com.example.dialer/call_events');
|
|
bool isDefaultDialer = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
// Listen for method calls from the Android side.
|
|
platform.setMethodCallHandler(handleMethodCalls);
|
|
}
|
|
|
|
|
|
|
|
Future<void> handleMethodCalls(MethodCall call) async {
|
|
switch (call.method) {
|
|
case 'onDefaultDialerSet':
|
|
// Update our UI to show that we are now the default dialer.
|
|
setState(() {
|
|
isDefaultDialer = true;
|
|
});
|
|
break;
|
|
case 'onDefaultDialerDenied':
|
|
// Show a message to the user when they deny the request.
|
|
_showDefaultDialerDeniedDialog();
|
|
break;
|
|
case 'onIncomingCall':
|
|
final phoneNumber = call.arguments as String? ?? "Unknown";
|
|
_showIncomingCallDialog(phoneNumber);
|
|
break;
|
|
default:
|
|
print("Unhandled method: ${call.method}");
|
|
}
|
|
}
|
|
|
|
// Show a dialog when the user denies the default dialer request.
|
|
void _showDefaultDialerDeniedDialog() {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Permission Denied'),
|
|
content: const Text(
|
|
'To use this app as your default dialer, please grant the permission when prompted.'),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text('OK'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// Show a dialog when an incoming call is intercepted.
|
|
void _showIncomingCallDialog(String phoneNumber) {
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (_) => AlertDialog(
|
|
title: const Text('Incoming Call'),
|
|
content: Text('Call from: $phoneNumber'),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
// (Here you could add code to reject the call.)
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text('Reject'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
// (Here you could add code to accept the call.)
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text('Accept'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// Invoke the native method to request to be the default dialer.
|
|
Future<void> requestDefaultDialer() async {
|
|
try {
|
|
await platform.invokeMethod('requestDefaultDialer');
|
|
} catch (e) {
|
|
print('Error requesting default dialer: $e');
|
|
// Show an error message if the request fails.
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text('Error requesting default dialer: $e')),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'Icing Dialer',
|
|
theme: ThemeData.dark(),
|
|
home: isDefaultDialer
|
|
? const CallScreen()
|
|
: DefaultDialerSetupScreen(onRequestDefaultDialer: requestDefaultDialer),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Shown when the app is not yet the default dialer.
|
|
class DefaultDialerSetupScreen extends StatelessWidget {
|
|
final VoidCallback onRequestDefaultDialer;
|
|
const DefaultDialerSetupScreen({Key? key, required this.onRequestDefaultDialer})
|
|
: super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Set as Default Dialer')),
|
|
body: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
const Text(
|
|
'This app is not set as your default dialer.',
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 20),
|
|
ElevatedButton(
|
|
onPressed: onRequestDefaultDialer,
|
|
child: const Text('Set as Default Dialer'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Shown when the app is the default dialer.
|
|
class CallScreen extends StatelessWidget {
|
|
const CallScreen({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// A simple UI indicating that the app is waiting for incoming calls.
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Icing Dialer')),
|
|
body: const Center(
|
|
child: Text('Waiting for incoming calls...'),
|
|
),
|
|
);
|
|
}
|
|
} |