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

求助:小米Android TV前台24/7运行APP遭系统查杀的解决办法

解决方案:小米Android TV前台APP 24/7持续运行适配

可以实现前台24/7持续运行,但需要针对小米定制的Android TV系统做专属适配,以下是具体方案:


1. 小米TV系统层面白名单配置

小米TV自带激进的后台/前台管控机制,仅靠代码权限无法完全绕过,必须手动完成以下设置:

  • 进入「设置」→「应用管理」→找到你的APP→「权限管理」,开启自启动和后台运行权限
  • 进入「电池与性能」(部分型号叫「省电优化」),将APP的后台运行策略设置为无限制(拒绝「智能限制」或「禁止后台」选项)
  • 手动关闭系统屏保:进入「设置」→「显示」→「屏保」,选择「关闭」

2. 改用前台服务(Foreground Service)替代普通唤醒锁

普通唤醒锁在小米系统的管控下容易失效,前台服务会被系统判定为「正在执行核心任务」,优先级更高:

步骤1:声明权限

在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- TV场景推荐添加媒体类前台服务权限,更贴合系统规则 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>

<!-- 注册服务 -->
<service android:name=".DashboardForegroundService" android:exported="false"/>

步骤2:实现前台服务类

public class DashboardForegroundService extends Service {
    private static final int NOTIFICATION_ID = 1001;
    private static final String CHANNEL_ID = "DashboardServiceChannel";
    private Handler checkHandler;
    private Runnable activityCheckRunnable;

    @Override
    public void onCreate() {
        super.onCreate();
        createNotificationChannel();
        initActivityChecker();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 创建前台通知(TV端可能不显示,但必须创建以满足系统要求)
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("仪表盘运行中")
                .setContentText("保持前台持续运行")
                .setSmallIcon(R.drawable.ic_service_notification) // 必须设置图标
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();

        startForeground(NOTIFICATION_ID, notification);
        checkHandler.post(activityCheckRunnable);
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID,
                    "前台服务通道",
                    NotificationManager.IMPORTANCE_LOW
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }

    // 初始化Activity存活检测逻辑
    private void initActivityChecker() {
        checkHandler = new Handler(Looper.getMainLooper());
        activityCheckRunnable = new Runnable() {
            @Override
            public void run() {
                if (!isActivityInForeground()) {
                    restartMainActivity();
                }
                checkHandler.postDelayed(this, 30000); // 每30秒检查一次
            }
        };
    }

    // 判断主Activity是否处于前台
    private boolean isActivityInForeground() {
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
        if (processes == null) return false;
        for (ActivityManager.RunningAppProcessInfo process : processes) {
            if (process.processName.equals(getPackageName()) 
                && process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                return true;
            }
        }
        return false;
    }

    // 重启主Activity(绕过Android 10+后台启动限制)
    private void restartMainActivity() {
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                getApplicationContext(),
                0,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );
        try {
            pendingIntent.send();
        } catch (PendingIntent.CanceledException e) {
            e.printStackTrace();
        }
    }
}

步骤3:在主Activity启动前台服务

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 启动前台服务
    Intent serviceIntent = new Intent(this, DashboardForegroundService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(serviceIntent);
    } else {
        startService(serviceIntent);
    }
    // 保持屏幕常亮
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    // 其他初始化逻辑...
}

3. 绕过系统闲置检测(可选)

如果系统仍因「设备闲置」启动屏保或查杀APP,可定时模拟用户输入(需系统级权限):

步骤1:授予权限

通过ADB命令授予触摸注入权限:

adb shell pm grant com.your.package.name android.permission.INJECT_EVENTS

步骤2:添加模拟输入逻辑

在前台服务的activityCheckRunnable中添加:

// 每5分钟模拟一次触摸事件
private void simulateUserInput() {
    try {
        Instrumentation inst = new Instrumentation();
        // 发送空触摸事件,避免干扰用户操作
        inst.sendPointerSync(MotionEvent.obtain(
                SystemClock.uptimeMillis(),
                SystemClock.uptimeMillis(),
                MotionEvent.ACTION_DOWN,
                0, 0, 0
        ));
        inst.sendPointerSync(MotionEvent.obtain(
                SystemClock.uptimeMillis(),
                SystemClock.uptimeMillis(),
                MotionEvent.ACTION_UP,
                0, 0, 0
        ));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

关键说明

小米TV的定制系统会针对前台APP进行周期性资源扫描,只有同时满足「系统白名单+前台服务+屏幕常亮」三个条件,才能稳定实现24/7持续运行。如果仍出现查杀,可尝试降低APP的内存占用,避免触发系统的高内存进程查杀机制。

内容的提问来源于stack exchange,提问作者Oleksii Kovalchuk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:44:54