Перезапустите службу, даже если приложение отключено и продолжает работать в фоновом режиме даже после закрытия приложения How?

Я пытаюсь запустить службу в фоновом режиме. То, что делает мое приложение, - это когда пользователь проверяет флажок, а затем запускается сервис, и когда он отключен, служба остановлена. Что работает отлично. Но проблема в том, что когда я закрыл приложение из диспетчера задач, он также останавливает службу. Я хочу, чтобы служба работала даже после того, как она находится рядом с диспетчером задач. Тогда единственный способ остановить эту услугу - сам пользователь, сняв флажок.

Как я могу это достичь?

Вот мой код

Моя основная деятельность

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));
            }
        }

    });
}
}

Мой класс обслуживания

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();
}
}

Обновление

Как мы можем сделать эту службу так, чтобы она выполнялась как сервис gtalk?

Ответ 1

Я не уверен, какой "Диспетчер задач" вы называете разными, будет действовать по-другому, поэтому я основываю свой ответ на действии, когда пользователь переходит в "Настройки" → "Управление приложениями" и → "Сила" останавливает приложение, которое дал ему андроид.

Предполагая, что ваша служба запущена как часть процесса, и если пользователь принудительно останавливает ваш процесс, вам не разрешается когда-либо запускать службу, пока пользователь вручную не запустит вас. Это особенно актуально для версии 3.0 и выше (проверьте для себя). Это также кажется логичным, если вы думаете, что есть приложение, которое постоянно запускает сервис и каким-то образом раздражает пользователя. Поэтому, когда пользователь заказывает хит (:) force-stops) в приложении, он не должен перезапускать службу, чтобы продолжить прослушивание пользователя.

Например, представьте, что произойдет, если вы сможете создайте приложения, которые просто ели в процессорное время, удерживая блокировку слежения, и вы не можете их убить. Это было бы ужасно и огромной катастрофой безопасности.

Итак, вы не сможете перезапускать службу любыми способами, пока пользователь не запустит одно из ваших действий.

Также вы не можете отключить кнопку AFAIK с принудительной остановкой. Вы должны придерживаться точки зрения, что ничто на устройстве не является вашим, кроме вашего приложения, и (в ограниченной степени) ресурсами, которым вам предоставлен доступ.

По правде говоря, даже приложение gtalk согнется по вашему желанию, если вы захотите принудительно остановить. Он начнется только при использовании Gtalk или других приложений, которые используют службу gtalk, такую ​​как PUSH Gmail (для телефонов, где gtalk не является частью прошивки). Также взгляните на Android C2DM здесь:

fooobar.com/questions/24247/...

Ответ 2

Но проблема в том, что когда я закрыл приложение из диспетчера задач, он также останавливает службу.

Правильно.

Я хочу, чтобы служба работала даже после того, как она находится рядом с диспетчером задач. Тогда единственный способ остановить эту услугу - сам пользователь, сняв флажок.

Вы можете реализовать свою службу на C/С++, встроить ее в какую-то специальную прошивку и убедить людей установить эту прошивку на своих устройствах.

Когда мы устанавливаем gtalk и как только мы входим в систему, он не появляется на вкладке активных приложений в диспетчере задач. Но он работает в фоновом режиме.

Это часть прошивки.

Ответ 4

Вы не можете предотвратить убийство вашего сервиса при любых обстоятельствах. Однако вы можете попросить систему перезагрузить его. Есть два случая: (1) процесс умирает по какой-то ненормальной причине (2) перезагрузка телефона. В первом случае START_STICKY или START_REDELIVER_INTENT используются для перезапуска службы. В последнем случае вам нужно добавить BroadcastReceiver для android.intent.action.BOOT_COMPLETED.

Ваш код возвращает START_STICKY из onStartCommand, поэтому вы выбрали один из путей перезапуска службы: "если этот сервисный процесс убит во время его запуска (после возвращения из onStartCommand (Intent, int, int)), он в запущенном состоянии, но не сохраняет это достигнутое намерение. Позже система попытается воссоздать сервис..."

"Этот режим имеет смысл для вещей, которые будут явно запущены и остановлены для запуска в течение произвольных периодов времени, таких как служба, выполняющая воспроизведение фоновой музыки."

Вы также можете использовать START_REDELIVER_INTENT.

Обратите внимание, что если ваша служба выполняет значительную работу, ее нужно запустить в фоновом потоке.

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

Ответ 5

Я не совсем уверен, что вы можете запретить закрывать приложение TaskManager. Если вы думаете об этом, это имеет смысл для этого. Представьте, что у вас есть приложение, которое не отвечает на ввод пользователя, а также не отвечает на то, что его убил диспетчер задач. Нехорошо. Однако я нашел этот вопрос, который аналогичен вашему. Кроме того, вы можете автоматически перезапустить систему, как описано здесь (немного прокрутите страницу вниз до "начала службы"

Ответ 6

Пусть ваш Service запускается в отдельном процессе. В в этом блоге есть хороший учебник.

Вы можете указать атрибут android:process в теге <Service>, чтобы приложение запускалось в рамках собственного процесса.

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

Ответ 7

используйте мой метод, если вы хотите запустить скрытое приложение только в первый раз Я делаю прозрачную деятельность Launcher, как это

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

Итак, я делаю приложение скрытым в Launcher, поместив этот код в 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);

Таким образом, я использую этот код для значка 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);

Теперь я могу запускать приложение в первый раз руками пользователя, и после этого я использую мой приемник для обеда в любое время.

Ответ 8

Вы можете попробовать перезапустить службу на событии onDestroy. Используйте несколько флагов, чтобы узнать, закрыт ли пользователь пользователем или его сила закрыта.

Обратите внимание, что нет гарантии, что onDestroy будет вызываться каждый раз.