简体   繁体   English

即使应用程序被强制停止,也要重新启动服务;关闭应用程序后,仍要在后台运行服务。

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

I am trying to run a service in the background. 我正在尝试在后台运行服务。 What my app does is when user checks checkbox then service starts and when it is unchecked service is stopped. 我的应用程序要做的是,当用户选中复选框,然后服务启动,而未选中时,服务停止。 Which is working perfectly fine. 哪个工作正常。 But the problem is when I closed the app from task manager it then also stops the service. 但是问题是,当我从任务管理器中关闭应用程序时,它也停止了服务。 What I want is to keep the service running even after it is close from task manager. 我想要的是即使从任务管理器关闭后也要保持服务运行。 Then only way to stop that service is by user himself by unckecking the box. 然后,停止该服务的唯一方法是由用户自己打开框。

How can I achieve this? 我该如何实现?

Here is my code 这是我的代码

My main activity 我的主要活动

public class SampleServiceActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final CheckBox cb = (CheckBox) findViewById(R.id.checkBox1);

    cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {

            if(isChecked) {
                Toast.makeText(getBaseContext(), "Checked", Toast.LENGTH_LONG).show();
                startService(new Intent(getBaseContext(), MyService.class));
            } else {
                Toast.makeText(getBaseContext(), "Unchecked", Toast.LENGTH_LONG).show();
                stopService(new Intent(getBaseContext(), MyService.class));
            }
        }

    });
}
}

My service class 我的服务等级

public class MyService extends Service {
Notify n = new Notify();
@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    n.initNotification(getBaseContext(), true);
    return START_STICKY;
}

//method to stop service
public void onDestroy() {
    super.onDestroy();
    n.cancelNotification(getBaseContext());
    Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
}

Update 更新资料

How can we make this service so that it runs like gtalk service? 我们如何使该服务像gtalk服务一样运行?

I am not sure which 'Task Manager' you are referring to as different ones would act differently, so I am basing my answer on the action when the user goes to Settings-->manage Applications and--> force stops the app the way android has given him. 我不确定您指的是哪个“任务管理器”会以不同的方式执行操作,所以我将答案基于用户进入“设置”->“管理应用程序”并->强制停止应用程序时的操作android给了他。

Assuming that your service is running as part of the process and if the user force-stops your process, you are prevented from ever running the service again until the user manually launches you.This is especially valid from 3.0 and above version ( check for yours). 假设您的服务正在运行的进程的一部分,如果用户强制停止的过程中,你是从以后再运行该服务,直到用户手动启动you.This防止尤其是从3.0版本以上有效(检查你的)。 It also seems logical when you think that there is an app which keeps a service started all the time and is annoying the user in some way. 当您认为有一个应用程序始终保持服务启动并以某种方式使用户烦恼时,这似乎也合乎逻辑。 So when the user orders a hit ( :) force-stops) on the app, it should not restart the service to continue bugging the user. 因此,当用户在应用上命令命中(:)强制停止)时,它不应重新启动服务以继续困扰用户。

For instance, Imagine what would happen if you could create apps which just ate at your processor time by holding a wake lock, and you couldn't kill them. 例如,想象一下,如果您创建一个仅通过持有唤醒锁就可以在处理器时间使用的应用程序,而又无法杀死它们,将会发生什么情况。 This would be horrible and a huge security disaster. 这将是可怕的,并且将是巨大的安全灾难。

So, you will not be able to restart your service by any means until the user launches one of your activities. 因此,在用户启动您的活动之一之前,您将无法以任何方式重新启动服务。

Also you cannot disable the force-stop button AFAIK. 同样,您不能禁用强制停止按钮AFAIK。 You should take the viewpoint that nothing on the device is yours to control besides your app and (to a limited extent) the resources to which you're granted access. 您应该认为,除了您的应用程序和(在一定程度上)授予您访问权限的资源之外,设备上什么都没有您可以控制。

Finnally, even the gtalk app will bend to your will if you desire to force stop. 最后,如果您想强制停止,即使gtalk应用程序也会屈服于您的意愿。 It will start only when you use Gtalk or other apps which use the gtalk service such as PUSH Gmail ( for phones where gtalk isnt a part of firmware). 仅当您使用Gtalk或使用gtalk服务的其他应用程序(例如PUSH Gmail)(对于gtalk不属于固件的手机)时,它才会启动。 Also take a look at Android C2DM here: 还可以在这里查看Android C2DM

https://stackoverflow.com/a/11238779/1218762 https://stackoverflow.com/a/11238779/1218762

But the problem is when I closed the app from task manager it then also stops the service. 但是问题是,当我从任务管理器中关闭应用程序时,它也停止了服务。

Correct. 正确。

What I want is to keep the service running even after it is close from task manager. 我想要的是即使从任务管理器关闭后也要保持服务运行。 Then only way to stop that service is by user himself by unckecking the box. 然后,停止该服务的唯一方法是由用户自己打开框。

You can implement your service in C/C++, build it into some custom firmware, and convince people to install that firmware on their devices. 您可以使用C / C ++实现服务,将其构建到某些自定义固件中,然后说服人们在其设备上安装该固件。

