Важно (9.07.22)

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

воскресенье, 31 января 2016 г.

[Android Service+BroadcastReceiver] Автозапуск службы после рестарта ОС

Продолжаем рассматривать тему Сервисов (служб). В двух предыдущих статьях я рассказал, как создать простейший сервис и как добавить возможность автозапуска приложения после рестарта системы. В этой статье я покажу, как добавить возможность автозапуска для Службы. Т.е. мы совместим две статьи, но с некоторыми специфичными нюансами.

План:
  1. JAVA класс (BroadcastReceiver), который будет запускать сервис
  2. Сервис (служба)
  3. Приложение
  4. Файл classes.dex из приложения, склеенный с нашим java-классом.

Пункт 1. JAVA класс (BroadcastReceiver).

Если вы читали статью «[BroadcastReceiver] Автозапуск приложения после перезагрузки ОС», то примерно представляете, как будет выглядеть класс. Единственное, что у нас изменится, так это код класса.

Для запуска Активити необходимо использовать метод «context.startActivity», а для запуска сервиса, метод «context.startService».

Итак, создаём структуру папок:

  • Папка «App» - будет хранить Приложение, а также папку «java», в которой, позже появится наш класс и файл «classes.dex».
  • Папка «App\java\src\com\TestReceiver» - будет хранить файл «BootCompletedReceiver.java» с нашим java классом
  • Папка «Service» - будет хранить Сервис (службу).

Теперь создаём файл «BootCompletedReceiver.java» и пишем код для автозапуска Сервиса:
package com.TestReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class BootCompletedReceiver extends BroadcastReceiver {

 public void onReceive(Context context, Intent intent) {

  if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
   Intent TestLauncher = new Intent();
            TestLauncher.setClassName(context, "com.embarcadero.services.AutoStartService");
   context.startService(TestLauncher);
  }

 }
 
}

Имя сервиса в студии всегда будет иметь начало «com.embarcadero.services.», а далее будет написано название вашего Сервиса.

Сохраняем файл и приступаем к следующему пункту.

Пункт 2. Сервис (служба).

О том, как создавать Сервис, я уже рассказал в статье «[Android Service] Создание простейшего Сервиса (службы)», в достаточно подробной (на мой взгляд) форме.

Создаём Сервис с именем «AutoStartService», пишем код, сохраняем его в папке «Service» и собираем через команду «Build».

Переходим к следующему шагу.

Пункт 3. Приложение.

Добавляем группу проекта новый проект «Delphi Projects > Multi-Device Application» с именем «ServiceApp» и сохраняем в папку «App».

Теперь добавляем Сервис в приложение. Опять же, как это сделать, я писал в статье «[Android Service] Создание простейшего Сервиса (службы)».

После добавления собираем приложение через команду «Build»:
  • В папке «App» появится файл «AndroidManifest.template.xml»
  • В папке «App\Android\Debug\» появится файл «classes.dex»
Давайте сразу внесём изменения в «AndroidManifest.template.xml».

Находим строчку «<%receivers%>» и после неё пишем (подробности в статье «[BroadcastReceiver] Автозапуск приложения после перезагрузки ОС»):
        <receiver android:name="com.TestReceiver.BootCompletedReceiver"

                  android:permission="android.permission.RECEIVE_BOOT_COMPLETED"

                  android:enabled="true">

            <intent-filter>

                <action android:name="android.intent.action.BOOT_COMPLETED" />

                <category android:name="android.intent.category.DEFAULT" />

            </intent-filter>

        </receiver>


В «Uses Prmissions» выдаём разрешение «Receive boot complited».

Теперь переходим к следующему, последнему пункту.

Пункт 4. Файл classes.dex из приложения, склеенный с нашим java-классом.

Нам необходимо склеить наш java класс с файлом «classes.dex», который лежит в папке «App\Android\Debug\». Для этого можно воспользоваться моим bat файлом из статьи «[BroadcastReceiver] Автозапуск приложения после перезагрузки ОС». Меняем в файле только путь до файла classes.dex, указанный в константе «EMBO_DEX».

В моём случае, строка будет такой «set EMBO_DEX="C:\Users\Пользователь\Desktop\ProjectAutoStartService\App\Android\Debug\classes.dex"».



Запускаем bat файл, в папке «App\java\output\dex\» появится необходимый нам файл «classes.dex». 

Заходим в Deployment приложения, снимаем галочку со стандартного файла и добавляем наш новый файл. Не забываем указать конечный путь (Remote Path) «classes\».


Сохраняем всё это дело и компилируем на устройстве.

Update 23.02.17. Действительно для XE7 и выше. BAT - файл для JAVA 1.7 - 1.8
Для тех, кто уже понимает или наоборот не хочет понимать, для чего нужен classes.dex.
Вы можете создать JAR файл с вашим JAVA классом и добавить его через Project Manager (Как добавить jar библиотеку в проект, в данном случае, обёртку делать не нужно).
Для создания JAR файла, вам необходимо использовать bat файл с таким содержимым:
@echo off
setlocal

if x%ANDROID% == x set ANDROID=C:\Android\sdk
set ANDROID_PLATFORM=%ANDROID%\platforms\android-24
set PROJ_DIR=%CD%
set VERBOSE=0

echo.
echo Compiling the Java service activity source files
echo.
mkdir output 2> nul
mkdir output\classes 2> nul
if x%VERBOSE% == x1 SET VERBOSE_FLAG=-verbose
javac -source 1.7 -target 1.7 %VERBOSE_FLAG% -Xlint:deprecation -cp %ANDROID_PLATFORM%\android.jar -d output\classes src\com\TestReceiver\BootCompletedReceiver.java

echo.
echo Creating jar containing the new classes
echo.
mkdir output\jar 2> nul
if x%VERBOSE% == x1 SET VERBOSE_FLAG=v
jar c%VERBOSE_FLAG%f output\jar\test_classes.jar -C output\classes com

echo.
echo Now we have the end result, which is output\jar\test_classes.jar

:Exit

pause

endlocal

После выполнения этого bat файла, у вас появится файл output\jar\test_classes.jar. Его то и добавьте через Project Manager (подробности в статье, указанной чуть выше). Останется только прописать ресейвер в манифесте.


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

На этом всё.


Видео


Исходники: Скачать с Google Drive