You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓锁屏上层显示带IME支持的UI(Service初始化)求解决方案

Solution to Show Editable UI Over Lock Screen (From Service)

I've tackled similar requirements before, and the key issues with your current approaches are mostly around window flags, focusability, and proper permission handling. Let's break down the correct approach to get your EditText (with IME support) showing over any lock screen (PIN/password or swipe):


Step 1: Required Permissions

First, you need the system overlay permission, which is a special permission that can't be requested via normal runtime permissions. Add this to your AndroidManifest.xml:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- Optional, but helps with keeping the screen awake reliably -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

Before creating your window, check if you have the overlay permission. If not, redirect the user to the settings page to grant it:

if (!Settings.canDrawOverlays(this)) {
    Intent overlayIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
    overlayIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(overlayIntent);
    return; // Exit until permission is granted
}

Step 2: Correct WindowManager Configuration

Your first attempt used FLAG_NOT_FOCUSABLE, which blocks your EditText from gaining focus (and thus showing the IME). Here's the adjusted LayoutParams that works reliably over lock screens:

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.MATCH_PARENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    // Use TYPE_APPLICATION_OVERLAY for Android 8.0+, fallback to TYPE_SYSTEM_ALERT for older versions
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.O 
        ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY 
        : WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    // Critical flags for lock screen behavior and focus
    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, // Let touches outside your UI pass through to the lock screen
    PixelFormat.TRANSLUCENT
);
params.gravity = Gravity.BOTTOM;
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL; // Adjust brightness as needed

Key Flag Explanations:

  • Removed FLAG_NOT_FOCUSABLE: This allows your EditText to request focus and trigger the IME.
  • FLAG_ALLOW_LOCK_WHILE_SCREEN_ON: Ensures your UI stays visible even if the lock screen is active (no auto-dismiss).
  • FLAG_NOT_TOUCH_MODAL: Lets users interact with the lock screen behind your UI if needed (optional, but improves UX).

Step 3: Create and Add the Editable UI

Now initialize your EditText with focusable properties, then add it to the WindowManager from your Service:

// Initialize EditText with IME support
EditText inputField = new EditText(this);
inputField.setHint("Type here...");
inputField.setTextColor(ContextCompat.getColor(this, android.R.color.white));
inputField.setTextSize(24f);
inputField.setInputType(InputType.TYPE_CLASS_TEXT);
// Ensure it can gain focus
inputField.setFocusable(true);
inputField.setFocusableInTouchMode(true);

// Get WindowManager instance
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(inputField, params);

// Force show the keyboard once the view is attached to the window
inputField.post(() -> {
    InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    imm.showSoftInput(inputField, InputMethodManager.SHOW_IMPLICIT);
});

Fixes for Your Transparent Activity Approach (Alternative)

If you prefer using an Activity instead, you missed a few critical flags in your Activity's code. Add these in onCreate() before setContentView():

getWindow().addFlags(
    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD // Optional: bypasses swipe lock (not PIN/password)
);

Also, update your manifest to use the non-deprecated attribute for lock screen visibility:

<activity
    android:name=".OverlayActivity"
    android:theme="@style/TransparentActivity"
    android:showWhenLocked="true"
    android:excludeFromRecents="true" />

Critical Notes

  1. Foreground Service Requirement: On Android 8.0+, background services can't show overlays. Make your Service a foreground service by showing a persistent notification:
    Notification notification = new NotificationCompat.Builder(this, "overlay_channel")
            .setContentTitle("Overlay Active")
            .setSmallIcon(R.drawable.ic_notification)
            .build();
    startForeground(1, notification);
    
  2. Cleanup: Always remove the view from WindowManager when your Service is destroyed to avoid memory leaks:
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (inputField != null && windowManager != null) {
            windowManager.removeView(inputField);
        }
    }
    
  3. Android 10+ Edge Cases: For PIN/password locks, TYPE_APPLICATION_OVERLAY should work, but if you encounter issues, consider using TYPE_ACCESSIBILITY_OVERLAY (requires enabling an accessibility service for your app, which has stricter Play Store guidelines).

Content of the question comes from Stack Exchange, asked by Udi Oshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:27:22