Создание фонового сервиса в Android - PullRequest
12 голосов
/ 07 февраля 2012

В моем проекте мне нужно создать сервис в Android.Я могу зарегистрировать сервис следующим образом:

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >

   <service   android:enabled="true"
    android:name=".ServiceTemplate"/>
      <activity
        android:name=".SampleServiceActivity"
        android:label="@string/app_name" >
        <intent-filter>
         <action android:name="android.intent.action.MAIN" />
         <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
     </activity>
</application>

Я вызываю этот сервис внутри действия, как показано ниже: -

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Intent service = new Intent(getApplicationContext(), ServiceTemplate.class);
    this.startService(service);
}

Но если я убью текущее действие, сервистакже разрушен.Мне нужен этот сервис всегда работает в фоновом режиме.Что я должен сделать?Как мне зарегистрировать сервис?Как мне запустить сервис?

Ответы [ 6 ]

10 голосов
/ 07 марта 2015

Вот полу-другой способ сохранить сервис навсегда.Есть способы убить его в коде, если вы хотите

Фоновая служба:

package com.ex.ample;

import android.app.Service;
import android.content.*;
import android.os.*;
import android.widget.Toast;

public class BackgroundService extends Service {

    public Context context = this;
    public Handler handler = null;
    public static Runnable runnable = null;

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

    @Override
    public void onCreate() {
        Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();

        handler = new Handler();
        runnable = new Runnable() {
            public void run() {
                Toast.makeText(context, "Service is still running", Toast.LENGTH_LONG).show();
                handler.postDelayed(runnable, 10000);
            }
        };

        handler.postDelayed(runnable, 15000);
    }

    @Override
    public void onDestroy() {
        /* IF YOU WANT THIS SERVICE KILLED WITH THE APP THEN UNCOMMENT THE FOLLOWING LINE */
        //handler.removeCallbacks(runnable);
        Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onStart(Intent intent, int startid) {
        Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
    }
}

Вот как вы начинаете это с вашей основной деятельности или с того места, где вы хотите:

startService(new Intent(this, BackgroundService.class));

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

Я надеюсь, что это кому-то поможет.

Причина, по которой некоторые люди делают это, связана с корпоративными приложениями, где в некоторых случаях пользователи / сотрудники должныне сможет остановить определенные вещи:)

http://i.imgur.com/1vCnYJW.png

5 голосов
/ 03 октября 2017

вы можете создать фоновую службу и вызывать ее с помощью AlarmManager

1 - вам нужно создать класс BroadcastReceiver для вызова с помощью AlarmManager

public class AlarmReceiver extends BroadcastReceiver

{
    /**

     * Triggered by the Alarm periodically (starts the service to run task)

     * @param context

     * @param intent

     */

    @Override

    public void onReceive(Context context, Intent intent)

    {

        Intent i = new Intent(context, AlmasService.class);

        i.putExtra("foo", "AlarmReceiver");

        context.startService(i);

    }

}

2 - необходимо создать класс IntentService для вызова с помощью AlarmReceiver

public class AlmasService extends IntentService

{

    public Context context=null;

    // Must create a default constructor
    public AlmasService() {

        // Used to name the worker thread, important only for debugging.
        super("test-service");

    }

    @Override

    public void onCreate() {

        super.onCreate(); // if you override onCreate(), make sure to call super().

    }


    @Override
    protected void onHandleIntent(Intent intent) {

        context=this;
        try

        {

            Thread.sleep(5000);

        }

        catch (InterruptedException e)

        {

            e.printStackTrace();

        }



        String val = intent.getStringExtra("foo");

        // Do the task here
        Log.i("MyTestService", val);

    }

}

3 - необходимо добавить AlarmReceiver в качестве получателя и AlmasService в качестве службы для манифеста

    <service
        android:name=".ServicesManagers.AlmasService"
        android:exported="false"/>

    <receiver
        android:name=".ServicesManagers.AlmasAlarmReceiver"
        android:process=":remote" >
    </receiver>

4 - теперь вы можете запустить сервис и вызвать AlarmManager на MainActivity

public class MainActivity extends AppCompatActivity
{
    public static final int REQUEST_CODE = (int) new Date().getTime();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        scheduleAlarm();
    }

    public void scheduleAlarm()
    {
        // Construct an intent that will execute the AlarmReceiver
        Intent intent = new Intent(getApplicationContext(), AlmasAlarmReceiver.class);
        // Create a PendingIntent to be triggered when the alarm goes off
        final PendingIntent pIntent = PendingIntent.getBroadcast(
                this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        // Setup periodic alarm every every half hour from this point onwards
        long firstMillis = System.currentTimeMillis(); // alarm is set right away
        AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        // First parameter is the type: ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC_WAKEUP
        // Interval can be INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_DAY
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis, (long) (1000 * 60), pIntent);



    }
}
5 голосов
/ 07 февраля 2012

Но если я убил текущую активность, служба также убивает.Мне нужен этот сервис всегда работает в фоновом режиме.Что мне нужно сделать?

Если под «убить текущую активность» вы подразумеваете, что используете убийцу задач или принудительную остановку из приложения «Настройки», ваша служба будет остановлена.С этим ничего не поделаешь.Пользователь указал, что не хочет, чтобы ваше приложение больше запускалось;Пожалуйста, уважайте пожелания пользователя.

Если под «убить текущую активность» вы подразумеваете, что нажали BACK или HOME или что-то еще, то служба должна продолжать работать, по крайней мере, некоторое время, если вы не позвоните stopService(),Он не будет работать вечно - Android в конце концов избавится от сервиса, потому что слишком много разработчиков пишут сервисы, которые пытаются «всегда работать в фоновом режиме».А также.конечно, пользователь может убить службу, когда захочет.

Служба должна быть «запущена» только тогда, когда она активно доставляет значение пользователю .Обычно это означает, что служба не должна быть «всегда запущена в фоновом режиме».Вместо этого используйте AlarmManager и IntentService для периодической работы.

4 голосов
/ 07 ноября 2012

Попробуйте запустить службу в отдельном потоке, чтобы, когда вы уничтожите свою деятельность, служба не пострадала. Он будет работать без перерыва. Кроме того, в сервисе верните Service.START_STICKY из onStartCommand(intent, flags, startId), чтобы убедиться, что сервис создается заново, если он был уничтожен системой (ОС Android).

1 голос
/ 07 февраля 2012

переопределить этот метод:

public int onStartCommand(Intent intent, int flags, int startId) {
    return Service.START_STICKY;
}
0 голосов
/ 04 июля 2019

чтобы завершить то, что сказал @abhinav: если вы используете onBind (), вам не нужно использовать onStartCommand () и наоборот:

фактически, если компонент вызывает bindService () для создания службы, и onStartCommand() не вызывается, служба работает только до тех пор, пока компонент привязан к ней.После того, как служба не связана со всеми своими клиентами, система уничтожает ее.Для иллюстрации: метод onStartCommand () вызывается, когда ваша служба начинает выполнять свою работу.Функция onCreate () завершена, и она готова приступить к выполнению того, что необходимо сделать.и если вы используете метод onBind (), вы привязываете Сервис к сроку службы, например, Деятельности.Если действие завершается, то служба может быть освобождена и может сама завершить работу.Служба будет действовать до тех пор, пока к ней еще что-то привязано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...