简体   繁体   中英

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?

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.

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). 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. 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. 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). Also take a look at Android C2DM here:

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.

When we install gtalk and once we sign in then it does not appear in active applications tab in task manager. 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.

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. In the former, START_STICKY or START_REDELIVER_INTENT are used to restart the service. In the latter, you'll need to add a BroadcastReceiver for android.intent.action.BOOT_COMPLETED.

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

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

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

I'm not entirely sure you can prevent your app from being closed by the 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]

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):

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. 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: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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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