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:
- When notification fires, ringtone starts in broadcast receiver.
- If device is on, user can stop ringtone pressing button on popup notification.
- 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.
I've just resolved by myself.
Then, all worked.