如何在Ionic Capacitor应用屏幕解锁时触发函数(支持非活跃/未启动状态)
实现Ionic Capacitor应用屏幕解锁触发函数的思路
由于Capacitor官方没有提供直接监听屏幕解锁的跨平台插件,需要针对iOS和Android分别做原生扩展,结合Capacitor的桥接机制来实现需求,以下是具体方案:
Android 端实现
- 监听系统广播:使用
BroadcastReceiver监听系统的ACTION_USER_PRESENT广播,该广播会在设备解锁完成时发送。 - 静态注册广播接收器:在
AndroidManifest.xml中静态注册接收器,确保应用未启动时也能接收广播(注意:Android 3.1+ 要求应用至少被用户启动过一次,否则静态广播不生效)。示例配置:<receiver android:name=".ScreenUnlockReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver> - 处理广播逻辑:在接收器中启动前台服务(Android 8+ 后台限制要求,避免代码被系统杀死),通过Capacitor桥接触发JS侧函数。示例接收器代码:
public class ScreenUnlockReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) { // 启动前台服务 Intent serviceIntent = new Intent(context, ScreenUnlockService.class); ContextCompat.startForegroundService(context, serviceIntent); } } } - 前台服务中触发JS事件:在服务中获取Capacitor的
Bridge实例,触发自定义事件:public class ScreenUnlockService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { // 创建前台通知(必须) Notification notification = new NotificationCompat.Builder(this, "unlock_channel") .setContentTitle("监听屏幕解锁") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(1, notification); // 触发JS事件 CapacitorBridge bridge = CapacitorBridge.getInstance(this); if (bridge != null) { bridge.triggerJSEvent("screenUnlocked", null); } // 执行完后停止服务(或根据需求保持) stopForeground(true); stopSelf(); return START_NOT_STICKY; } @Nullable @Override public IBinder onBind(Intent intent) { return null; } } - 权限配置:在
AndroidManifest.xml中添加前台服务权限:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
iOS 端实现
- 监听系统通知:通过
NotificationCenter监听UIApplicationProtectedDataDidBecomeAvailable通知,该通知会在设备解锁、应用受保护数据可用时触发(支持后台或未启动状态)。 - AppDelegate中处理通知:在
AppDelegate的application:didFinishLaunchingWithOptions:方法中注册通知,或直接实现系统回调方法:import UIKit import Capacitor @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 注册通知监听 NotificationCenter.default.addObserver(self, selector: #selector(onScreenUnlocked), name: UIApplication.protectedDataDidBecomeAvailableNotification, object: nil) return true } @objc func onScreenUnlocked() { // 触发JS事件 if let bridge = CAPBridgeViewController.getBridge() { bridge.triggerJSEvent("screenUnlocked", data: nil) } // 若需执行长时间任务,需申请后台任务断言 var backgroundTask: UIBackgroundTaskIdentifier = .invalid backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "ScreenUnlockTask") { UIApplication.shared.endBackgroundTask(backgroundTask) backgroundTask = .invalid } } // 也可直接使用系统回调方法 func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) { onScreenUnlocked() } } - 后台模式配置:在
Info.plist中添加后台模式支持(确保应用能被唤醒到后台):<key>UIBackgroundModes</key> <array> <string>fetch</string> </array>
Ionic JS 侧处理
在应用中监听原生触发的自定义事件,执行指定函数:
import { Capacitor } from '@capacitor/core'; // 在应用初始化时注册监听 Capacitor.addListener('screenUnlocked', () => { // 执行你的指定函数 console.log('屏幕已解锁,触发目标函数'); yourTargetFunction(); });
注意事项
- Android:首次安装后需用户手动启动应用一次,否则静态广播接收器无法生效;前台服务需要创建通知,避免被系统回收。
- iOS:后台执行时间有限(约30秒),需保证触发的函数逻辑轻量;若需长时间任务,需使用后台任务断言。
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

