如何让Flutter应用在Android平板上24/7保持前台运行?
Hey there! I’ve worked on several kiosk-style Flutter apps for Android tablets that need non-stop runtime, so I know exactly the headaches you’re facing. Let’s break down how to eliminate the lockscreen issue and keep your app reliably in the foreground around the clock:
1. Stop the Lockscreen from Ever Appearing (Root Cause Fix)
Your current WAKE_LOCK and screen plugin help keep the display on, but they don’t fully disable the system lockscreen. Here are two foolproof ways:
Option A: System-Level Settings (Easiest if You Control the Tablet)
Since this is a dedicated display device, just turn off the lockscreen directly in Android settings:
- Go to Settings > Security > Screen Lock
- Select None (or "Swipe" if you need minimal protection, but "None" is best for 24/7 display)
Option B: Programmatic Lockscreen Disable (Device Policy Manager)
If you can’t rely on manual settings, use Android’s Device Policy Manager to permanently disable the lockscreen. This requires user approval once, but it’s fully automated after that:
Step 1: Add Device Admin Components to AndroidManifest.xml
<receiver android:name=".DeviceAdminReceiver" android:description="@string/device_admin_description" android:label="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>
Step 2: Create res/xml/device_admin.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <disable-keyguard /> </uses-policies> </device-admin>
Step 3: Call Native Code via Flutter MethodChannel
In your Android native code (Kotlin/Java), add a method to activate the device admin and disable the lockscreen:
fun disableKeyguard() { val devicePolicyManager = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val componentName = ComponentName(this, DeviceAdminReceiver::class.java) if (devicePolicyManager.isAdminActive(componentName)) { // Already active: disable lockscreen devicePolicyManager.setKeyguardDisabled(componentName, true) } else { // Request user to activate device admin val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN) intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName) intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Enable this to keep the display unlocked") startActivityForResult(intent, 1001) } }
Then call this method from your Flutter code on app startup.
2. Keep Your App in the Foreground (Prevent System Termination)
Even with the lockscreen gone, Android’s background restrictions can kill your app after hours. Use these steps to make it "untouchable":
Use a Foreground Service
Android prioritizes foreground apps, so wrap your app’s core logic in a foreground service:
Step 1: Add Permissions to AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For Android 12+, add this special use permission --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
Step 2: Create a Foreground Service Class
class KioskForegroundService : Service() { override fun onBind(intent: Intent): IBinder? = null override fun onCreate() { super.onCreate() // Create a low-priority notification channel (won't bother users) val channelId = "kiosk_service_channel" if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "Kiosk Display Service", NotificationManager.IMPORTANCE_LOW ) getSystemService(NotificationManager::class.java).createNotificationChannel(channel) } // Build and show the foreground notification val notification = NotificationCompat.Builder(this, channelId) .setContentTitle("Display App Running") .setContentText("Continuous display service active") .setSmallIcon(R.mipmap.ic_launcher) .build() startForeground(1, notification) } }
Step 3: Start the Service from Flutter
Call this native method on app startup via MethodChannel:
fun startKioskService() { val intent = Intent(this, KioskForegroundService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(intent) } else { startService(intent) } }
Exempt from Battery Optimization
Android’s battery saver will kill long-running apps unless you opt out:
Step 1: Add Permission to AndroidManifest.xml
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Step 2: Request Exemption via Native Code
fun requestBatteryOptimizationExemption() { val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) intent.data = Uri.parse("package:$packageName") startActivity(intent) }
This prompts the user to allow your app to bypass battery restrictions—critical for 24/7 runtime.
3. Solidify Your App as the Default Launcher
You already added the HOME category, but let’s make sure it’s set as the default so users can’t escape to the system desktop:
Verify the Activity Intent Filter
Double-check your MainActivity in AndroidManifest.xml:
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Set as Default Launcher Programmatically
Add this native method to prompt users to set your app as the default home screen:
fun setAsDefaultLauncher() { val intent = Intent(Intent.ACTION_MAIN) intent.addCategory(Intent.CATEGORY_HOME) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK startActivity(Intent.createChooser(intent, "Set as default display app")) }
Final Checklist
- Disable lockscreen via Device Policy Manager or system settings
- Start a foreground service to keep the app prioritized
- Exempt the app from battery optimization
- Set the app as the default launcher
Follow these steps, and your app will run 24/7 without lockscreen interruptions or system termination.
内容的提问来源于stack exchange,提问作者Emam




