Kotlin уведомляет и записывает звонок, когда вы его получаете ⇐ Android
Kotlin уведомляет и записывает звонок, когда вы его получаете
I wrote the following code, when I receive a call I should receive a notification whether or not I want to record the call, the problem is that I do not receive any notification.
How do I ensure that the CallReceiver is always listening?
Furthermore, I don't need MainActivity to show anything, what can I do?
Can you give me a hand?
Manifest:
NotificationActionReceiver:
import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log class NotificationActionReceiver : BroadcastReceiver() { companion object { const val ACTION_RECORD_CALL = "ACTION_RECORD_CALL" const val ACTION_CANCEL = "ACTION_CANCEL" const val EXTRA_PHONE_NUMBER = "EXTRA_PHONE_NUMBER" } override fun onReceive(context: Context?, intent: Intent?) { when (intent?.action) { ACTION_RECORD_CALL -> { val phoneNumber = intent.getStringExtra(EXTRA_PHONE_NUMBER) Log.d("NotificationAction", "Recording call from $phoneNumber") // Aggiungi qui la logica per iniziare la registrazione } ACTION_CANCEL -> { Log.d("NotificationAction", "Recording cancelled") // Aggiungi qui la logica per annullare la registrazione } } } } CallReceiver:
import android.Manifest import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.media.MediaRecorder import android.os.Build import android.telephony.TelephonyManager import android.util.Log import androidx.core.app.ActivityCompat import androidx.core.app.NotificationCompat import java.io.IOException import java.text.SimpleDateFormat import java.util.* class CallReceiver : BroadcastReceiver() { private var mediaRecorder: MediaRecorder? = null private var isRecording = false private lateinit var context: Context override fun onReceive(context: Context?, intent: Intent?) { this.context = context!! if (intent?.action.equals("android.intent.action.PHONE_STATE")) { val state = intent?.getStringExtra(TelephonyManager.EXTRA_STATE) if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { val phoneNumber = intent?.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) Log.d("CallReceiver", "Incoming call from: $phoneNumber") showNotification(phoneNumber) } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) { Log.d("CallReceiver", "Call ended") stopRecording() } } } private fun startRecording() { if (isRecording) { return } if (ActivityCompat.checkSelfPermission( context, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED ) { try { val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date()) val audioFilePath = context.getExternalFilesDir(null)?.absolutePath + "/$timestamp.3gp" mediaRecorder = MediaRecorder().apply { setAudioSource(MediaRecorder.AudioSource.VOICE_CALL) setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) setOutputFile(audioFilePath) try { prepare() } catch (e: IOException) { Log.e("CallRecorder", "prepare() failed") } start() } isRecording = true Log.d("CallReceiver", "Recording started") } catch (e: Exception) { Log.e("CallReceiver", "Error starting recording: ${e.message}") } } else { Log.e("CallReceiver", "Permission to record audio not granted") } } private fun stopRecording() { if (isRecording) { mediaRecorder?.apply { stop() release() } isRecording = false Log.d("CallReceiver", "Recording stopped") } } private fun showNotification(phoneNumber: String?) { val channelId = "RecordCallChannel" val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "Record Call Channel", NotificationManager.IMPORTANCE_HIGH ) notificationManager.createNotificationChannel(channel) } val builder = NotificationCompat.Builder(context, channelId) .setSmallIcon(android.R.drawable.ic_dialog_info) .setContentTitle("Incoming Call") .setContentText("Do you want to record this call?") .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) .addAction( android.R.drawable.ic_menu_save, "Record", getPendingIntent(true, phoneNumber) ) .addAction( android.R.drawable.ic_menu_close_clear_cancel, "Cancel", getPendingIntent(false, null) ) notificationManager.notify(1, builder.build()) } private fun getPendingIntent(record: Boolean, phoneNumber: String?): PendingIntent { val intent = Intent(context, NotificationActionReceiver::class.java).apply { action = if (record) NotificationActionReceiver.ACTION_RECORD_CALL else NotificationActionReceiver.ACTION_CANCEL putExtra(NotificationActionReceiver.EXTRA_PHONE_NUMBER, phoneNumber) } return PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT ) } } MainActivity:
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.myapp.callrec.ui.theme.CallrecTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CallrecTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Greeting("Android") } } } } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) } @Preview(showBackground = true) @Composable fun GreetingPreview() { CallrecTheme { Greeting("Android") } }
Источник: https://stackoverflow.com/questions/780 ... receive-it
I wrote the following code, when I receive a call I should receive a notification whether or not I want to record the call, the problem is that I do not receive any notification.
How do I ensure that the CallReceiver is always listening?
Furthermore, I don't need MainActivity to show anything, what can I do?
Can you give me a hand?
Manifest:
NotificationActionReceiver:
import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log class NotificationActionReceiver : BroadcastReceiver() { companion object { const val ACTION_RECORD_CALL = "ACTION_RECORD_CALL" const val ACTION_CANCEL = "ACTION_CANCEL" const val EXTRA_PHONE_NUMBER = "EXTRA_PHONE_NUMBER" } override fun onReceive(context: Context?, intent: Intent?) { when (intent?.action) { ACTION_RECORD_CALL -> { val phoneNumber = intent.getStringExtra(EXTRA_PHONE_NUMBER) Log.d("NotificationAction", "Recording call from $phoneNumber") // Aggiungi qui la logica per iniziare la registrazione } ACTION_CANCEL -> { Log.d("NotificationAction", "Recording cancelled") // Aggiungi qui la logica per annullare la registrazione } } } } CallReceiver:
import android.Manifest import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.media.MediaRecorder import android.os.Build import android.telephony.TelephonyManager import android.util.Log import androidx.core.app.ActivityCompat import androidx.core.app.NotificationCompat import java.io.IOException import java.text.SimpleDateFormat import java.util.* class CallReceiver : BroadcastReceiver() { private var mediaRecorder: MediaRecorder? = null private var isRecording = false private lateinit var context: Context override fun onReceive(context: Context?, intent: Intent?) { this.context = context!! if (intent?.action.equals("android.intent.action.PHONE_STATE")) { val state = intent?.getStringExtra(TelephonyManager.EXTRA_STATE) if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { val phoneNumber = intent?.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) Log.d("CallReceiver", "Incoming call from: $phoneNumber") showNotification(phoneNumber) } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) { Log.d("CallReceiver", "Call ended") stopRecording() } } } private fun startRecording() { if (isRecording) { return } if (ActivityCompat.checkSelfPermission( context, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED ) { try { val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date()) val audioFilePath = context.getExternalFilesDir(null)?.absolutePath + "/$timestamp.3gp" mediaRecorder = MediaRecorder().apply { setAudioSource(MediaRecorder.AudioSource.VOICE_CALL) setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) setOutputFile(audioFilePath) try { prepare() } catch (e: IOException) { Log.e("CallRecorder", "prepare() failed") } start() } isRecording = true Log.d("CallReceiver", "Recording started") } catch (e: Exception) { Log.e("CallReceiver", "Error starting recording: ${e.message}") } } else { Log.e("CallReceiver", "Permission to record audio not granted") } } private fun stopRecording() { if (isRecording) { mediaRecorder?.apply { stop() release() } isRecording = false Log.d("CallReceiver", "Recording stopped") } } private fun showNotification(phoneNumber: String?) { val channelId = "RecordCallChannel" val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "Record Call Channel", NotificationManager.IMPORTANCE_HIGH ) notificationManager.createNotificationChannel(channel) } val builder = NotificationCompat.Builder(context, channelId) .setSmallIcon(android.R.drawable.ic_dialog_info) .setContentTitle("Incoming Call") .setContentText("Do you want to record this call?") .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) .addAction( android.R.drawable.ic_menu_save, "Record", getPendingIntent(true, phoneNumber) ) .addAction( android.R.drawable.ic_menu_close_clear_cancel, "Cancel", getPendingIntent(false, null) ) notificationManager.notify(1, builder.build()) } private fun getPendingIntent(record: Boolean, phoneNumber: String?): PendingIntent { val intent = Intent(context, NotificationActionReceiver::class.java).apply { action = if (record) NotificationActionReceiver.ACTION_RECORD_CALL else NotificationActionReceiver.ACTION_CANCEL putExtra(NotificationActionReceiver.EXTRA_PHONE_NUMBER, phoneNumber) } return PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT ) } } MainActivity:
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.myapp.callrec.ui.theme.CallrecTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CallrecTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Greeting("Android") } } } } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) } @Preview(showBackground = true) @Composable fun GreetingPreview() { CallrecTheme { Greeting("Android") } }
Источник: https://stackoverflow.com/questions/780 ... receive-it
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
BLE неправильно уведомляет две характеристики в приложении Kotlin Compose
Anonymous » » в форуме Android - 0 Ответы
- 38 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Что делать дальше, когда вы получаете трассировку ядра, указывающую на libc?
Anonymous » » в форуме C++ - 0 Ответы
- 41 Просмотры
-
Последнее сообщение Anonymous
-