Android 如何保持前台应用程序全天候运行?

Android 如何保持前台应用程序全天候运行?,android,Android,我正在研究如何让我的Android应用程序在前台运行 这将是一个私人发布的应用程序,所以我可以做任何可能的事情来确保它在设备上持续运行(HDMI电视棒) 那么,我如何确保应用程序无论发生什么情况都能保持运行呢?该应用程序在资源使用方面非常轻量级,因此让它全天候运行应该不会有问题 我在清单中读到了关于持久参数的信息,但它似乎只适用于系统应用程序 我应该将我的应用程序设置为系统应用程序吗?我将如何做到这一点,它会有帮助吗?使用以下方法: import android.os.PowerManager;

我正在研究如何让我的Android应用程序在前台运行

这将是一个私人发布的应用程序,所以我可以做任何可能的事情来确保它在设备上持续运行(HDMI电视棒)

那么,我如何确保应用程序无论发生什么情况都能保持运行呢?该应用程序在资源使用方面非常轻量级,因此让它全天候运行应该不会有问题

我在清单中读到了关于持久参数的信息,但它似乎只适用于系统应用程序

我应该将我的应用程序设置为系统应用程序吗?我将如何做到这一点,它会有帮助吗?

使用以下方法:

import android.os.PowerManager;

public class MyActivity extends Activity {

    protected PowerManager.WakeLock mWakeLock;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(final Bundle icicle) {
        setContentView(R.layout.main);

        /* This code together with the one in onDestroy() 
         * will make the screen be always on until this Activity gets destroyed. */
        final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
        this.mWakeLock.acquire();
    }

    @Override
    public void onDestroy() {
        this.mWakeLock.release();
        super.onDestroy();
    }
}
在舱单上:

<uses-permission android:name="android.permission.WAKE_LOCK" />


如图所示:

这不是一件容易实现的事情,因为从技术上讲,前台应用程序不应该不停地运行。此外,如果android内存不足,它将开始杀死风险最小的应用程序,这将要求用户重新启动应用程序

如前所述,您可以将其作为系统应用程序,但我认为您确实需要根设备或构建自己的ROM,并将应用程序作为ROM的一部分。可能不是满足您需求的最佳解决方案,尽管很少有人能够将ROM闪存到其设备上

我认为最简单的解决方案是在清单中说明你的应用程序是主屏幕的替代品,即启动器应用程序。我不知道确切的代码,但这将进入android清单中的应用程序部分。这意味着一旦设备启动,或者用户按下home按钮,他们就会被带到你的应用程序

  • 如果您想要外部应用程序,请使用:

  • 如果您想以编程方式执行此操作,您可以使用每“x”毫秒轮询一次的服务,以查看您的应用程序是否位于前台。如果不是,它将启动/将您的应用程序置于前台。这样做:

    public class PersistService extends Service {
    
        private static final int INTERVAL = 3000; // poll every 3 secs
        private static final string YOUR_APP_PACKAGE_NAME = "YOUR_APP_PACKAGE_NAME";
    
        private static boolean stopTask;
        private PowerManager.WakeLock mWakeLock;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            stopTask = false;
    
            // Optional: Screen Always On Mode!
            // Screen will never switch off this way
            mWakeLock = null;
            if (settings.pmode_scrn_on){
                PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
                mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "a_tag");
                mWakeLock.acquire();
            }
    
            // Start your (polling) task
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
    
                    // If you wish to stop the task/polling
                    if (stopTask){
                        this.cancel();
                    }
    
                    // The first in the list of RunningTasks is always the foreground task.
                    RunningTaskInfo foregroundTaskInfo = activityManager.getRunningTasks(1).get(0);
                    String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
    
                    // Check foreground app: If it is not in the foreground... bring it!
                    if (!foregroundTaskPackageName.equals(YOUR_APP_PACKAGE_NAME)){
                        Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(YOUR_APP_PACKAGE_NAME);
                        startActivity(LaunchIntent);
                    }
                }
            };
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(task, 0, INTERVAL);
        }
    
        @Override
        public void onDestroy(){
            stopTask = true;
            if (mWakeLock != null)
                mWakeLock.release();
            super.onDestroy();
        }
    }
    
上面的代码还有一个“选项”,可以强制屏幕始终打开!当然,您需要以下权限:

<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

同时,不要忘记注册您的服务:

    <service android:name="YOURPACAKGE.PersistService" 
     android:enabled="true"/>

您可以通过在
标签中添加以下2个类别标签,使您的应用程序成为启动器:

  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.HOME"/>

我尝试过这个解决方案,但它不能隐藏上面的应用程序,比如Facebook Messenger聊天头。

我通过运行一个粘性服务来解决这个问题,该服务在活动结束时重新启动应用程序

//Your activity

@Override
public void onPause() {
    super.onPause();

    if (yourservice != null) {
        yourservice.validateActivityOnPause();
    }
}
在validateActivityOnPause()中,有如下内容:

//Your service

public void validateLynxActivityOnPause() {
    //Do some stuff here

    Intent startActivityIntent = new Intent(this, LynxActivity.class);
    startActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    this.startActivity(startActivityIntent);
}

现在activityManager.getRunningAppProcesses()已被弃用(从API21开始),您将需要替换:

RunningTaskInfo foregroundTaskInfo = activityManager.getRunningTasks(1).get(0);
String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
与:

顺便说一句,我不确定OP是如何让屏幕一直亮着的。我不确定它是否能像他那样工作,但更重要的是,不推荐使用唤醒锁,因为您需要添加权限,这为bug打开了大门。相反,使用窗口管理器标志通常是更好的做法:

您可以尝试
startocktask()

有关更多信息,

我相信只有在设备根目录下,您才能将应用程序设置为系统应用程序。你可能想考虑让你的应用程序成为家庭屏幕替代品,比如亭模式应用程序。看我的答案。这不是OP想要的。他想让他的应用程序永久运行,这只会在他的应用程序运行时保持屏幕打开,但设备的用户将能够转到其他应用程序,但一旦它运行,它应该无休止地运行吗?否则,如果应用程序不在前台,则可以选择处理OnDestroy和一些broadcastReceivers来启动该应用程序。按home按钮,然后使用设备上可能安装的其他应用程序,不会阻止用户,因此会将OP应用程序置于后台。Thomas-感谢您的输入,但正如布罗迪所说,你误解了。保持屏幕打开是我应用程序的一部分,但这与我需要解决的问题不同。遗憾的是,即使使用您的代码,如果系统需要内存,应用程序仍可能关闭OP可能还需要记住的一点是,在使用自定义的home替换启动后,可能会出现问题(至少我是这样做的)。回答很好,这样即使应用程序不可见(另一个应用程序已打开),也能保持应用程序运行吗?Thx。如果它根本没有运行或在后台运行,它将还原它,即将它带到前台。回答很好,但:我唯一的问题是收到电子邮件通知时,例如,我可以选择电子邮件,它会收到前台应用程序。我如何禁用它?看起来应用程序AutoStart and Stay已经不存在了
RunningTaskInfo foregroundTaskInfo = activityManager.getRunningTasks(1).get(0);
String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
List<ActivityManager.RunningAppProcessInfo> tasks = activityManager.getRunningAppProcesses();
String foregroundTaskPackageNameTest = tasks.get(0).processName;
import java.util.List;