Модераторы Andrey Efimov Опубликовано 15 февраля, 2016 Модераторы Поделиться Опубликовано 15 февраля, 2016 Ссылка: http://delphifmandroid.blogspot.ru/2016/02/alarmmanager-rad-studio.html Автор: Ефимов Андрей Описание: [AlarmManager] Автозапуск приложения в назначенное время AngryOwl, Rusland, Dev и 3 других 6 Цитата Ссылка на комментарий
ENERGY Опубликовано 22 февраля, 2017 Поделиться Опубликовано 22 февраля, 2017 (изменено) Привет. Я тут узнал что оказывается начиная с XE7 не нужно создавать Dex файл затем подменять его на classes.dex. Достаточно создать Jar файл и подключить его к проекту. Я проверил на новом проекте - все прекрасно работает. Проект автозапускается из AlarmManager (делал на основе этой статьи ) .А Dex файлы нужны для XE5 и XE6. Узнал я это из этого вопроса на stackoverflow. Пожалуйста Вы не могли бы обновить статью? Просто дописав эту заметку? На мой взгляд это важно. Я также обновил бат файл, он будет примерно такой: @echo off setlocal if x%ANDROID% == x set ANDROID=c:\Users\Alex\Documents\Embarcadero\Studio\18.0\PlatformSDKs\android-sdk-windows 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\AlarmReceiver.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, in directory output\jar\ pause Также еще один ньюанс. Для варианта 2 никакой Dex файл не нужен. Также не нужен и Jar файл. Также ничего не нужно в манифест добавлять, т.к. вызывается activity напрямую, без BroadcastReceiver.Но это только для варианта 2. Для первого варианта (Broadcast) все это нужно.Я проверял на новом проекте с вариантом 2 - все работает. Изменено 23 февраля, 2017 пользователем ENRGY Rusland и Евгений Корепов 2 Цитата Ссылка на комментарий
Модераторы Andrey Efimov Опубликовано 23 февраля, 2017 Автор Модераторы Поделиться Опубликовано 23 февраля, 2017 По поводу "как подключать JAVA класс": процитирую ответ в блоге: Цитата По поводу JAR файла. Для подобных статей, я всегда стараюсь детально описать каждый шаг дальнейших действий. Это направлено на то, чтобы человек, начал понимать, что он делает, а не просто копипастить и потом на форуме кучу тем создавать с вопросами, как и что. Если вам хочется добавлять JAR через Project Manager, то и пожалуйста, http://delphifmandroid.blogspot.ru/2015/03/jar.html По поводу Цитата "Также еще один ньюанс. Для варианта 2 никакой Dex файл не нужен. Также не нужен и Jar файл. Также ничего не нужно в манифест добавлять, т.к. вызывается activity напрямую, без BroadcastReceiver.Но это только для варианта 2. Для первого варианта (Broadcast) все это нужно. " Цитата из ответа в блоге: Цитата Да, всё правильно, для второго варианта dex не нужен. Два примера использованы в одном приложении. Видимо недостаточно понятно описал в статье, различия между getBroadcast и getActivity, а также между двумя тестовыми вариантами. Расчёт был на то, что читатель хотя бы поинтересуется в официальной справке, что делают два этих метода. К слову, по названию методов уже понятно, для чего каждый из них предназначен. Но раз есть один прецедент, то может быть и второй. Поэтому я уже добавил прямое указание различий у двух примеров. p.s. Не нужно заниматься кросспостингом. Update. Все три статьи обновлены. Конкретно в этой статье постарался объяснить в тексте поверхностные отличия двух примеров, которые мне, до сегодняшнего дня казались очевидными. Чуть позже выложу ещё всё на ГитХаб, чтобы не терялось ENERGY, Rusland и Равиль Зарипов (ZuBy) 3 Цитата Ссылка на комментарий
ENERGY Опубликовано 23 февраля, 2017 Поделиться Опубликовано 23 февраля, 2017 (изменено) Большое спасибо что поддерживаете статьи в актуальном состоянии! Я также часто ссылаюсь на ваши статьи на других сайтах - англоязычных. Что удивительно подобная информация редко вcтречается на англоязычных сайтах, к примеру про Alarm Manager и Delphi нет ни одной статьи, даже на сайте Embarcadero этот вопрос долгое время висел без ответа, пока я не дал ссылку на вашу статью. Непопулярность Delphi Mobile как раз и связана с тем, кроме цены, что на многие вопросы почти нет ответов, при этом Java сообщество пестрит готовыми Copy Paste решениями, что увеличивает и без того большую армию пользователей. Но Java нет на iOS. И на Java не сделаешь кроссплатформенный проект с единым кодом и GUI, поэтому Delphi здесь на шаг впереди. Поэтому мне и показалось важным указать на ньюанс с JAR в темах связанными с DEX (заодно кстати и осветили баг с батником, помните javac -source 1.7 -target 1.7? - ведь на этом этапе у человека изучающего Delphi может пропасть желание изучать дальше), столько плясок с бубном с этим dex, и разбросать чтобы больше людей увидели более удобный и простой вариант. Изменено 23 февраля, 2017 пользователем ENRGY Rusland и Евгений Корепов 2 Цитата Ссылка на комментарий
Евгений Корепов Опубликовано 25 февраля, 2017 Поделиться Опубликовано 25 февраля, 2017 Спасибо за статью, все отлично работает. Вот только не допру как запустить не приложение, а сервис. Все темы в разделе Сервис перечитал, но информацию не нашел :-( Делаю по второму примеру: procedure TForm2.Button2Click(Sender: TObject); var Intent: JIntent; PendingIntent: JPendingIntent; begin // Создаём Интент Intent := TJIntent.Create; Intent.setClassName(TAndroidHelper.Context, StringToJString('com.embarcadero.firemonkey.FMXNativeActivity')); // Оборачиваем Интент в PendingIntent PendingIntent := TJPendingIntent.JavaClass.getActivity(TAndroidHelper.Context, 1, Intent, 0); // Устанавливаем оповещение TAndroidHelper.AlarmManager.&set(TJAlarmManager.JavaClass.RTC_WAKEUP, getTimeAfterInSecs(30), PendingIntent); end; Но activity "com.embarcadero.firemonkey.FMXNativeActivity" одинаковые у приложения и сервиса. Запускается именно приложение. Как сделать только запуск сервиса? Цитата Ссылка на комментарий
Модераторы Andrey Efimov Опубликовано 25 февраля, 2017 Автор Модераторы Поделиться Опубликовано 25 февраля, 2017 Евгений, внимательнее читайте статью, там есть раздел теории, а конкретно такие строчки: Цитата Основные методы: getActivity –для запуска Activity getBroadcast – для BroadcastReciver getService – для Service это половина ответа на ваш вопрос. Вторую половину можно найти например в этой статье [Android Service+BroadcastReceiver] Автозапуск службы после рестарта ОС. В ней говорится, какое имя будет у сервиса после создания: Цитата Имя сервиса в студии всегда будет иметь начало «com.embarcadero.services.», а далее будет написано название вашего Сервиса. Равиль Зарипов (ZuBy) и Rusland 2 Цитата Ссылка на комментарий
Евгений Корепов Опубликовано 25 февраля, 2017 Поделиться Опубликовано 25 февраля, 2017 Andrey Efimov, огромное спасибо! Так и думал что глаз замылился и ответ перед глазами! Причем вашу статью раза четыре перечитал :-) Цитата Ссылка на комментарий
ENERGY Опубликовано 7 марта, 2017 Поделиться Опубликовано 7 марта, 2017 (изменено) Блин, проблема. Уже сутки не могу решить. Если телефон подключен к USB - то Alarm запускает активити. Если он на батареях, то он спит себе дальше и ничего не происходит. Ну понятно почему, - на батареях он уходит в sleep режим. Я уже пробовал и WakeLock и флаги FLAG_TURN_SCREEN_ON or FLAG_DISMISS_KEYGUARD or FLAG_SHOW_WHEN_LOCKED.- все в OnCreate (даже до и после Application.Initialize пробовал), пробовал и первый и второй метод со статьи (Activity и BroadcastReceiver) Проблема в том, что когда срабатывает RTC - система просыпается, но просыпается ненадолго. Где то на 2-3 секунды. Т,е. фактически не доходит до кода с WakeLock или кода с флагами (я уже пробовал его и до и после инициализации). Есть один рабочий вариант - ставить WakeLock в java коде с BroadcastReceiver (это кстати рекомендованный способ для запуска сервисов) - это работает, я пробовал, но я пока не знаю как отключить его. Пример Возможно у кого то есть рабочий вариант? Был бы очень благодарен. Странно что никто об этом не говорил.. Изменено 7 марта, 2017 пользователем ENRGY Цитата Ссылка на комментарий
ENERGY Опубликовано 7 марта, 2017 Поделиться Опубликовано 7 марта, 2017 (изменено) Ребят, а можете отозваться у кого работает без Wake Lock? Возможно у автора статьи, ведь Андрей даже никаких намеков не давал. Я просто удивлен что никто с этим не сталкивался. Изменено 7 марта, 2017 пользователем ENRGY Цитата Ссылка на комментарий
ENERGY Опубликовано 7 марта, 2017 Поделиться Опубликовано 7 марта, 2017 (изменено) Фух. Наконец то проспался и понял как сделать. Нужно просто поставить Alarm еще раз, напр. чтобы выполнился через 3 секунды. (неудобный, есть вероятность попасть на ошибку) просто вызвать его в Broadcast после Activity . (не всегда работает) Запустить Activity и в BroadcastReceiver подождать 8 секунд, а затем там же снять WakeLock. Это вариант работает прекрасно. Также с этим кодом Alarm срабатывает если Activity уже запущено либо в фоне. Нужно перехватывать WillBecomeForeground, BecameActive и там включать экран. Процессор включается в WakeLock, но не на долго, вам нужно включить экран при помощи функции ниже, сделать работу затем отключить экран). В моем случае, в отдельном потоке крутиться самописный планировщик, для других задач, который возбуждает события, по нему я и включаю\отключаю экран. Итак выстраданный бесcонными ночами Java код, обратите внимание на TestLauncher.putExtra("StartedFromAM", true), это чтобы знать из Activity что запустились из Broadcast (предложенный Blong'гом EXTRA_ALARM_COUNT с BroadcastReceiver всегда вернет ноль, он работает только если запускать напрямую Activity!) : package com.TestReceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.PowerManager; import android.os.Handler; public class AlarmReceiver extends BroadcastReceiver { private static PowerManager.WakeLock mWakeLock; @Override public void onReceive(Context context, Intent intent) { if (mWakeLock == null) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Delphi"); mWakeLock.acquire(); } Intent TestLauncher = new Intent(); TestLauncher.setClassName(context, "com.embarcadero.firemonkey.FMXNativeActivity"); TestLauncher.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); // I TestLauncher.putExtra("StartedFromAM", true); context.startActivity(TestLauncher); // Handler h = new Handler(); h.postDelayed(new Runnable(){ public void run(){ mWakeLock.release(); mWakeLock = null; } }, 8000); //Toast.makeText(context, "Reelase! ("+mcounter.toString()+")", Toast.LENGTH_SHORT).show(); // For example } } PARTIAL_WAKE_LOCK означает что процессор во время выполнения этого кода, не будет уходить в спящий режим. Теперь в OnCreate нашей формы добавляем флаги чтобы включить экран, но при условии что запустились мы из AlarmManager : function StartedFromAlarmManager: boolean; begin {$IFDEF ANDROID} Result := TAndroidHelper.Activity.getIntent.getBooleanExtra(StringToJString('StartedFromAM'), false); // this will work only if using Activity instead of Broadcast - TJPendingIntent.JavaClass.getActivity: // Result := TAndroidHelper.Activity.getIntent.getIntExtra(TJIntent.JavaClass.EXTRA_ALARM_COUNT, 0); {$ELSE} Result := false; {$ENDIF} end; {$IFDEF ANDROID} procedure TurnOnAndKeepScreenAndroid(aEnable: boolean); var vFlags: integer; begin vFlags := TJWindowManager_LayoutParams.JavaClass.FLAG_TURN_SCREEN_ON or TJWindowManager_LayoutParams.JavaClass.FLAG_DISMISS_KEYGUARD or TJWindowManager_LayoutParams.JavaClass.FLAG_SHOW_WHEN_LOCKED or TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON; if aEnable then begin CallInUIThread ( // uses FMX.Helpers.Android procedure begin TAndroidHelper.Activity.getWindow.setFlags (vFlags, vFlags); end ); end else CallInUIThread ( procedure begin TAndroidHelper.Activity.getWindow.clearFlags (vFlags); end ); end; {$ENDIF} И сразу же отключаем наш WakeLock устанавливая второй раз Alarmmanager на срабатывание через 3 сек (соответственно запуститься BroadcastReceiver и освободит WakeLock). (уже отключается сам в Broadcast сразу после старта Activity)- т.к. во флагах окна, уже указан FLAG_KEEP_SCREEN - это будет держать экран и систему включенной. Не забудьте поставить разрешение WAKE LOCK = true! Изменено 8 марта, 2017 пользователем ENRGY Rusland, amok и Евгений Корепов 2 1 Цитата Ссылка на комментарий
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.