Перейти к содержанию
Fire Monkey от А до Я

Pax Beach

Пользователи
  • Постов

    414
  • Зарегистрирован

  • Посещение

  • Победитель дней

    12

Весь контент Pax Beach

  1. Жалко, что смог только сейчас подключиться к теме. Спасибо большое за ваше решение! Если говорить о больших Notifications, хотелось бы не просто весь текст всех уведомлений читать на экране, а разворачивать только те, что заинтересовали. Т.е. сделать у себя расширяемые и управляемые (с кнопками) уведомления. И хотелось бы, делать это без импорта дополнительных JAVA классов, если уж Embarcadero предоставляет нам возможность делать мосты, а Android SDK содержит все необходимые классы. К сожалению, я завис на своем проекте, и не могу сейчас предоставить готовый PAS код. Но вот, с чего бы я начал в первую очередь: 1. Взял пример работы с GSM из \Embarcadero\Studio\18.0\source\rtl\common\System.Android.Notification.pas; 2. Использовал порт \Embarcadero\Studio\18.0\source\rtl\android\Androidapi.JNI.Support.pas или выдернул последний из SDK 3. Изучил готовые примеры на Java, которые используют bigText и setAction; 4. Сделал бы свой Unit (компоненты я не научился пока хорошо делать) для работы с Big Smart Notifications (название сам придумал). Удачи в этом. Ваши исследования очень полезны для нас.
  2. Как видно в исходных кодах, при создании, запуске или активации контролов нет ни каких обработчиков. События начинаются, когда жмете на кнопки. Монитор что-нибудь полезное сообщает? Я тестирую на платформе android-19, SDK 23.0.3. Что у Вас стоит?
  3. Где висит? У меня весь код работает, за исключением того, что с принудительной остановкой сервиса вылетает и приложение почему-то. Исходный код открыт, можно понять, где зависает.
  4. var LJO: JObject; AM: JActivityManager; begin try LJO := TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.ACTIVITY_SERVICE); AM := TJActivityManager.Wrap((LJO as ILocalObject).GetObjectID); Log('Try to kill ' + JStringToString(TAndroidHelper.Context.getPackageName())); AM.killBackgroundProcesses(TAndroidHelper.Context.getPackageName()); except Log('Can not Access Activity Service!'); end; end; Этот код у меня работает. Добавил разрешение: <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> Еще есть такая тема
  5. Коллеги, в теме «Использование нативных LocalBroadcastManager и BroadcastReceiver» выложил пример работы с ресиверами без компонентов. На этом примере можно отловить суть проблемы. А именно, сервис всегда должен получать определенные сообщения, посланные ему broadcast. Но если запустить сервис, и нажать кнопку «Убить приложение», то сервис перезапустится, таймер в сервисе будет тикать, отправлять broadcast'ы, но ресивер не будет их принимать, пока руками не убить приложение в списке последних приложений. Тогда сервис снова перезапустится и будет нормально принимать сообщения. Потратил несколько часов на создание этого тестового стенда. Буду рад любой помощи в решении проблемы.
  6. Из PlatformSDK (PlatformSDKs\android-sdk-windows\sources\android-23\android\support\v4\content\) портировал в Delphi класс TJLocalBroadcastManager. Это очень полезный класс, если вы не хотите рассылать сообщения по всей системе, а есть необходимость общаться только внутри приложения или между хост-приложением и сервисом. Во вложении сам класс, в своем приложении убедитесь, что в Target Platforms (Android) → Android → Libraries включена библиотека android-support-v4.dex.jar. Прилагаю пример, для изучения и использования в работе, который демонстрирует работу обычного BroadcastReceiver и LocalBroadcastReceiver. В примере демонстрируется работа сообщений в приложении и сервисе. Сначала делаем build проекта LBCRService, потом будет доступна возможность собрать LocalBCR. Собираю в Berlin 10.1, но на младших версиях тоже должно работать, по крайней мере в Seatlle. В реализации методов procedure RegisterReceiver(); procedure UnRegisterReceiver(); необходимо снять комментарий с соответствующих строчек, в зависимости от того, какой тип ресивера вы хотите использовать. Androidapi.JNI.LocalBroadcastManager.pas.zip LocalBroadCastReceiver.zip
  7. Появляется диалоговое окно с надписью "Handle null exception" кнопкой ОК. Приложение сразу вылетает. В общем-то оно уничтожается, как и при закрытии с Action := caFree. На всякий случай я дал приложению android.permission.KILL_BACKGROUND_PROCESSES.
  8. Это всегда отдельная процедура — постобработчик. Вопрос лишь в том, на какое событие вы ее повесите — onChange, onChangeTracking, onExit, onKyeUp, onValidate, onValidating.
  9. Сервис стартует при старте приложения. При уничтожении приложения сервис перезапускается. В сервисе работает таймер, который раз в десять секунд отправляет приложению (и соответственно local service) Local Broadcast. При старте сервиса регистрируется Broadcast Receiver. Так вот после уничтожения приложения, но пока оно висит в списке последних, Handler перестает ловить события. Ждать можно сколько угодно, Android не чистит память самостоятельно, только когда я руками очищаю список последних приложений, как уже писал ранее. Попробую ставить для вас пример для тестирования.
  10. К сожалению, нет. После вызова методов, приложение действительно закрывается, но продолжает висеть в списке последних приложений. А это в свою очередь не позволяет сервису данного приложения получать broadcast сообщения, пока я вручную не выброшу приложения из списка последних запущенных. Т.е. сервис после этих вызовов перезагружается (пересоздается и запускается), но не получает broadcast, который генерирует таймер внутри сервиса. Как только приложение руками убил — монитор выдает собщения: Сервис снова перезапускается, и уже событие, которое слушает broadcastreceiver, начинает принимать сообщения. Вот что я уже испробовал вместе и по отдельности: procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction); var LJO: JObject; begin // Action := TCloseAction.caMinimize; Action := TCloseAction.caFree; Application.Terminate; TAndroidHelper.Activity.finish; TJActivityManager.Wrap((LJO as ILocalObject).GetObjectID).killBackgroundProcesses (StringToJString('ru.MySoft.DMControl')); TJActivityManager.Wrap((LJO as ILocalObject).GetObjectID).killBackgroundProcesses (StringToJString('com.embarcadero.firemonkey.FMXNativeActivity')); end;
  11. Мне необходимо, когда пользователь нажимает кнопку «Закрыть», уничтожить приложение. Если указать Action = caFree, приложение остается висеть в памяти, не уничтожается, методы Destroy в приложении и сервисе не срабатывают: procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction); begin DM.LocationSensor.Active := false; Action := TCloseAction.caFree; end; Если уничтожить приложение в смартфоне через «Последние приложения», тогда приложение уничтожается, сервис приложения перезапускается, и продолжает работать — это мне и надо. Помогите пожалуйста понять, как же правильно уничтожить приложение при закрытии основной формы? Подойдут решения отправки Intent, куда нужно, или вызовы нативных методов.
  12. Попробовал синхронизацию — сервис зависает на вызове TThread.Synchronize. TJLocalBroadcastManager решил проблему, код ниже. Правда, когда приложение завершается, и сервис перезапускается, последний перестает ловить сообщения для ресивера, потому что сервис уничтожается, а поток остается жить. Видимо, я не правильно убиваю поток. Помогите пожалуйста понять, как уничтожить анонимный поток, когда завершаться сервис (или приложение)? procedure TSvcMain.AndroidServiceCreate(Sender: TObject); var LThread: TThread; begin MyService := JavaService; // глобальная переменная FThreads := TObjectList<TThread>.Create; RegisterReceiver; StartLocationSensor; LThread := TThread.CreateAnonymousThread( procedure begin Log('+ Thread [%d] started', [TThread.CurrentThread.ThreadID]); while TThread.CurrentThread.Started do begin Log('... Thread [%d] ticked', [TThread.CurrentThread.ThreadID]); Sleep(TimerInterval); if (not Assigned(MyService)) or (not TThread.CurrentThread.Started) then begin Log('- stop Thread [%d]', [TThread.CurrentThread.ThreadID]); break; end else begin TJLocalBroadcastManager.JavaClass.getInstance(MyService) .sendBroadcast(TJIntent.JavaClass.init(StringToJString(LocationAction))); end; end; TThread.CurrentThread.Terminate; end); LThread.FreeOnTerminate := false; FThreads.Add(LThread); LThread.Start; end; При уничтожении сервиса я пытаюсь убить поток: procedure TSvcMain.AndroidServiceDestroy(Sender: TObject); var i: Integer; begin StopLocationSensor; try for i := 0 to FThreads.Count - 1 do if Assigned(FThreads.Items[i]) then begin Log('Thread [%d] terminated', [FThreads.Items[i].ThreadID]); FThreads.Items[i].Terminate; end; finally FThreads.Free; end; end;
  13. Спасибо, актуально. Но мои устройства работают без интернета, sim-карт и Wi-Fi, только GPS в сервисе. Соответственно, работать могу только с сенсором.
  14. Спасибо, Ярослав. Есть вопросы: какой вызов нужно синхронизировать с главным потоком и как это делается в Delphi? Сложный для моего понимания вопрос. Ни как не могу понять, как синхронизация позволяет передать в поток таймера контекст основного потока. Наверное, потому что кусками материал изучаю. Вот если бы пример на Java или, еще лучше, Delphi.
  15. Обнаружил нюанс: если обращаться к TSensorManager.Current из события POSIX таймера, монитор выдает такую ошибку: E/error(19014): - Сan't start sensor: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() А что это за лупер, и почему его нет в моем потоке, я пока ни как не могу разобраться.
  16. У меня почему-то умирает приложение, я так подозреваю, что в момент, когда приходит сигнал от устройства. Последнее сообщение в monitor, что сервис запущен. А потом: 06-24 20:15:22.894: I/art(5078): Thread[2,tid=5083,WaitingInMainSignalCatcherLoop,Thread*=0xb9c54f00,peer=0x12d200a0,"Signal Catcher"]: reacting to signal 3 06-24 20:15:23.036: I/art(5078): Wrote stack traces to '/data/anr/traces.txt' UPD: А... пардон. Доблестные документаторы забыли дописать, что для приложения нужно установить разрешения на работу с BlueTooth <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> UP-UPD: Все приходит, монитор сообщает о событии в сервисе каждые несколько секунд: 06-24 20:27:29.121: I/info(14450): Beacon1BeaconProximity: {B9407F30-F5F8-466E-AFF9-25556B57FE6D} 06-24 20:27:29.121: I/info(14450): Beacon1BeaconProximity: {B9407F30-F5F8-466E-AFF9-25556B57FE6D} Правда Notification вылетает в StatusBar только по первому событию, а потом, молчит. Думаю, что Bluetooth здесь уже не причем.
  17. Так как приложение называется в AppStore? Просто утонул в выдаче по запросу iBeacon. UPD: нашел Locate Beacon.
  18. Ну вот, запустил я демку и сервис крутится в памяти. А как из iPhone сделать маячок?
  19. как бы да, но вендор говорит, что будет вежливым у пользователя спросить разрешение.
  20. А где такое реализовано, подскажите плиз, хочу с ними встретиться?
  21. Да, у меня такая же ситуация. Не доделали в С++.
  22. Это предрассудки для новых моделей Android, да и iOS. Сетевые карты спать ложатся, когда не используются. Ну и, если очень нужно, можно время от времени включать и выключать программно.
  23. Я думал, здесь шутят по поводу отсутствия Android сервисов в C++. Оказывается, действительно нет =( Но это не повод переходить на Delphi — всегда можно переписать шаблон service.template.java под себя, и в манифесте включить этот сервис =)
  24. ZuBy, у меня почему-то цвет статус-бара темнее, чем цвет фона кнопок. А еще возникает вопрос, как изменить цвет иконок статус-бара, потому что на белом фоне белые иконки не очень хорошо смотрятся?
×
×
  • Создать...