Создание фоновой службы Android, которая постоянно опрашивает REST API для получения данных.

Мне нужно написать службу Android, которая опрашивает сервер на наличие данных, анализирует данные, а затем отправляет их в приложение через намерения. Опрос должен происходить часто (каждые несколько секунд). Из того, что я читал, подобные опросы не рекомендуются (из-за проблем с временем автономной работы). Я впервые разрабатываю для Android, и после долгих исследований осталось несколько вещей, которые мне не ясны.

Я не уверен, что служба, адаптер синхронизации или менеджер аварийных сигналов лучше подходят для моих нужд. Что из этого имеет смысл в контексте этой проблемы?

Эта служба должна запускаться при загрузке и продолжать работать в фоновом режиме. После опроса сервера данные отправляются в другое приложение через намерения. Сервис не должен иметь никакого взаимодействия с пользователем. Из того, что я читал, кажется, что Android пытается помешать людям писать подобные вещи из-за проблем с вредоносными программами. Возможно ли это осуществить?


person twcus    schedule 26.08.2016    source источник
comment
Есть ли способ использовать push-уведомление или сохранить соединение с сокетом? Десять секунд — это так мало, что адаптер Wi-Fi/сотовой сети будет активен и разрядит аккумулятор.   -  person Viktor Yakunin    schedule 26.08.2016


Ответы (2)


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

  public class SyncService extends Service {

   private Handler mHandler;
   // default interval for syncing data
    public static final long DEFAULT_SYNC_INTERVAL = 30 * 1000;

        // task to be run here
        private Runnable runnableService = new Runnable() {
            @Override
            public void run() {
                syncData();
                // Repeat this runnable code block again every ... min
                mHandler.postDelayed(runnableService, Constant.DEFAULT_SYNC_INTERVAL);
            }
        };

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // Create the Handler object
            mHandler = new Handler();
            // Execute a runnable task as soon as possible
            mHandler.post(runnableService);

            return START_STICKY;
        }

        private synchronized void syncData() {
            // call your rest service here
        }
    }

Внутри метода syncData() поместите вызов REST API, который будет вызываться через 30-секундный интервал.

Что касается запуска службы при загрузке, используйте широковещательный приемник, который запускает службу после завершения загрузки, например,

<receiver android:name=".BootCompletedIntentReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

Остальное дело за вами! Пожалуйста, сначала попробуйте сами и обратитесь за помощью!

person Prokash Sarkar    schedule 26.08.2016
comment
Нужно ли классу SyncServer переопределять метод onBind(Intent)? - person colelemonz; 18.05.2017
comment
@colelemonz я считаю, что это необходимо, когда вы расширяете service. - person Brady Sheehan; 03.04.2018

Вам нужно использовать BroadcastReceiver для обнаружения события загрузки с помощью BOOT_COMPLETEDfilter. Затем вам нужно будет запустить IntentService для запроса вашего сервиса.

Шаг 1. Добавьте разрешение в свой манифест.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Шаг 2: Зарегистрируйте свой сервис

<receiver android:name="com.myapp.BootReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
  </intent-filter>
</receiver>

Шаг 3. Создайте свой BootReceiver

public class BootReceiver extends BroadcastReceiver {

@Override 
public void onReceive(Context context, Intent intent) {
    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
        // Start your intent service
        ... 
     } 
  }
} 

Шаг 4: Начните и создайте свой IntentService

...    
Intent i = new Intent(context, BackgroundService.class);
context.startService(i);
...

Шаг 5: Как только это заработает, используйте AlarmManager, чтобы запланировать запуск IntentService каждые x времени.

Дайте мне знать, если у вас есть еще вопросы!

person Amilcar Andrade    schedule 26.08.2016