本文目录导读:
实现原理
- 触发条件:车辆停止(手刹拉起) + 用户无操作超时
- 退出条件:触摸屏幕/车辆启动(手刹释放)
- 功能特性:
- 全屏沉浸式显示
- 显示时间/日期/车辆信息
- 低功耗处理
- 防止系统休眠
核心代码实现
屏保Activity (ScreensaverActivity.kt)
class ScreensaverActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_screensaver)
// 全屏沉浸模式
window.apply {
addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
)
}
// 触摸退出
root_layout.setOnClickListener { finish() }
// 初始化显示
updateDisplay()
// 每秒更新一次时间
Handler(Looper.getMainLooper()).postDelayed(updateRunnable, 1000)
}
private val updateRunnable = object : Runnable {
override fun run() {
updateDisplay()
Handler(Looper.getMainLooper()).postDelayed(this, 1000)
}
}
private fun updateDisplay() {
val time = SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date())
val date = SimpleDateFormat("yyyy/MM/dd EEEE", Locale.getDefault()).format(Date())
tv_time.text = time
tv_date.text = date
}
override fun onDestroy() {
super.onDestroy()
// 清除定时器
Handler(Looper.getMainLooper()).removeCallbacks(updateRunnable)
}
}
屏保布局 (activity_screensaver.xml)
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:clickable="true">
<!-- 时间显示 -->
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#FFFFFF"
android:textSize="80sp"
android:fontFamily="sans-serif-light"/>
<!-- 日期显示 -->
<TextView
android:id="@+id/tv_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_time"
android:layout_centerHorizontal="true"
android:textColor="#CCCCCC"
android:textSize="24sp"
android:layout_marginTop="16dp"/>
</RelativeLayout>
屏保管理服务 (ScreensaverService.kt)
class ScreensaverService : Service() {
private val idleHandler = Handler(Looper.getMainLooper())
private val idleRunnable = Runnable { startScreensaver() }
private val idleTimeout = 5 * 60 * 1000L // 5分钟无操作
// 监听车辆状态(需替换为实际车机SDK)
private val vehicleStateReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == "com.vehicle.HANDBRAKE_CHANGED") {
val isHandbrakeOn = intent.getBooleanExtra("is_on", false)
if (!isHandbrakeOn) {
// 手刹释放时关闭屏保
stopScreensaver()
}
}
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
resetIdleTimer()
registerVehicleReceiver()
return START_STICKY
}
private fun resetIdleTimer() {
idleHandler.removeCallbacks(idleRunnable)
idleHandler.postDelayed(idleRunnable, idleTimeout)
}
private fun startScreensaver() {
if (!isScreensaverActive()) {
val intent = Intent(this, ScreensaverActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
startActivity(intent)
}
}
private fun stopScreensaver() {
// 通过ActivityManager关闭屏保Activity
(getSystemService(ACTIVITY_SERVICE) as ActivityManager).apply {
getRunningTasks(10).forEach { task ->
if (task.topActivity?.className == ScreensaverActivity::class.java.name) {
// 发送关闭广播(Activity内接收后finish)
sendBroadcast(Intent("CLOSE_SCREENSAVER"))
}
}
}
}
private fun isScreensaverActive(): Boolean {
// 检测屏保是否已在前台
}
private fun registerVehicleReceiver() {
registerReceiver(vehicleStateReceiver, IntentFilter("com.vehicle.HANDBRAKE_CHANGED"))
}
override fun onBind(intent: Intent) = null
}
用户操作监听(在BaseActivity中)
open class BaseActivity : AppCompatActivity() {
override fun onUserInteraction() {
super.onUserInteraction()
// 通知服务重置计时器
sendBroadcast(Intent("RESET_IDLE_TIMER"))
}
}
关键配置
AndroidManifest.xml 配置
<!-- 屏保Activity -->
<activity
android:name=".ScreensaverActivity"
android:theme="@style/FullScreenTheme"
android:excludeFromRecents="true"
android:showOnLockScreen="true"
android:turnScreenOn="true"/>
<!-- 全屏主题 -->
<style name="FullScreenTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/black</item>
</style>
<!-- 后台服务 -->
<service android:name=".ScreensaverService" />
权限申请
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
优化建议
- 硬件加速:在布局中使用
android:hardwareAccelerated="true" - 能耗控制:使用
PARTIAL_WAKE_LOCK保持CPU运行 - :添加天气预报/音乐封面等动态元素
- 车辆数据集成:
// 示例:获取车速(需车机SDK支持) val speed = VehicleApi.getSpeed() if (speed > 5) stopScreensaver() // 行驶中关闭屏保
- 动画效果:使用属性动画实现平滑的时间刷新
调试技巧
- 使用
adb shell dumpsys activity检查Activity栈 - 模拟车辆状态:
adb shell am broadcast -a com.vehicle.HANDBRAKE_CHANGED --ez is_on true
- 强制触发屏保:
startService(Intent(this, ScreensaverService::class.java))
注意事项:实际开发中需替换车辆状态API为车机厂商提供的SDK接口,不同车型的车辆信号获取方式可能不同。
免责声明
本网站内容仅供参考,不构成专业建议。使用本网站内容造成的损失,本网站不承担责任。
网站内容来源于网络,如有侵权请联系我们删除!






