Android SDK29环境下检测锁屏状态的替代方法咨询(无人机应用)
Hey there! Let's figure out how to reliably detect when the phone locks so you can trigger your drone's landing. You’re right that older KeyguardManager methods are deprecated, and just using onPause() isn’t perfect—since that method fires when you switch apps too, not just when locking the screen. Here are some solid approaches tailored to your SDK setup (minSdk 15, targetSdk 29):
1. Use Updated KeyguardManager Methods (Most Reliable)
While some old KeyguardManager methods are deprecated, there’s still a supported way to check if the device is locked. We’ll use version-specific checks to cover your minSdk 15 up to targetSdk 29:
private boolean isDeviceLocked() { KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // For API 23+, use the recommended method return keyguardManager.isDeviceLocked(); } else { // Fallback for older versions (API 16-28) return keyguardManager.isKeyguardLocked(); } }
Then, update your onPause() method to only trigger landing if the device is actually locked:
@Override protected void onPause() { super.onPause(); if (isDeviceLocked()) { // Execute drone landing logic here } }
This way, you avoid triggering landing when the user just switches to another app.
2. Listen for ACTION_SCREEN_OFF Broadcast
When the phone locks, the screen usually turns off—so you can listen for the ACTION_SCREEN_OFF intent. Note that starting from API 26, background broadcast receivers are restricted, so we’ll register it dynamically in your Activity:
private BroadcastReceiver screenOffReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { // Double-check if the device is locked to avoid false triggers if (isDeviceLocked()) { // Trigger drone landing } } } }; @Override protected void onResume() { super.onResume(); // Register the receiver when the Activity is active IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); registerReceiver(screenOffReceiver, filter); } @Override protected void onPause() { super.onPause(); // Unregister to avoid memory leaks unregisterReceiver(screenOffReceiver); }
Adding the isDeviceLocked() check here ensures you don’t land the drone if the screen turns off but the device isn’t locked (like if the screen times out on an unlocked phone).
3. Activity Lifecycle Callbacks (For Global Monitoring)
If your app has multiple Activities and you need a global way to detect when the app goes into the background and the device is locked, you can register ActivityLifecycleCallbacks in your Application class:
public class MyApp extends Application implements Application.ActivityLifecycleCallbacks { private int activeActivityCount = 0; @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(this); } @Override public void onActivityResumed(Activity activity) { activeActivityCount++; } @Override public void onActivityPaused(Activity activity) { activeActivityCount--; if (activeActivityCount == 0) { // App is in background—check if device is locked KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); boolean isLocked; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { isLocked = keyguardManager.isDeviceLocked(); } else { isLocked = keyguardManager.isKeyguardLocked(); } if (isLocked) { // Trigger drone landing } } } // Implement other lifecycle methods with empty bodies @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} @Override public void onActivityStarted(Activity activity) {} @Override public void onActivityStopped(Activity activity) {} @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} @Override public void onActivityDestroyed(Activity activity) {} }
Don’t forget to declare your custom Application in AndroidManifest.xml:
<application android:name=".MyApp" ...> ... </application>
Final Recommendation
For your single-Activity use case, combining the onPause() method with the isDeviceLocked() check (Method 1) is the simplest and most reliable approach. If you want to react immediately when the screen locks (before onPause() fires), add the ACTION_SCREEN_OFF broadcast listener (Method 2) with the same lock check.
内容的提问来源于stack exchange,提问作者Sarath




