diff --git a/dialer/android/app/src/main/AndroidManifest.xml b/dialer/android/app/src/main/AndroidManifest.xml index 138e514..e0de6a4 100644 --- a/dialer/android/app/src/main/AndroidManifest.xml +++ b/dialer/android/app/src/main/AndroidManifest.xml @@ -15,7 +15,7 @@ android:icon="@mipmap/ic_launcher" android:enableOnBackInvokedCallback="true"> + when (call.method) { + "makeGsmCall" -> { + val phoneNumber = call.argument("phoneNumber") + if (phoneNumber != null) { + CallService.makeGsmCall(this, phoneNumber) + result.success("Calling $phoneNumber") + } else { + result.error("INVALID_PHONE_NUMBER", "Phone number is required", null) + } + } + "hangUpCall" -> { + CallService.hangUpCall(this) + result.success("Call ended") + } + else -> result.notImplemented() + } + } + // Set up the keystore channel. MethodChannel(flutterEngine.dartExecutor.binaryMessenger, KEYSTORE_CHANNEL) .setMethodCallHandler { call, result -> diff --git a/dialer/android/app/src/main/kotlin/com/icing/dialer/services/CallService.kt b/dialer/android/app/src/main/kotlin/com/icing/dialer/services/CallService.kt new file mode 100644 index 0000000..e0016dc --- /dev/null +++ b/dialer/android/app/src/main/kotlin/com/icing/dialer/services/CallService.kt @@ -0,0 +1,30 @@ +package com.icing.dialer.services + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.telecom.TelecomManager +import android.os.Build +import android.util.Log + +object CallService { + + fun makeGsmCall(context: Context, phoneNumber: String) { + try { + val intent = Intent(Intent.ACTION_CALL) + intent.data = Uri.parse("tel:$phoneNumber") + context.startActivity(intent) + } catch (e: Exception) { + Log.e("CallService", "Error making GSM call: ${e.message}") + } + } + + fun hangUpCall(context: Context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager + telecomManager.endCall() + } else { + Log.e("CallService", "Hangup call is only supported on Android P or later.") + } + } +} \ No newline at end of file diff --git a/dialer/lib/features/composition/composition.dart b/dialer/lib/features/composition/composition.dart index 6edfa01..9bde112 100644 --- a/dialer/lib/features/composition/composition.dart +++ b/dialer/lib/features/composition/composition.dart @@ -1,10 +1,9 @@ -// lib/pages/composition_page.dart - import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../services/contact_service.dart'; import '../../services/obfuscate_service.dart'; // Import ObfuscateService +import '../../services/call_service.dart'; // Import the CallService import '../contacts/widgets/add_contact_button.dart'; class CompositionPage extends StatefulWidget { @@ -23,6 +22,9 @@ class _CompositionPageState extends State { // Instantiate the ObfuscateService final ObfuscateService _obfuscateService = ObfuscateService(); + // Instantiate the CallService + final CallService _callService = CallService(); + @override void initState() { super.initState(); @@ -71,13 +73,15 @@ class _CompositionPageState extends State { }); } - // Function to call a contact's number - void _launchPhoneDialer(String phoneNumber) async { - final uri = Uri(scheme: 'tel', path: phoneNumber); - if (await canLaunchUrl(uri)) { - await launchUrl(uri); - } else { - debugPrint('Could not launch $phoneNumber'); + // Function to call a contact's number using the CallService + void _makeCall(String phoneNumber) async { + try { + await _callService.makeGsmCall(phoneNumber); + setState(() { + dialedNumber = phoneNumber; + }); + } catch (e) { + debugPrint("Error making call: $e"); } } @@ -128,13 +132,13 @@ class _CompositionPageState extends State { trailing: Row( mainAxisSize: MainAxisSize.min, children: [ - // Call button + // Call button (Now using CallService) IconButton( icon: Icon(Icons.phone, color: Colors.green[300], size: 20), onPressed: () { - _launchPhoneDialer(phoneNumber); + _makeCall(phoneNumber); // Make a call using CallService }, ), // Message button diff --git a/dialer/lib/features/contacts/widgets/contact_modal.dart b/dialer/lib/features/contacts/widgets/contact_modal.dart index 632d8be..9f641ad 100644 --- a/dialer/lib/features/contacts/widgets/contact_modal.dart +++ b/dialer/lib/features/contacts/widgets/contact_modal.dart @@ -5,6 +5,7 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:dialer/widgets/username_color_generator.dart'; import '../../../services/block_service.dart'; import '../../../services/contact_service.dart'; +import '../../../services/call_service.dart'; // Import CallService class ContactModal extends StatefulWidget { final Contact contact; @@ -28,6 +29,7 @@ class _ContactModalState extends State { late String phoneNumber; bool isBlocked = false; final ObfuscateService _obfuscateService = ObfuscateService(); + final CallService _callService = CallService(); // Instantiate CallService @override void initState() { @@ -258,9 +260,9 @@ class _ContactModalState extends State { _obfuscateService.obfuscateData(phoneNumber), style: const TextStyle(color: Colors.white), ), - onTap: () { + onTap: () async { if (widget.contact.phones.isNotEmpty) { - _launchPhoneDialer(phoneNumber); + await _callService.makeGsmCall(phoneNumber); } }, ), @@ -329,12 +331,11 @@ class _ContactModalState extends State { icon: Icon( isBlocked ? Icons.block : Icons.block_flipped), label: Text(isBlocked ? 'Unblock' : 'Block'), - ), ), + ), ], ), ), - const SizedBox(height: 16), ], ), diff --git a/dialer/lib/services/call_service.dart b/dialer/lib/services/call_service.dart new file mode 100644 index 0000000..c07027e --- /dev/null +++ b/dialer/lib/services/call_service.dart @@ -0,0 +1,26 @@ +import 'package:flutter/services.dart'; + +// Service to manage call-related operations +class CallService { + static const MethodChannel _channel = MethodChannel('call_service'); + + // Function to make a GSM call + Future makeGsmCall(String phoneNumber) async { + try { + await _channel.invokeMethod('makeGsmCall', {"phoneNumber": phoneNumber}); + } catch (e) { + print("Error making call: $e"); + rethrow; + } + } + + // Function to hang up the current call + Future hangUpCall() async { + try { + await _channel.invokeMethod('hangUpCall'); + } catch (e) { + print("Error hanging up call: $e"); + rethrow; + } + } +}