18

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

这将是一个私人分发的应用程序,所以我可以尽一切可能确保它在设备上持续运行(HDMI TV Stick)

那么,我怎样才能确保应用程序无论如何都保持运行?该应用程序在资源使用方面非常轻巧,因此希望它 24/7 运行应该不是问题。

我在清单中阅读了有关持久性参数的信息,但它看起来可能仅适用于系统应用程序?

我应该让我的应用程序成为系统应用程序吗?我该怎么做,会有帮助吗?

4

7 回答 7

16
  • 如果您想要外部应用程序使用:自动启动和停留!

  • 如果您想以编程方式执行此操作,您可以使用每“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"/>
于 2014-06-16T19:56:00.347 回答
3

用这个:

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" />

在这里看到:如何在我的应用程序中保持屏幕开启?

于 2013-08-16T15:04:56.470 回答
2

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

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

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

于 2013-08-16T15:14:38.323 回答
2

我通过运行粘性服务解决了这个问题,该服务在活动关闭时重新启动应用程序。

//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);
}
于 2017-07-07T13:12:33.183 回答
1

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

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;

作为旁注,我不确定 OP 保持屏幕始终亮着的方式。我不确定它是否像他所做的那样工作,但更重要的是,它已被弃用,并且非常建议不要使用唤醒锁,因为您需要添加权限,这为错误打开了大门。相反,使用窗口管理器标志通常是更好的做法: https ://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON

于 2018-07-13T12:12:49.883 回答
0

您可以通过将以下 2 个类别标签添加到标签中,使您的应用成为启动器<intent-filter>

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

那么您应该始终检查是否有另一个应用程序在上面运行,运行以下代码将用户引导到我们的应用程序:

  Intent startMain = new Intent(Intent.ACTION_MAIN);
  startMain.addCategory(Intent.CATEGORY_HOME);
  startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  startActivity(startMain);

我已经尝试过这个解决方案,但它无法隐藏在顶部绘制的应用程序,例如 Facebook Messenger 聊天头。

于 2015-06-29T15:28:38.073 回答
0

您可以尝试startLockTask(); 了解更多信息,请访问此处

于 2019-03-26T07:57:24.507 回答