feat: default dialer prompt screen #56

Merged
stcb merged 1 commits from defaultAppScreen into dev 2025-05-14 09:45:10 +00:00
3 changed files with 148 additions and 2 deletions
Showing only changes of commit 04ced659c4 - Show all commits

View File

@ -95,7 +95,6 @@ class MainActivity : FlutterActivity() {
pendingIncomingCall = null
}
}
checkAndRequestDefaultDialer()
result.success(true)
}
"makeGsmCall" -> {
@ -191,6 +190,15 @@ class MainActivity : FlutterActivity() {
result.error("SPEAKER_FAILED", "No active call or failed to set speaker", null)
}
}
"isDefaultDialer" -> {
val isDefault = isDefaultDialer()
Log.d(TAG, "isDefaultDialer called, returning: $isDefault")
result.success(isDefault)
}
"requestDefaultDialer" -> {
checkAndRequestDefaultDialer()
result.success(true)
}
else -> result.notImplemented()
}
}
@ -216,6 +224,13 @@ class MainActivity : FlutterActivity() {
}
}
private fun isDefaultDialer(): Boolean {
val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager
val currentDefault = telecomManager.defaultDialerPackage
Log.d(TAG, "Checking default dialer: current=$currentDefault, myPackage=$packageName")
return currentDefault == packageName
}
private fun checkAndRequestDefaultDialer() {
val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager
val currentDefault = telecomManager.defaultDialerPackage

View File

@ -0,0 +1,102 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class DefaultDialerPromptScreen extends StatelessWidget {
const DefaultDialerPromptScreen({super.key});
Future<void> _requestDefaultDialer(BuildContext context) async {
const channel = MethodChannel('call_service');
try {
await channel.invokeMethod('requestDefaultDialer');
// Navigate to home page after requesting default dialer
Navigator.of(context).pushReplacementNamed('/home');
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error requesting default dialer: $e')),
);
}
}
void _exploreApp(BuildContext context) {
// Navigate to home page without requesting default dialer
Navigator.of(context).pushReplacementNamed('/home');
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Set as Default Dialer',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
textAlign: TextAlign.center,
),
SizedBox(height: 16),
Text(
'To handle calls effectively, Icing needs to be your default dialer app. This allows Icing to manage incoming and outgoing calls seamlessly.\n\nWithout the permission, Icing will not be able to encrypt calls.',
style: TextStyle(
fontSize: 16,
color: Colors.white70,
),
textAlign: TextAlign.center,
),
],
),
),
Row(
children: [
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: ElevatedButton(
onPressed: () => _exploreApp(context),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[800],
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 16, vertical: 12),
),
child: Text('Explore App first'),
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: ElevatedButton(
onPressed: () => _requestDefaultDialer(context),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 16, vertical: 12),
),
child: Text('Set as Default Dialer'),
),
),
),
],
),
],
),
),
),
);
}
}

View File

@ -1,4 +1,5 @@
import 'package:dialer/features/home/home_page.dart';
import 'package:dialer/features/home/default_dialer_prompt.dart';
import 'package:flutter/material.dart';
import 'package:dialer/features/contacts/contact_state.dart';
import 'package:dialer/services/call_service.dart';
@ -51,6 +52,17 @@ Future<void> _requestPermissions() async {
class Dialer extends StatelessWidget {
const Dialer({super.key});
Future<bool> _isDefaultDialer() async {
const channel = MethodChannel('call_service');
try {
final isDefault = await channel.invokeMethod<bool>('isDefaultDialer');
return isDefault ?? false;
} catch (e) {
print('Error checking default dialer: $e');
return false;
}
}
@override
Widget build(BuildContext context) {
return ContactState(
@ -59,7 +71,24 @@ class Dialer extends StatelessWidget {
theme: ThemeData(
brightness: Brightness.dark,
),
home: SafeArea(child: MyHomePage()),
initialRoute: '/',
routes: {
'/': (context) => FutureBuilder<bool>(
future: _isDefaultDialer(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
if (snapshot.hasError || !snapshot.hasData || snapshot.data == false) {
return DefaultDialerPromptScreen();
}
return SafeArea(child: MyHomePage());
},
),
'/home': (context) => SafeArea(child: MyHomePage()),
},
),
);
}