Продолжаем рассматривать тему Сервисов (служб). В двух предыдущих статьях я рассказал, как создать простейший сервис и как добавить возможность автозапуска приложения после рестарта системы. В этой статье я покажу, как добавить возможность автозапуска для Службы. Т.е. мы совместим две статьи, но с некоторыми специфичными нюансами.
План:
- JAVA класс (BroadcastReceiver), который будет запускать сервис
- Сервис (служба)
- Приложение
- Файл 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-классом.
Теперь переходим к следующему, последнему пункту.
Пункт 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