Активность тревоги не запускается при выключенном экране - PullRequest
0 голосов
/ 26 февраля 2019

Я работаю над приложением тревоги, когда Intent запускается и отображает Activity при срабатывании будильника, даже если экран устройства выключен.Приложение предназначено для SDK 16 +.
Я могу подтвердить с помощью пользовательской регистрации, что AlarmBroadcastReceiver срабатывает вовремя, и это, в свою очередь, запускает AlarmActivity.Благодаря пользовательской регистрации AlarmActivity не тянется в нужное время.Вместо этого он либо запускается поздно, либо когда пользователь снова включает экран.

Я в недоумении, почему это происходит.Я пробовал несколько решений от других подобных проблем, размещенных на SO.

Есть ли у вас какие-либо предложения относительно моей проблемы?Спасибо за любую помощь!
См. Код ниже для AlarmBroadcastReceiver, AlarmActivity и AndroidManifest.

Я тестирую на следующих устройствах:
Samsung Galaxy II, Android 4.1.2, API 16 - (Это худший вариант - никогда не запускать AlarmActivity или ждать, пока не включится экран.)
LG Nexus 5, Android 6.0.1, API 23
LG Harmony, Android 7.0, API 24

AndroidManifest

...
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".view.AlarmActivity">
        </activity>
        <activity android:name=".view.TimerActivity">
        </activity>
        <activity android:name=".view.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity> 

        <!-- Register the BroadcastReceiver -->
        <receiver android:name=".AlarmBroadcastReceiver"/>
        <receiver android:name=".TimerBroadcastReceiver"/>
    </application>

</manifest>

AlarmBroadcastReceiver

class AlarmBroadcastReceiver : BroadcastReceiver() {

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

        // ***** CUSTOM LOGGING HERE *****
        // This code logs at the correct alarm time

        val newIntent = Intent(context, AlarmActivity::class.java)
        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        ContextCompat.startActivity(context, newIntent, null)
    }

}

AlarmActivity

class AlarmActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(com.devbygc.toddlertimer.R.layout.activity_alarm)

        // ***** CUSTOM LOGGING HERE *****
        // This code does NOT log until either
        // - user turns on the devices screen
        // - some lapse in time making the alarm "late" by 1 min to 1+ 

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setTurnScreenOn(true)
            setShowWhenLocked(true)
            val k = this.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            k.requestDismissKeyguard(this, null)
        } else {
            @Suppress("DEPRECATION")
            window.addFlags(
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY or
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                    WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
            )
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

После изучения собственной кодовой базы Google для их предыдущей тревоги - AlarmClock - я выяснил, как ответить на этот вопрос с помощью WakeLock.
AlarmBroadcastReceiver получает частичную блокировку в onReceive().Затем он публикуется в onDestroy() моего AlarmActivity.
. Новый класс, AlertWakeLock, обрабатывает все функции wakelock.
Не было никаких изменений в манифесте, см. Оригинальный вопрос о разрешениях.
Этот код не вызвал срабатывания аварийного сигнала на нескольких устройствах с несколькими тестами с временем простоя более 12 часов.

Чтобы отдать должное, я все же нашел код WindSekirun полезным и предлагаю рассмотреть его, если у вас возникла подобная проблема..

См. Код ниже:

AlarmBroadcastReceiver

class AlarmBroadcastReceiver : BroadcastReceiver() {

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

        AlertWakeLock.acquireWakeLock(context)

        val newIntent = Intent(context, AlarmActivity::class.java)
        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        ContextCompat.startActivity(context, newIntent, null)
    }

}

AlarmActivity

class AlarmActivity : AppCompatActivity() {

    override fun onDestroy() {
        super.onDestroy()
        AlertWakeLock.releaseWakeLock()
    }

}

AlertWakeLock

class AlertWakeLock {

    companion object {

        private var wakeLock: PowerManager.WakeLock? = null

        fun acquireWakeLock(context: Context) {
            Log.d(TAG,"Acquiring cpu wake lock")
            if (wakeLock != null) {
                return
            }

            val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager

            wakeLock = pm.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK or
                    PowerManager.ACQUIRE_CAUSES_WAKEUP or
                    PowerManager.ON_AFTER_RELEASE, "ToddlerTimer:WakeLock"
            )
            wakeLock!!.acquire()
        }

        fun releaseWakeLock() {
            Log.d(TAG,"Releasing cpu wake lock")
            if (wakeLock != null) {
                wakeLock!!.release()
                wakeLock = null
            }
        }
    }

}
0 голосов
/ 26 февраля 2019

Я использовал этот код в своем проекте напоминания о лекарстве.

Разрешение

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 

Код

@Suppress("DEPRECATION")
fun Activity.setTurnScreenOnLock() {
    val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as? KeyguardManager?
    when {
        android.os.Build.VERSION.SDK_INT >= 27 -> {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
            keyguardManager?.requestDismissKeyguard(this, null)
        }
        android.os.Build.VERSION.SDK_INT == 26 -> {
            window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
            window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
            keyguardManager?.requestDismissKeyguard(this, null)
        }
        else -> {
            window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
            window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
            window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
        }
    }

    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}

Используется (Это Java, на самом деле.)

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Utils.setTurnScreenOnLock(this);
        setContentView(R.layout.some_activity);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...