警报广播接收器,总是触发,但是“活动”未启动,并且我没有收到任何崩溃报告

时间:2019-09-27 07:52:12

标签: android broadcastreceiver android-mediaplayer alarmmanager alarm

我知道这一点:

  • 之所以叫广播接收器,是因为它设置了第二天的警报。
  • 如果该应用在前景中,关闭或关闭屏幕时有效。
  • 我使用'com.github.thefuntasty.hauler:library:2.0.0'通过滑动来取消活动
  • 当时未设置其他警报
  • 我没有任何崩溃报告

我不知道为什么活动没有开始。我尝试进行尝试并捕获,以查看是否有帮助,但没有帮助。

编辑:

预期:

  • 当广播接收者触发时,将警报设置为第二天,即使手机处于锁定状态,也要在前台启动“活动”。
  • 向下滑动会破坏活动

当前:

  • 有时它打开活动,而其他时候却不打开,我也不知道为什么。如果我从现在开始将其设置为5分钟(锁定屏幕,关闭的应用),则可以正常使用。如果我将其设置为明天,则90%的时间都可以使用。

我试图弄清楚为什么有时活动无法开始,因为我没有从Firebase收到任何崩溃报告。

这是代码:

清单:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


        <receiver
            android:name=".views.alarm.broadcast.ResumeOnBootAlarm"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <receiver
            android:name=".views.alarm.broadcast.MyAlarm"
            android:exported="true" />

   <activity
            android:name=".views.alarm.broadcast.TriggeredAlarmActivity"
            android:excludeFromRecents="true"
            android:launchMode="singleInstance"
            android:theme="@style/AppTheme.Draggable" />

这是我的BroadCastReciever:

class MyAlarm : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val alarmID = intent.extras?.getInt(ARG_ALARM_ID)

        //Immediatly set new alarm
        val realm = Realm.getDefaultInstance()
        val alarmFromRealm = DataHelper.getAlarm(realm, alarmID!!)
        alarmFromRealm?.let { alarm ->
            val shouldEnableAlarm = alarm.isEnabled && alarm.daysList!!.isNotEmpty()
            DataHelper.enableAlarm(alarmID, shouldEnableAlarm, realm)
            if (shouldEnableAlarm) {
                setAlarm(context, alarm, false)
            } else {
                cancelAlarm(context, alarm.id)
            }
        }
        try {
            context.startActivity(TriggeredAlarmActivity.getIntent(context, alarmID))
        } catch (ex: Exception) {
            Crashlytics.logException(ex)
            context.startActivity(TriggeredAlarmActivity.getIntent(MyApplication.appContext, null))
        }
    }
}

这是TriggeredActivity:

class TriggeredAlarmActivity : BaseActivity() {

    private var currentUserVolume: Int = 0
    private lateinit var timer: Timer
    private lateinit var realm: Realm
    private lateinit var vibrator: Vibrator
    private var mediaPlayer: MediaPlayer? = null
    private var shouldResumePlaying: Boolean = false

    private val alarmID: Int?
        get() {
            return intent.extras?.getInt(ARG_ALARM_ID)
        }

    private val mAudioManager: AudioManager by lazy {
        baseContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    }

