即使用户强制关闭它,如何自动重启服务?

时间:2014-02-04 10:44:16

标签: android service alarm

我希望服务能够在我的应用程序中一直运行。因此,即使用户强行关闭,我也想重新启动它。肯定有一种方法可以像facebook这样的应用程序这样做。(它没有使用推送通知,即使互联网关闭,facebook也会重启其服务)。

任何帮助将不胜感激。谢谢!

10 个答案:

答案 0 :(得分:64)

首先,根据用户的意愿强行运行 非常糟糕的模式

无论如何,您可以使用BroadcastReceiver重新启动它,该onDestroy()处理从您服务的public class StickyService extends Service { private static final String TAG = "StickyService"; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); sendBroadcast(new Intent("YouWillNeverKillMe")); } } 发送的广播。

<强> StickyService.java

public class RestartServiceReceiver extends BroadcastReceiver
{

    private static final String TAG = "RestartServiceReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "onReceive");
    context.startService(new Intent(context.getApplicationContext(), StickyService.class));

    }

}

<强> RestartServiceReceiver.java

    <service android:name=".StickyService" >
    </service>

    <receiver android:name=".RestartServiceReceiver" >
        <intent-filter>
            <action android:name="YouWillNeverKillMe" >
            </action>
        </intent-filter>
    </receiver>

声明清单文件中的组件:

StickyService

在组件中启动Application(例如ActivityFragmentstartService(new Intent(this, StickyService.class)); ):

sendBroadcast(new Intent("YouWillNeverKillMe"));

OR

{{1}}

答案 1 :(得分:11)

您必须使用覆盖sticky service方法创建onTaskRemoved,您可以在其中设置闹钟服务以再次触发代码。

public class BackgroundService extends Service {

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        //create an intent that you want to start again.
        Intent intent = new Intent(getApplicationContext(), BackgroundService.class);
        PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
        super.onTaskRemoved(rootIntent);
    }
}

此外,在像小米,Huwaei这样的设备中,一旦从最近的应用程序中移除应用程序,该应用程序就会被关闭。这是因为制造商具有可提高内存/电池性能的任务管理器功能。

您可以查看此链接以获取更多信息:https://stackoverflow.com/a/41360159/2798289

答案 2 :(得分:4)

每当服务被终止时,始终会调用其onDestroy方法。 最好使用 BroadcastReceiver 在它被杀死时启动你的服务。

以下是说明其实施的示例代码: -

@Override
public void onDestroy() {
Intent in = new Intent();
in.setAction("StartkilledService");
sendBroadcast(in);
Log.d("debug", "Service Killed");
}

然后在AndroidManifest.xml注册接收器: -

<receiver android:name=".app.ServiceDestroyReceiver" >
    <intent-filter>
        <action android:name="StartKilledService" >
        </action>
    </intent-filter>
</receiver>

最后,创建 BroadcastReceiver ,然后使用onReceive方法启动您的服务: -

@Override
public void onReceive(Context context, Intent intent) {
Log.d("debug", "ServeiceDestroy onReceive...");
Log.d("debug", "action:" + intent.getAction());
Log.d("debug", "Starting Service");
ServiceManager.startService();
}

希望这有帮助。

答案 3 :(得分:4)

根据Android文档

Starting from Android 3.1, the system's package manager keeps track of applications 
that are in a stopped state and provides a means of controlling their launch from 
background processes and other applications.

Note that an application's stopped state is not the same as an Activity's stopped
state. The system manages those two stopped states separately.
FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the
list of potential targets to resolve against.

FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the
list of potential targets.

When neither or both of these flags is defined in an intent, the default behavior is to
include filters of stopped applications in the list of potential targets. 

Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents.
It does this to prevent broadcasts from background services from inadvertently or
unnecessarily launching components of stopped applications. A background service 
or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES
flag to broadcast intents that should be allowed to activate stopped applications.

在强制停止应用时,Android只会终止进程ID。没有警告,回调服务/活动。根据Android文档,当应用程序被杀死时,它有可能调用onPause()。

当我在我的应用程序中尝试时,即使onPause()也未被调用。我认为唯一的方法是使用FLAG_INCLUDE_STOPPED_PACKAGES意图标记并从另一个应用程序发送它

答案 4 :(得分:3)

在服务的startCommand方法上返回START_STICKY。通常它告诉操作系统在被杀死时启动服务。

答案 5 :(得分:2)

如果我理解正确,那么实际上这是不可能的,强制关闭应用程序的Android功能旨在允许用户摆脱不需要的应用程序,因此它不允许任何活动,直到用户再次启动其任何活动。 / p>

Restart the service even if app is force-stopped and Keep running service in background even after closing the app How?

答案 6 :(得分:2)

如果情况允许使用'root',通常可以实现Humpty-Dumpty范例。

您的应用程序(第一个)安装另一个应用程序(第二个,从资产中获取APK)并运行第二个应用程序的服务。 第二个应用程序的服务绑定到第一个应用程序服务并在断开连接时重新绑定。第一个应用程序也是这样。

当一些免费内存或类似的应用程序杀死所有应用程序时,当Android杀死其中任何一个时,它将无法帮助,另一个将重新启动它的对应物。

答案 7 :(得分:1)

保持服务生存的唯一真正解决方案是使用提供的通知调用Service.startForeground(...)。这将是唯一有效的解决方案,每隔一个解决方案将非常依赖于Google将如何改变其系统的行为。每次API更新,Google都可以阻止其他所有黑客攻击。

这也让用户意识到,您的应用正在执行一些后台任务,这将使应用程序保持活动状态,并且用户必须停止此操作。但是,如果您向用户提供了停止它的功能,那么它就是您应用程序的一部分。

See the Documentation:

void startForeground (int id, Notification notification)
  

使此服务在前台运行,提供在此状态下向用户显示的持续通知。默认情况下,服务是后台服务,这意味着如果系统需要杀死它们以回收更多内存(例如在Web浏览器中显示大页面),它们可以被杀死而不会造成太大的伤害。如果终止您的服务会对用户造成干扰,您可以设置此标记,例如,如果您的服务正在播放背景音乐,那么用户会注意到他们的音乐是否停止播放。

答案 8 :(得分:0)

即使你强制停止服务,也有一个非常hacky的解决方案来保持服务运行。我不建议这样做,因为它违背了用户的意愿。您可以定义广播接收器以通过操作X. onStartCommand处理器接收意图,广播X(如果服务尚未启动)。在接收到X的广播接收器上,首先启动服务,然后,睡眠几分钟,最后重新播放X.

答案 9 :(得分:-1)

我认为这里唯一的万无一失的解决方案是在单独的进程中有两个服务(清单中的android:process="somecustomprocessname",在服务条目中),它们都监听广播并相互重新启动,因为目前UI不允许用户在一个操作中杀死多个进程。然后,您可以在每个服务中设置一个pinger线程,检查其他服务是否每100毫秒左右运行一次,如果没有,则尝试重新启动它。但这开始变得越来越像恶意软件......