如何获取Android锁屏可见屏幕宽度?锁屏位图居中失败求助
锁屏位图居中失败的问题排查与解决
问题描述
- 在Android锁屏上尝试居中显示位图时,发现部分屏幕区域不可见,无法找到锁屏边距的相关细节
- 测试代码绘制了居中的10x10红色方块和刻度标尺,结果显示可见范围仅在30到620之间,导致居中计算完全失效
- 系统自带的锁屏图标可以正确居中,但自定义绘制的红色方块位置明显错误
测试代码
fun DrawRuler(context: Context) { val paint = Paint(Paint.ANTI_ALIAS_FLAG) paint.color = Color.WHITE var densityDpi = Resources.getSystem().displayMetrics.densityDpi var density = Resources.getSystem().displayMetrics.density var xdpi = Resources.getSystem().displayMetrics.xdpi var ydpi = Resources.getSystem().displayMetrics.ydpi var screenWidth_int = Resources.getSystem().displayMetrics.widthPixels var screenHeight_int = Resources.getSystem().displayMetrics.heightPixels var screenWidth = screenWidth_int.toFloat() var wallpaper = Bitmap.createBitmap(screenWidth_int , screenHeight_int, Bitmap.Config.ARGB_8888) val canvas = Canvas(wallpaper) val textPaint = Paint(Paint.ANTI_ALIAS_FLAG) textPaint.color = Color.WHITE textPaint.setTextSize(40f); canvas.drawText("densityDpi = $densityDpi" , 40f, 850f, textPaint) canvas.drawText("density = $density" , 40f, 900f, textPaint) canvas.drawText("xdpi = $xdpi" , 40f, 950f, textPaint) canvas.drawText("ydpi = $ydpi" , 40f, 1000f, textPaint) canvas.drawText("screenWidth_int = $screenWidth_int" , 40f, 1050f, textPaint) canvas.drawText("screenHeight_int = $screenHeight_int" , 40f, 1100f, textPaint) // Draw a red 10x10 block and attempt to centre it. val bitmap1 = Bitmap.createBitmap(10,10, Bitmap.Config.ARGB_8888) val image1 = Canvas(bitmap1) image1.drawColor(Color.RED); var redLeft = ((screenWidth-10F)/2F) canvas.drawBitmap(bitmap1 , redLeft, 1200f, Paint(Paint.ANTI_ALIAS_FLAG)) canvas.drawText("left = $redLeft" , redLeft, 1150f, textPaint) // Draw ruler var rulerPos = 1158f; canvas.drawLine(0f, rulerPos, screenWidth, rulerPos, paint) var x = 0f; while (x <= screenWidth ) { var thisDepth = 5f; if (x % 10 == 0F) thisDepth = 10f if (x % 50 == 0F) { thisDepth = 20f canvas.drawText(x.toString(), x, rulerPos + 30F, paint) } canvas.drawLine(x, rulerPos, x, rulerPos + thisDepth, paint) x = x + 5f } val wallpaperManager = WallpaperManager.getInstance(context) wallpaperManager.setBitmap(wallpaper, null, false, WallpaperManager.FLAG_LOCK) wallpaper.recycle() }
问题根源
- 错误使用物理屏幕尺寸:你通过
Resources.getSystem().displayMetrics获取的是设备物理屏幕的完整尺寸,但锁屏壁纸的实际显示区域会被系统裁剪或偏移——系统会自动适配刘海屏、状态栏/导航栏、锁屏安全区域等UI元素,导致物理尺寸和实际可用显示区域不匹配。 - 未遵循锁屏壁纸适配规则:系统锁屏图标能正确居中,是因为它绘制在系统预设的锁屏安全区域内;而你直接按物理屏幕尺寸计算居中位置,完全忽略了系统对锁屏壁纸的缩放、偏移规则。
- 壁纸设置参数错误:调用
setBitmap()时传入null作为偏移量参数,系统会自动应用默认的偏移策略,进一步导致你绘制的居中位置和实际显示位置脱节。
修复方案
修改后的代码
fun DrawRuler(context: Context) { val paint = Paint(Paint.ANTI_ALIAS_FLAG) paint.color = Color.WHITE val wallpaperManager = WallpaperManager.getInstance(context) // 获取系统推荐的锁屏壁纸有效尺寸(已适配UI元素) val lockScreenWidth = wallpaperManager.desiredMinimumWidth val lockScreenHeight = wallpaperManager.desiredMinimumHeight val textPaint = Paint(Paint.ANTI_ALIAS_FLAG) textPaint.color = Color.WHITE textPaint.setTextSize(40f) // 基于锁屏有效尺寸创建Bitmap val wallpaper = Bitmap.createBitmap(lockScreenWidth, lockScreenHeight, Bitmap.Config.ARGB_8888) val canvas = Canvas(wallpaper) // 绘制调试信息 canvas.drawText("lockScreenWidth = $lockScreenWidth", 40f, 850f, textPaint) canvas.drawText("lockScreenHeight = $lockScreenHeight", 40f, 900f, textPaint) // 基于锁屏有效尺寸计算居中位置 val bitmap1 = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888) val image1 = Canvas(bitmap1) image1.drawColor(Color.RED) val redLeft = ((lockScreenWidth - 10F) / 2F) canvas.drawBitmap(bitmap1, redLeft, 1200f, Paint(Paint.ANTI_ALIAS_FLAG)) canvas.drawText("left = $redLeft", redLeft, 1150f, textPaint) // 绘制适配锁屏尺寸的标尺 val rulerPos = 1158f canvas.drawLine(0f, rulerPos, lockScreenWidth.toFloat(), rulerPos, paint) var x = 0f while (x <= lockScreenWidth) { var thisDepth = 5f if (x % 10 == 0F) thisDepth = 10f if (x % 50 == 0F) { thisDepth = 20f canvas.drawText(x.toString(), x, rulerPos + 30F, paint) } canvas.drawLine(x, rulerPos, x, rulerPos + thisDepth, paint) x += 5f } // 设置锁屏壁纸,禁用系统缩放,确保绘制内容准确显示 wallpaperManager.setBitmap(wallpaper, null, true, WallpaperManager.FLAG_LOCK) wallpaper.recycle() }
关键修改点说明
- 使用
WallpaperManager.desiredMinimumWidth/Height获取系统适配后的锁屏有效尺寸,这个尺寸已经考虑了所有UI元素对显示区域的影响 - 基于锁屏有效尺寸计算居中位置,确保绘制内容落在实际可见区域内
- 调用
setBitmap()时将第三个参数设为true,禁用系统自动缩放,保证你的绘制内容按原尺寸显示
内容的提问来源于stack exchange,提问作者sgmoore
相关产品推荐
相关产品推荐

