如何让安卓应用始终在后台运行?

75
我正在使用一款安卓设备。当我打开 设置 > 应用 > 正在运行 时,屏幕左上角有一个选项,可以查看:(1) 正在运行的进程 (2) 缓存后台进程。而我想要始终运行的应用程序(24×7)不幸地列在了 (2) 缓存后台进程下,我希望它们能列在 (1) 正在运行的进程下(如果可能的话)。是否可以实现?或者简单说,如何让安卓应用程序始终在后台运行?

你可以尝试创建一个服务。这里是官方文档的链接:Link - JP_
对于新的API,你可以使用这个技巧 ;):https://dev59.com/AHE85IYBdhLWcg3w3Xv6#49878237 - MHSaffari
3个回答

113

您需要在应用程序类中启动一个服务,以便始终运行。

如果这样做,您的服务将始终运行。即使用户从任务管理器中终止了您的应用程序或强制停止了您的应用程序,它也将重新开始运行。

创建一个服务:

public class YourService extends Service {

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // do your jobs here
        return super.onStartCommand(intent, flags, startId);
    }
}

创建一个Application类并启动你的服务:
public class App extends Application {

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

        startService(new Intent(this, YourService.class));
    }
}

在你的AndroidManifest.xml文件中的"application"标签中添加"name"属性。
android:name=".App"

同样,不要忘记将您的服务添加到AndroidManifest.xml文件中的“应用程序”标签中。
<service android:name=".YourService"/>

如果API级别为28或更高,则还需要在“清单”标签中添加此权限请求:

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

更新

在安卓Oreo之后,谷歌引入了一些后台限制。因此,上述解决方案可能不起作用。当用户从任务管理器中杀死您的应用程序时,Android系统也会杀死您的服务。如果您想要运行一个始终在后台活动的服务,则必须运行一个前台服务并显示一个持续的通知。因此,请按照以下方式编辑您的服务。

public class YourService extends Service {

    private static final int NOTIF_ID = 1;
    private static final String NOTIF_CHANNEL_ID = "Channel_Id";

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){

        // do your jobs here

        startForeground();
        
        return super.onStartCommand(intent, flags, startId);
    }

    private void startForeground() {
        Intent notificationIntent = new Intent(this, MainActivity.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

        startForeground(NOTIF_ID, new NotificationCompat.Builder(this, 
                NOTIF_CHANNEL_ID) // don't forget create a notification channel first
                .setOngoing(true)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(getString(R.string.app_name))
                .setContentText("Service is running background")
                .setContentIntent(pendingIntent)
                .build());         
    }
}

编辑:受限制的OEM厂商

不幸的是,一些OEM厂商(如小米、一加、三星、华为等)由于提供更长的电池续航时间而限制后台操作。对于这些OEM厂商,目前没有合适的解决方案。用户需要允许一些特殊权限,这些权限是针对OEM厂商特定的,或者他们需要将您的应用程序添加到设备设置中的白名单应用程序列表中。您可以从https://dontkillmyapp.com/获取更详细的信息。

如果后台操作对您来说是必须的,您需要向用户解释为什么您的功能无法正常工作以及他们如何通过允许这些权限来启用您的功能。我建议您使用AutoStarter库(https://github.com/judemanutd/AutoStarter),以便从您的应用程序轻松重定向用户至权限页面。

顺便说一下,如果您需要运行一些周期性任务而不是持续的后台任务,最好看一下WorkManager(https://developer.android.com/topic/libraries/architecture/workmanager)。


1
谢谢。但是,如何创建一个服务?有适当的应用程序吗?抱歉,因为我只是一个初学者...您能提供一个从头开始的逐步指南吗? - Manuel
5
请在Android Studio左侧的项目资源管理器中,右键点击“app”。然后选择“新建 >> 服务 >> 服务”。请注意保持原文意思不变,同时使翻译内容通俗易懂。 - sembozdemir
3
Android Studio是一种集成开发环境(IDE),用于编写Android应用程序。它可在桌面上运行(Windows、Mac或Linux),您需要使用它来编写Android应用程序,也可以使用Eclipse IDE。在项目资源管理器的左侧,"App"是项目文件中的一个文件夹。这样解释清楚了吗? - Anish Muthali
5
你的代码让我朝着正确的方向前进——最终找到了解决方案。感谢你,伙计!@sembozdemir - SilSur
3
@sembozdemir,我尝试了您在Android 8.1上的解决方案,但不起作用。也就是说,一旦我从“设置”应用程序中“强制停止”我的应用程序,该应用程序不会自动重启,我仍然需要手动重启该应用程序。您测试过哪个版本的Android上的解决方案?我的理解是,一旦停止应用程序,其具有相同进程的服务也应停止,否则这是一个设计缺陷。 - jonathanzh
显示剩余12条评论

4

在一些移动设备上,例如我的小米Redmi 3(MIUI系统),您可以将特定应用程序添加到列表中,在任务管理器中终止应用程序时,该应用程序不会停止(它会停止,但会重新启动)。

只需转到“设置”>“权限”>“自启动”,即可实现此功能。


是的,你说得对。在一些手机上,比如小米和Vivo,我们需要更改设置并从设置应用程序中为应用程序授予特殊权限以在后台运行。即使您已经创建了一个在应用程序关闭时自动重新启动的服务,该服务也不会运行,除非您在手机的设置应用程序中设置权限。 - Gaurav Bharti
我能否从我的应用程序请求此权限,还是必须告诉用户手动更改设置? - ColdSpike

0
在小米和vivo手机上 - 使用上述解决方案是不够的。您还必须告诉用户手动添加权限。 您可以通过打开手机设置中的正确位置来帮助他们。不同的手机型号可能会有所不同。

请详细说明“添加权限”。 - Rohit Surwase
2
@RohitSurwase IGNORE_BATTERY_OPTIMIZATIONS权限可能会解决这个问题。但是我的Oppo手机无论进行哪些设置更改,都会关闭应用程序。因此,我不得不采用前台服务。 - Anirudh Ganesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接