When we install gtalk and once we sign in then it does not appear in active applications tab in task manager. 安装gtalk并登录后,它不会出现在任务管理器的“活动应用程序”选项卡中。 But it runs in the background. 但是它在后台运行。

It is part of the firmware. 它是固件的一部分。

I think this link will help you. 我认为此链接将为您提供帮助。
Disable force stop button in manage application 在管理应用程序中禁用强制停止按钮

Its disable the Force Stop button in Package Installer setting so, no one can stop your application. 它禁用了Package Installer设置中的“强制停止”按钮,因此没有人可以停止您的应用程序。

You cannot prevent your service from being killed under all circumstances. 您不能在任何情况下都防止您的服务被终止。 However, you can ask the system to restart it. 但是,您可以要求系统重新启动它。 There are two cases: (1) the process dies for some abnormal reason (2) the phone reboots. 有两种情况:(1)该进程由于某种异常原因而终止(2)手机重新启动。 In the former, START_STICKY or START_REDELIVER_INTENT are used to restart the service. 在前者中,START_STICKY或START_REDELIVER_INTENT用于重新启动服务。 In the latter, you'll need to add a BroadcastReceiver for android.intent.action.BOOT_COMPLETED. 在后者中,您需要为android.intent.action.BOOT_COMPLETED添加一个BroadcastReceiver。

Your code is returning START_STICKY from onStartCommand, so you've chosen one of the service restart paths: "if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service..." 您的代码正在从onStartCommand返回START_STICKY,因此您选择了服务重新启动路径之一:“如果此服务的进程在启动时被杀死(从onStartCommand(Intent,int,int)返回之后),则将其保留在处于开始状态,但不保留此交付意图。稍后,系统将尝试重新创建服务...”

"This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a service performing background music playback." “这种模式对于可以明确启动和停止运行任意时间的事情是有意义的,例如执行背景音乐播放的服务。”

You can also use START_REDELIVER_INTENT. 您也可以使用START_REDELIVER_INTENT。

Note that if your service is doing any significant work, it needs to run in a background thread. 请注意,如果您的服务正在做任何重要的工作,它需要在后台线程中运行。

http://developer.android.com/reference/android/app/Service.html#START_STICKY http://developer.android.com/reference/android/app/Service.html#START_STICKY

I'm not entirely sure you can prevent your app from being closed by the TaskManager. 我不确定您是否可以阻止TaskManager关闭您的应用。 If you think about it, it makes sense for it to be that way. 如果您考虑一下,那么这样做是有意义的。 Imagine that you have an app that fails to respond to user input and also fails to respond to being killed by the Task Manager. 想象一下,您有一个应用程序既无法响应用户输入,又无法响应被任务管理器杀死。 Not good. 不好。 However I found this question which is in a similar vein to yours. 但是我发现这个问题与您的问题相似。 Also you can have the system automatically re-start your Service as described here (scroll down on that page a little to just before 'starting a service' 另外,您还可以让系统按照此处所述自动重新启动服务(在“启动服务”之前向下滚动至该页面略微

use my method if you want to start a hidden app for just first time I make a transparent Launcher activity like this 如果您想首次启动隐藏的应用程序,请使用我的方法,例如,我进行透明的启动器活动

<activity android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.Transparent"
    android:excludeFromRecents="true"
    >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

So I make the app hidden in launcher by placing this code in oncreat() [Code] 因此,我将代码放置在oncreat()中,将应用隐藏在启动器中[代码]

PackageManager p = getPackageManager();
    ComponentName componentName = new ComponentName(this, MainActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

So I use this code for show app icon on launcher and make it run able on service class that use broadcast receiver boot and in network connection broadcast receiver class too(autostart.java and networkConnectinCheck.java): 因此,我将此代码用于启动器上的show app图标,并使其能够在使用广播接收器启动的服务类和网络连接的广播接收器类(autostart.java和networkConnectinCheck.java)中运行:

PackageManager p = context.getPackageManager();
    ComponentName componentName = new ComponentName(context, MainActivity.class);
    p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

Now I can run app for first time by user hands and after this I use my receiver's to lunch app any time. 现在,我可以用用户的手第一次运行该应用程序,此后,我可以随时使用接收方的午餐应用程序。

Let your Service run in a separate process. 让您的Service在单独的过程中运行。 There is a good tutorial in this blog . 该博客中有一个很好的教程。

You can specify the android:process attribute in <Service> tag to make your app run within its own process. 您可以在<Service>标记中指定android:process属性,以使您的应用在其自己的进程中运行。

<service
android:name="MyServiceName"
android:process="my_process" 
android:icon="@drawable/icon"
android:label="@string/service_name"
>
</service>

You can try to restart service on onDestroy event of service. 您可以尝试在服务的onDestroy事件上重新启动服务。 Use some flags to find if service is closed by the User or its force closed. 使用一些标志来查找服务是由用户关闭还是由用户强制关闭。

Note that there is not guarantee that onDestroy will be called everytime. 注意,不能保证每次都会调用onDestroy。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM