【Android/Kotlin】Kotlinのコードで画面のスリープを無効にする(スマートフォンでカップ麺タイマーをつくる6)

投稿日:2021年3月14日
最終更新日:2021年3月14日

画面のスリープを無効にする

カップ麺タイマーをつくっていて気づいたが、今のままだとタイマーが動いているうちにAndroid端末がスリープ状態になってしまい、時間がわからなくなってしまうという致命的な問題がある。

今回はKotlinのコード上で画面のスリープを無効にしたので方法をメモしておく。

 

環境

開発PC環境

Windows 10
Android Studio 4.1.1

実行Android環境

機種:Xperia X Performance SOV33

Androidバージョン:7.0

 

アクティビティをFLAG_KEEP_SCREEN_ONに設定する

参考文献の公式ドキュメントを読むと、Activityのコード上でスリープを無効にする方法とレイアウト XML上でスリープを無効にする方法があるが、今回はActivityのKotlinコード上でスリープを無効にする。やり方はいたって簡単で、まず

import android.view.WindowManager

でWindowManagerをインポートして、以下のコードをonCreateの適当な位置に配置するだけ。

window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

作成中のカップ麺タイマーでは以下のようにコード中に配置した。

package com.example.cupnoodletimer
import android.content.Context
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.SoundPool
import android.os.*
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
val TIMERTIME: Long = 180000;
lateinit var timerText: TextView
lateinit var timer: CountDownTimer
var isRunning: Boolean = false;
lateinit var soundPool: SoundPool
var soundAlarm = 0
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val startButton: Button = findViewById(R.id.buttonStart)
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
soundPool = SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.setMaxStreams(1)
.build()
val imageView = findViewById<ImageView>(R.id.imageView)
imageView.setImageResource(R.drawable.cup_ramen)
imageView.visibility = View.INVISIBLE
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
startButton.setOnClickListener {
if (isRunning) {
timer.cancel()
setTime(TIMERTIME)
isRunning = false
startButton.text = "START"
imageView.visibility = View.INVISIBLE
} else {
soundAlarm = soundPool.load(this, R.raw.alarm, 1)
timer = object : CountDownTimer(TIMERTIME, 1000) {
override fun onTick(millisUntilFinished: Long) {
setTime(millisUntilFinished)
}
override fun onFinish() {
setTime(0)
isRunning = false
startButton.text = "RESTART"
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val vibrationEffect = VibrationEffect.createOneShot(5000, VibrationEffect.DEFAULT_AMPLITUDE)
vibrator.vibrate(vibrationEffect)
} else {
vibrator.vibrate(5000)
}
val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
val alarmVol: Float = am.getStreamVolume(AudioManager.STREAM_RING).toFloat()
var alarmMaxVol: Float = am.getStreamMaxVolume(AudioManager.STREAM_RING).toFloat()
var setVol: Float = (alarmVol / alarmMaxVol).toFloat()
soundPool.play(soundAlarm, setVol, setVol, 0, 0, 1.0f)
imageView.visibility = View.VISIBLE
}
}
timer.start()
isRunning = true
startButton.text = "RESET"
imageView.visibility = View.INVISIBLE
}
}
}
private fun setTime(t: Long) {
timerText = findViewById(R.id.textViewTime)
var time: Long = t
var minutes: Long = (time / 1000) / 60
var seconds: Long = (time / 1000) % 60
timerText.setText("%d:%02d".format(minutes, seconds))
}
}

実機で確認してみて、アプリ起動中はスクリーンがスリープにならないことを確認した。なお、ドキュメントにも書いてあるが明示的にFLAG_KEEP_SCREEN_ONをクリアしなくても、アプリがバックグラウンドに移動するか、またはフォアグラウンドに戻ってくると、ウィンドウ マネージャーが適切な処理が行われるようにしてくれるとのこと。

参考文献

今回は以下のサイトを参考にさせて頂きましたm(_ _)m

デバイスの起動状態を維持する | Android デベロッパー | Android Developers

 

Androidアプリをつくって遊ぼう日記まとめ

以下にAndoirdアプリで遊んでみた軌跡を残しています。興味があればのぞいてみてください。

【Android】Androidアプリをつくって遊ぼう日記

0

投稿者: wakky

映画と旅行が大好きなエンジニア。お酒、ゲーム、読書も好き。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください