Alarm Broadcast Reciever, всегда срабатывает, но активность не запускается, и я не получаю никаких отчетов о сбоях - PullRequest
0 голосов
/ 27 сентября 2019

Я знаю это:

  • ВСЕГДА вызывается широковещательный приемник, потому что он устанавливает будильник на следующий день.
  • Когда он работает, если приложение находится на переднем плане, или еслионо закрыто или, если оно закрыто, экран.
  • Я использую 'com.github.thefuntasty.hauler:library:2.0.0', чтобы отклонить действие с помощью пролистывания
  • . В это время не установлен никакой другой сигнал тревоги
  • Не знаюя не получаю никаких отчетов о сбоях

Я понятия не имею, почему действие не начинается.Я попытался сделать попытку и поймать, чтобы увидеть, поможет ли это, но это не помогло.

РЕДАКТИРОВАТЬ:

Ожидается:

  • Когда сработает приемник Broadcast, установите будильник на следующий день, запустите Activity на переднем плане, даже если телефон заблокирован, и включите сигнал будильника.
  • При проведении вниз уничтожьте действие

В настоящее время:

  • Иногда он открывает действие, а иногда нет, и я не знаю почему.Если я установлю его на 5 минут (заблокированный экран, закрытое приложение), он будет работать без проблем.Если я установлю его на завтра, он будет работать 90% времени.

Я пытаюсь выяснить, почему иногда не запускается действие, потому что я не получаю никаких отчетов о сбоях.из базы огня.

Это код:

Манифест:

    <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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...