首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >谷歌日历或Instagram如何让他们的应用程序即使在强制停止后也能一直运行

谷歌日历或Instagram如何让他们的应用程序即使在强制停止后也能一直运行
EN

Stack Overflow用户
提问于 2017-04-05 19:48:45
回答 4查看 691关注 0票数 18

看起来强制停止应该会阻止应用程序运行,它甚至会禁用所有应用程序的警报。然而,我发现谷歌日历中的通知即使在强制停止后仍然显示良好,我一直看到Instagram应用程序运行,即使我关闭它,它只是自动重新启动,它又一次出现在那里。

那么,有什么方法可以让应用程序持续运行呢?我正在做有提醒的应用程序,需要在特定的时间显示通知,无论应用程序以前是如何关闭的。

EN

回答 4

Stack Overflow用户

发布于 2017-04-07 23:25:23

对于初学者来说,他们有一个作业调度系统,可以调度要执行的作业,这些作业可以停止、启动或恢复。他们实现了一种检测崩溃的机制,想想java-script,如果一个应用程序崩溃了,它可以重新启动(nodemon或永远),在android中有服务,可以启动或恢复,有这个特殊的服务行为来重新启动崩溃的服务。

START_ redeliver _INTENT-告诉系统在崩溃后重新启动服务,并重新传递崩溃时存在的意图。

Android5.0棒棒糖(API21)版本通过JobScheduler类引入了作业调度程序API。此接口允许在设备有更多可用资源时批量执行作业。通常,此API可用于调度对用户而言不是时间关键型的所有事情。

您还可以将警报、广播接收器和线程与反应式编程相结合来执行job.Alarms (基于AlarmManager类),这为您提供了一种在应用程序生命周期之外执行基于时间的操作的方法。例如,您可以使用警报来启动一个长期运行的操作,例如每天启动一次服务以下载天气预报。

您可以将可观察对象附加到执行特定操作的特定任务,您可以通过设计自己的可观察对象来实现异步i/o、计算操作,甚至是“无限”数据流。

票数 1
EN

Stack Overflow用户

发布于 2017-04-14 18:17:46

只要加上Sagar Damani的回答,就需要一个服务调用来在后台运行您的长时间操作,但它们也在单独的进程中运行。在androidMenifes.xml中声明服务或活动时,还要添加android:process="“属性。因此,如果用户终止/强制停止活动,它将始终是持久的。

票数 1
EN

Stack Overflow用户

发布于 2017-04-15 00:35:24

根据我有限的知识,你需要使用AlarmManagerWakefulBroadcastReceiver,并为所有这些后台任务创建一个ServiceIntentService。有关它的更多信息,请阅读here。我有一个服务,我使用我的Firebase消息应用程序,它工作正常,即使在用户关闭该应用程序。在我的例子中,我使用以下服务定期连接到Firebase。

首先,我使用以下类来设置AlarmManager

代码语言:javascript
复制
public class FirebaseHandler {

    private Context context;
    private static final long FIREBASE_ALARM_CYCLE_TIME = 300000;

    // constructors
    public FirebaseHandler(Context context) {
        this.context = context;
    }

    // set alarm
    public void setAlarm() {
        // create pending intent
        Intent intent = new Intent(context, AlarmReceiver.class);
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        final PendingIntent pendingIntent = PendingIntent.getBroadcast(
            context,
            AlarmReceiver.ALARM_REQUEST_CODE,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

        // create alarm
        AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarm.setInexactRepeating(
            AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() + FIREBASE_ALARM_CYCLE_TIME,
            FIREBASE_ALARM_CYCLE_TIME,
            pendingIntent);
    }
}

我只是通过在活动中的某处调用new FirebaseHandler(getApplicationContext()).setAlarm()来启动此操作。AlarmReceiver类如下所示。

代码语言:javascript
复制
public class AlarmReceiver extends WakefulBroadcastReceiver {

    public static final int ALARM_REQUEST_CODE = 12345;

    @Override
    public void onReceive(Context context, Intent wakefulIntent) {
        Intent intent = new Intent(context, FirebaseAlarmService.class);
        startWakefulService(context, intent);
    }
}

FirebaseAlarmService类如下所示。

代码语言:javascript
复制
public class FirebaseAlarmService extends Service {

    private static final String CLASSNAME = FirebaseAlarmService.class.getSimpleName();
    private HandlerThread handlerThread;

    // onStartCommand
    @Override
    public int onStartCommand(final Intent intent, int flags, final int startId) {
        // start a new thread
        // this depends on your need. I need to do a continuous operation for some time
        // you can use IntentService too
        handlerThread = new HandlerThread(CLASSNAME);
        handlerThread.start();
        Handler handler = new Handler(handlerThread.getLooper());
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
            // all your codes here for the background task...

            // remember to release the wake lock and stop service 
            AlarmReceiver.completeWakefulIntent(wakefulIntent);
            stopSelf();
        } 
        return START_NOT_STICKY;
    }

    // this is the part that does the trick
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        // when the service is killed, start it again
        new FirebaseHandler(getApplicationContext()).setAlarm();
    }

    // onDestroy
    @Override
    public void onDestroy() {
        super.onDestroy();
        // make sure to quit the thread
        handlerThread.quit();
    }
}

总之,FirebaseHandler设置了一个AlarmManager,它将定期调用WakefulBroadcastReceiver,它将定期启动一个Service。当服务被终止时,服务本身将再次启动AlarmManager onTaskRemoved

AndroidManifest中,您需要添加以下唤醒锁权限。

代码语言:javascript
复制
<uses-permission android:name="android.permission.WAKE_LOCK" />

还要记得添加接收器。

代码语言:javascript
复制
<receiver
    android:name=".receiver.AlarmReceiver"
    android:process=":remote" />

额外好处:手机重启或应用程序通过PlayStore更新后,你可能想要启动这项服务。创建另一个WakefulBroadcastReceiver

代码语言:javascript
复制
public class BootBroadcastReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent wakefulIntent) {
        // check if user is login, then set the alarm
        if (isLogin) {
            new FirebaseHandler(context).setAlarm();
        }

        // remove wake lock
        WakefulBroadcastReceiver.completeWakefulIntent(wakefulIntent);
    }
}

AndroidManifest中,添加所需的权限。

代码语言:javascript
复制
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

添加意图过滤器。

代码语言:javascript
复制
<receiver android:name=".receiver.BootBroadcastReceiver">
    <intent-filter>
        <!-- get notified on reboot -->
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <!-- get notified on app updated -->
        <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

小贴士:有时你会发现上面的方法不起作用。这很大程度上不是你的错。这是手机的安全设置导致的,特别是小米手机。用户将需要“信任”应用程序,并在手机设置中启用“自动启动”,然后一切都应该很好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43230330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档