    /*
    LifeCycle
     */

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_triggered_alarm)

        initTextClock()
        showIfScreenIsLocked()
        showDanceAnimation()

        if (alarmID == null) {
            val uri = getDefaultRingtone()
            mediaPlayer= MediaPlayer()
            mediaPlayer?.setDataSource(this,uri)
            mediaPlayer?.prepare()
            mediaPlayer?.start()
        } else {
            realm = Realm.getDefaultInstance()
            vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator

            val alarmFromRealm = DataHelper.getAlarm(realm, alarmID!!)
            alarmFromRealm?.let { alarm ->
                try {
                    if (alarm.useDefaultRingtone) {
                        val uri = getDefaultRingtone()
                        mediaPlayer = MediaPlayer()
                        mediaPlayer?.let { increaseVolumeOverTime(it, alarm.shouldVibrate) }
                        mediaPlayer?.setDataSource(this, uri)
                        mediaPlayer?.isLooping = true
                        shouldResumePlaying = alarm.shouldResumePlaying
                        mediaPlayer?.setOnPreparedListener {
                            if (alarm.shouldResumePlaying) {
                                mediaPlayer?.seekTo(alarm.secondsPlayed)
                            }
                            mediaPlayer?.start()
                        }
                        mediaPlayer?.prepareAsync()
                    } else {
                        initMediaPlayer(alarm)
                    }
                } catch (exception: Exception) {
                    Crashlytics.logException(exception)
                    val uri = getDefaultRingtone()
                    mediaPlayer = MediaPlayer()
                    mediaPlayer?.let { increaseVolumeOverTime(it, true) }
                    mediaPlayer?.setDataSource(this, uri)
                    mediaPlayer?.isLooping = true
                    mediaPlayer?.setOnPreparedListener {
                        mediaPlayer?.start()
                    }
                    mediaPlayer?.prepareAsync()
                }
            }
        }

        haulerView?.setOnDragDismissedListener {
            finish() // finish activity when dismissed
        }

    }

    private fun getDefaultRingtone(): Uri {
        var uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM)
        if (uri == null) {
            uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
            if (uri == null) {
                uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
            }
        }
        return uri
    }


    private fun initTextClock() {
        val period = 5000L

        val timer = Timer()
        val formatter = SimpleDateFormat("HH:mm")

        val task = object : TimerTask() {
            override fun run() {
                val today = Date()
                runOnUiThread {
                    tvCurrentTimeActual?.text = formatter.format(today)
                }
            }
        }
        timer.scheduleAtFixedRate(task, 0L, period)
    }

    override fun onDestroy() {
        super.onDestroy()
        if (shouldResumePlaying) {
            mediaPlayer?.let {
                alarmID?.let { it1 -> DataHelper.updateProgress(it1, it.currentPosition) }
            }
        }
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentUserVolume, 0)
        timer.cancel()
        mediaPlayer?.stop()
        vibrator.cancel()
        realm.close()
    }

    /*
    Private
     */

    private fun showIfScreenIsLocked() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
            val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            keyguardManager.requestDismissKeyguard(this, null)
        } else {
            window.addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                        WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                        WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            )
        }
    }

    private fun showDanceAnimation() {
        val lottieFiles = mutableListOf(
            "lottie/dance/chicken_6.json",
            "lottie/dance/sound.json",  //White
            "lottie/dance/pinguin.json" //White
        )
        val file = lottieFiles.random()
        messageLottie?.setAnimation(file)
        if (file == "lottie/dance/pinguin.json"
            || file == "lottie/dance/sound.json"
        ) {
            messageLottie?.addValueCallback(
                KeyPath("**"), LottieProperty.COLOR_FILTER,
                { PorterDuffColorFilter(getColor(R.color.white), PorterDuff.Mode.SRC_ATOP) }
            )
        }
        messageLottie?.playAnimation()
    }

    private fun increaseVolumeOverTime(mediaPlayer: MediaPlayer, shouldVibrate: Boolean) {
        mediaPlayer.setAudioAttributes(
            AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build()
        )

        currentUserVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
        var currentVolume = 1
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0)

        if (shouldVibrate) {
            startVibrating()
        }

        timer = Timer()
        timer.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                currentVolume += 1
                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0)
                if (currentVolume % 10 == 0) {
                    if (shouldVibrate) {
                        startVibrating(currentVolume)
                    }
                }

                if (currentVolume >= 90) this.cancel()
            }
        }, 0, 2000)
    }

    private fun startVibrating(currentVolume: Int = 10) {
        val vibratorLength = ((50 * currentVolume) / 1.2).roundToInt().toLong()
        val patternShort = longArrayOf(1200, vibratorLength)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            vibrator.vibrate(VibrationEffect.createWaveform(patternShort, 0))
        } else {
            vibrator.vibrate(patternShort, 0)
        }
    }

    private fun initMediaPlayer(alarm: Alarm) {
        mediaPlayer = MediaPlayer()
        mediaPlayer?.let { increaseVolumeOverTime(it, alarm.shouldVibrate) }
        val currentlySelectedPath = alarm.currentlySelectedPath
        if (currentlySelectedPath == null) {
            var uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM)
            if (uri == null) {
                uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
                if (uri == null) {
                    uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
                }
            }
            mediaPlayer?.setDataSource(this, uri)
        } else {
            mediaPlayer?.setDataSource(this, Uri.parse(currentlySelectedPath))
        }
        mediaPlayer?.isLooping = false
        mediaPlayer?.setOnCompletionListener {
            it?.stop()
            it?.reset()
            it?.isLooping = false
            val path = alarm.songsList?.random()?.path
            it?.setDataSource(this, Uri.parse(path))
            alarmID?.let { it1 -> DataHelper.nextRandomSong(it1, path) }
            it?.setOnPreparedListener {
                mediaPlayer?.start()
            }
            it?.prepareAsync()
        }
        mediaPlayer?.setOnPreparedListener {
            if (alarm.shouldResumePlaying) {
                mediaPlayer?.seekTo(alarm.secondsPlayed)
            }
            mediaPlayer?.start()
        }
        mediaPlayer?.prepareAsync()
        shouldResumePlaying = alarm.shouldResumePlaying
    }

    companion object {
        const val ARG_ALARM_ID = "AlarmID"

        fun getIntent(context: Context, alarmID: Int?): Intent {
            val intent = Intent(context, TriggeredAlarmActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_HISTORY) //If it doesn't hide in recent use or Intent.FLAG_ACTIVITY_CLEAR_TASK
            intent.putExtra(ARG_ALARM_ID, alarmID)
            return intent
        }
    }
}

0 个答案:

没有答案