1,定时任务的搭建,先启动一个Service,然后在onStartCommand中,通过AlarmManager创建一个定时器
代码:
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
GlobalScope.launch(Dispatchers.Main) {
//获取CPU温度
val temperature = GetCpuInfo.getCPUTemperature(0)
//获取一个Messenger用来发送handler的message
val messenger = intent!!.extras.get("messenger") as Messenger
//创建定时任务
val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager
//定时间隔,一个小时 1 * 60分钟 * 60秒钟 * 1000毫秒
val alarmTime = 1 * 60 * 60 * 1000
//发送广播的时间:为当前系统时间 + 间隔时间
val targetTime: Long = SystemClock.elapsedRealtime() + alarmTime
//注册定时任务的接收广播
val i = Intent(applicationContext, AlarmReceiver::class.java)
val bundle = Bundle()
Log.e("TAG", " AlarmService to AlarmReceiver $temperature ")
bundle.putInt("temperature", temperature)
bundle.putParcelable("messenger", messenger)
i.putExtras(bundle)
val pendingIntent = PendingIntent.getBroadcast(
applicationContext,
0,
i,
//这个FLAG表示:Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent. 即会替换掉前一个PendingIntent的extra data如果不设置,那么每次传的值不会生效,永远第一次注册广播时传入的值
PendingIntent.FLAG_UPDATE_CURRENT
)
//Schedule an alarm.
//参数:type = AlarmManager.ELAPSED_REALTIME_WAKEUP,设置为这个参数,将会唤醒设备
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, targetTime, pendingIntent)
}
return super.onStartCommand(intent, flags, startId)
}
2,在AlarmReceiver这个广播中,接收定时任务发送的消息,然后startService,继续执行service的onStartCommand()方法,开启下一个定时流程
代码:
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
//获取发送广播时的传输的Bundle
val bundle = intent.extras
val temperature = bundle.getInt("temperature")
val messenger = bundle.getParcelable("messenger") as Messenger
Log.e("TAG", " AlarmReceiver get temperature $temperature ")
//创建一个Message,然后通过Messenger发送,通过Handler回调接收
val msg = Message()
msg.what = temperature
messenger.send(msg)
//重新startService
val intent = Intent(context, AlarmService::class.java)
intent.putExtra("messenger", messenger)
context.startService(intent)
}
}
3,在Activity的Handler中,接收定时任务发送的消息,然后执行这个时段要执行的任务 在Activity onCreate时候,第一次启动承载定时器的服务
代码
class CPUInfoActivity : AppCompatActivity() {
var temperature = 0
val handler: Handler = object : Handler() {
override fun handleMessage(msg: Message?) {
if (null != msg) {
temperature = msg.what
GlobalScope.launch(Dispatchers.Main) {
val text = cpuTemp.text
cpuTemp.text =
"$text \n" + "当前CPU温度为 ${temperature}° 时间:${getCurrentTime()}"
}
}
}
}
private fun getCurrentTime(): String {
val year = Calendar.getInstance().get(Calendar.YEAR)
val month = Calendar.getInstance().get(Calendar.MONTH) + 1
val day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH)
val hours = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
val minute = Calendar.getInstance().get(Calendar.MINUTE)
return "${year}年 ${month}月 ${day}日 ${hours}时 ${minute}分"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cpu_info)
//启动Activity的时候,启动定时任务的服务
val intent = Intent(this, AlarmService::class.java)
intent.putExtra("messenger", Messenger(handler))
startService(intent)
}
4,获取CPU温度,需要有root权限,有条件的可以给apk打系统签名即可
代码
object GetCpuInfo {
suspend fun getCPUTemperature(index: Int): Int {
var temperature = 0
val job = GlobalScope.launch(Dispatchers.Default) {
try {
//在系统目录/sys/class/thermal/thermal_zone0/temp下,cat temp文件,获取的数据就是当前CPU温度,在/sys/class/thermal/目录下,会有好多个thermal_zone*文件,*从0开始递增,所以查出来的数据为0或者没有这个文件的时候,去查下一个
val args =
arrayListOf("/system/bin/cat", "/sys/class/thermal/thermal_zone$index/temp")
val cmd = ProcessBuilder(args)
val process = cmd.start()
val ins = process.inputStream
val byte = ByteArray(24)
var result = ""
var size = 0
while ((ins.read(byte).also { size = it }) != -1) {
val resultByte = ByteArray(size)
for (index in resultByte.indices) {
resultByte[index] = byte[index]
}
result += String(resultByte)
}
ins.close()
if (result.isNotEmpty()) {
var resultInt = result.trim().toInt()
if (resultInt > 1000) {
resultInt /= 1000
}
temperature = resultInt
} else {
if (index < 10) {
getCPUTemperature(index + 1)
}
}
} catch (e: Exception) {
e.printStackTrace()
if (index < 10) getCPUTemperature(index + 1)
}
}
job.join()
return temperature
}
}
参考文档:
AlarmManager: developer.android.google.cn/reference/a… PendingIntent: developer.android.google.cn/reference/a…