Stop ringtone of broadcastReceiver from an activity kotlin

444 Views Asked by At

I've already tried similar question stop alarm from ringing in another activity. However, it didn't work in my case. What I want to achieve is:

  1. When notification fires, ringtone starts in broadcast receiver.
  2. If device is on, user can stop ringtone pressing button on popup notification.
  3. If device is off, fullscreen activity turns on and user can stop ringtone pressing stop button in this activity.

The problem is, when I press stop button in fullscreen activity, the ringtone doesn't stop.

Here is the code. AlarmReceiver:

class AlarmReceiver: BroadcastReceiver() {

        companion object {
            lateinit var ringtoneSound: Ringtone
            val ALARM_CHANNEL_ID = "alarm_channel"
        }

        lateinit var notificationManager: NotificationManager

        override fun onReceive(context: Context, intent: Intent) {

            val alarmId = intent.getIntExtra("alarmId", 0)
            val title = intent.getStringExtra("title")
            val memo = intent.getStringExtra("memo")
            val ringLength = intent.getIntExtra("ringLength", 5)


            notificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

            createAlarmChannel()

            val contentIntent = Intent(context, MainActivity::class.java)
            val contentPendingIntent = PendingIntent.getActivity(
                context, alarmId, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT)

            val fullScreenIntent = Intent(context, LockscreenActivity::class.java)
            val fullScreenPendingIntent = PendingIntent.getActivity(context, alarmId, fullScreenIntent, 0)

            val deleteIntent = Intent(context, StopAlarmReceiver::class.java).putExtra("alarmId", alarmId)
            val deletePendingIntent = PendingIntent.getBroadcast(context,alarmId,deleteIntent,0)

            val builder = NotificationCompat.Builder(context, ALARM_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_circle_24)
                .setContentTitle(title)
                .setContentText(memo)
                .setColor(ResourcesCompat.getColor(context.resources, R.color.purple_700, null))
                .setContentIntent(contentPendingIntent)
                .setFullScreenIntent(fullScreenPendingIntent, true)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setCategory(NotificationCompat.CATEGORY_ALARM)
                .setAutoCancel(true)
                .setSound(null)
                .addAction(R.drawable.ic_circle_24, "STOP", deletePendingIntent)

            notificationManager.notify(alarmId, builder.build())

            // when notification fired, Ringtone starts.
            ringtoneSound = RingtoneManager.getRingtone(context, getDefaultUri(RingtoneManager.TYPE_ALARM))
            ringtoneSound.play()

            // and after certain seconds, Ringtone will stop.
            val countLength = 1000 * ringLength.toLong()
            object : CountDownTimer(countLength, 1000) {

                override fun onTick(millisUntilFinished: Long) {}

                override fun onFinish() {
                    ringtoneSound.stop()
                    notificationManager.cancel(alarmId)
                }
            }.start()
        }


    fun createAlarmChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val alarmChannel = NotificationChannel(ALARM_CHANNEL_ID, "Alarm", NotificationManager.IMPORTANCE_HIGH)
            alarmChannel.setSound(null, null)
            alarmChannel.enableLights(true)
            alarmChannel.lightColor = Color.RED
            alarmChannel.enableVibration(true)
            alarmChannel.description = "Alarm style"
            alarmChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            notificationManager.createNotificationChannel(alarmChannel)
        }
    }
}

StopAlarmReceiver:

class StopAlarmReceiver: BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {

            val alarmId = intent.getIntExtra("alarmId", 0)

            // This stops alarm when press the button of notification.(It works!)
            AlarmReceiver.ringtoneSound.stop()


            val notificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.cancel(alarmId)
        }
    }

LockScreenActivity:

class LockscreenActivity : AppCompatActivity() {

    private lateinit var binding: ActivityLockscreenBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        showWhenLockedAndTurnScreenOn()
        super.onCreate(savedInstanceState)
        binding = ActivityLockscreenBinding.inflate(layoutInflater)
        setContentView(binding.root)


        binding.stoppingbutton.setOnClickListener {

            // This does not stop Alarm!
            AlarmReceiver.ringtoneSound.stop()

            finish()
        }

    }


    private fun showWhenLockedAndTurnScreenOn() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
        } else {
            window.addFlags(
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            )
        }
    }
}

StopAlarmReceiver is working, however LockScreenActivity doesn't work even though using same code.

Of course, if I write start() on LockScreenActivity, it works. However when device is on and popup appears, ringtone doesn't start. So how can I stop receiver's ringtone from Activity? Any help appreciate.

1

There are 1 best solutions below

0
Tieria On

I've just resolved by myself.

  1. Make new service.
  2. Ringtone starts in service.
  3. Stop this service from wherever I want (fullscreen or notification).
  4. When destroy the service, service stops ringtone.

Then, all worked.