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

ENERGY

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

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

  • Посещение

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

    57

Весь контент ENERGY

  1. ENERGY

    Отправка SMS в IOS

    Есть какие то результаты? Тоже интересует эта тема. На iOS нельзя отправить SMS в фоне без разрешения пользователя. Это искуcственный запрет от Apple. Максимум что можно сделать это только отправить текст смс в специальный компонент системы, это сообщение потом будет показано пользователю, который решит можно ли отправлять сообщение или нет. Если нужно отправить сообщение без вмешательства пользователя, нужно использовать сторонние сервисы, которые предлагают API для отправки смс на своей стороне. Т.е. для этого нужен интернет. Хотя вопрос остается открытым, как это сделать средствами iOS даже с учетом ограничений.
  2. Как увеличить количество последних сообщений? Это панель на форуме справа. Фактически это текущий, основной форум, это жизнь форума. 20 тем это мало, бывает пару дней не появишься, и пропустишь интересные темы уже навсегда. Хотя бы 30 надо.. Это еще людей на форуме мало, будет в раза 2-3 больше, - состав последних сообщений будет очень быстро меняться, в результате вероятность что вопрос останется без ответа увеличиться... Еще вопрос как найти свои темы? Зашел в настройки, там не нашел ни того ни другого.. Спасибо.
  3. ENERGY

    TMultiView и TListBox

    Тоже столкнулся с этим багом. Delphi Berlin update 2. А баг есть в QC? Я так понял проблема в MultiView, проще сделать popup меню вообще без MultiView - здесь описание: http://docwiki.embarcadero.com/RADStudio/Seattle/en/Mobile_Tutorial:_Using_ListBox_Components_to_Display_a_Table_View_(iOS_and_Android) Вообще по идее MultiView должен сам снимать выделение перед показом листбокса, странно что так не сделали.
  4. TMonchromeEffect подойдет для контролов. Для моего случая подходит. Но он не работает. Пишет "Class TMonochromeEffect not found" - добавляю как обычный эффект. В DesignTime работает. При запуске выбрасывает такое исключение. Кидаю вместо него TGlowEffect - работает без проблем. А как сделать это для картинки в runtime, есть ли какая-то процедура, вообще?
  5. Как сделать картинку TBitmap серой, т.н. неактивной? Возможно в FMX уже есть какие то эффекты или готовые методы для этого? Нужно для сгруппированных TSpeedButton - стили segmentedbuttonleft, segmentedbuttonmiddle итп.
  6. Еще мультипоточный вариант отсюда: class procedure TFireMonkey.CachePictures(const aLV: TListView); begin Pool.SetMaxWorkerThreads(10); // TThreadPool.Default.MaxWorkerThreads TParallel.For(0, FMembersList.Count - 1, procedure(Idx: Integer) var AHTTP: TIdHTTP; begin if not FileExists(FMembersList[Idx].FileName) then begin AHTTP := TIdHTTP.Create(nil); try AHTTP.HandleRedirects := true; FStreamList[Idx].Clear; AHTTP.Get(FMembersList[Idx].URL, FStreamList[Idx]); finally FreeAndNil(AHTTP); end; TThread.Queue(TThread.CurrentThread, procedure var AItem: Integer; begin if FStreamList[Idx].Size > 0 then begin FStreamList[Idx].SaveToFile(FMembersList[Idx].FileName); AItem := Trunc(Idx / aLV.Columns); if AItem < aLV.Items.Count then aLV.Adapter.ResetView(aLV.Items[AItem]); end; Log.d('Current Thread = ' + inttostr(Idx)); end); end; end, Pool); end; После загрузки ставьте boolean флаг в своем массиве, обозначающий что картинка загружена. Btw Boolean у Intel и ARM можно записывать и читать без синхронизации между потоками (Т.е. не нужно использовать TMonitor или AtomicExchange ), если он не в packed структуре (packed record).
  7. А зачем вам подряд все пиксели перебирать. Можно по диагонали перебрать к примеру 20-30 пикселей (5%-10% из всех пикселей из этой диагонали-линии).
  8. Много помалу = много.
  9. krapotkin На мой взгляд формат ini наиболее удобный - Секция > Имя=значение. 1. Не нашел как делить настройки на секции - в этом основное преимущество ini. 2. Парсинг json требует больше времени чем ini. Если настроек много, то это будет в несколько раз медленнее варианта ini. Например в моем проекте кроме основных настроек, есть еще группы, профайлы, и кампании. И очень удобно когда секции ссылаются друг на друга, причем втч. читать сам ini файл в текстовом редакторе. К примеру : [Group1] Key=Value [Profile2] Key=Value [Campaign1] Groups=Group1, Group2 Profiles=Profile1, Profile2 [Campaign2] [Campaign3]
  10. BEE-KEE-PER Что у Вас конкретно не получается? Способ описан выше, чтобы напрямую указать файл с изображением, - вместо TGlyph используйте TImage ,
  11. BEE-KEE-PER Вместо TGlyph можно использовать TImage, там точно можно указать картинку напрямую, без TimageList
  12. SharedPreference удаляются при деинсталяции программы.
  13. В Unix нет реестра, там все на файлах. Android, MacOS и iOS - это Unix. В Android есть 2 варианта для сохранения данных, которые не будут удалены после деинсталяции - сохранять на SD карту, и сохранять удаленно в свою базу (через интернет). http://stackoverflow.com/questions/19683614/android-persist-data-after-uninstall Хотя можно попробовать записать что-то и во внутреннее хранилище, в папки Music, Ringtones итп почитайте здесь статью Saving files that can be shared with other apps
  14. egorea1999 А о причинах, почему Вы не советуете делать действие X, нам нужно догадаться самим?
  15. Это касается ARC компиляторов, Android, iOS и будущего Linux. Если контейнер владелец, содержит классы, которые используют анонимный метод для общения с ним (классом владельцем), то такая конструкция порождает утечку памяти из-за появления циклической ссылки. Т.к. при присваивании анонимного метода инкрементируется счетчик ссылок и не меняется. Причем это не указано в хелпе. А дело было так - при вызове MyCore.Free класс не уничтожался - не вызывался деструктор из за того, что после вызова Free, счетчик ссылок (reference Count) был равен 1. Приходилось пользоваться DisposeOf. Решил разобраться. Для этого перекрыл виртуальные методы TObject отвечающие за изменения счетчика объекта (см. также полный пример ниже). function __ObjAddRef: Integer; override; function __ObjRelease: Integer; override; Итак TCore содержит класс TTestClass - у которого есть событие OnMyEvent. Прототип описан как анонимная процедура - TAnonymProc = reference to procedure; При указании анонимной процедуры, т.е. : procedure TCore.SetEvent; begin fTest.OnMyEvent := procedure () begin fSetFlag := true; end; end; счетчик ссылок TCore увеличивается на 1 и не изменяется при выходе из SetEvent. Теперь при вызове Free TCore - не будет вызван деструктор, который должен уничтожит классы TCore и TTestClass и произойдет утечка памяти. Решение : 1. Использовать слабые ссылки - weak, в нашем примере добавить атрибут [weak]: TTestClass = class strict private [weak]fOnMyEvent:TAnonymProc; public property OnMyEvent: TAnonymProc read fOnMyEvent write fOnMyEvent; end; При присваивании объекта в переменную со слабой ссылкой не происходит увеличение счётчика ссылок объекта на единицу. Аналогично, при очистке слабой ссылки не происходит уменьшение счётчика объекта на единицу. 2. Не использовать анонимные методы, а использовать обычные указатели на метод: Вместо TAnonymProc = reference to procedure; используем классический TAnonymProc = procedure of object; Демо пример, где можно отследить утечку прикрепил. Полный код: AnonMethodsCycle.zip
  16. Правильней будет сначала обнулить Родителя, затем вызвать Free. Чтобы уменьшить счетчик ARC. При присваивании класса этот счетчик увеличивается (т.к. появилась еще одна ссылка на него), и при обнулении ссылки - уменьшается. Можно поставить точку останова на деструктор вашего класса, чтобы точно узнать вызывается он или нет. При вызове Free на ARC компиляторах (а это iOS, Android и будущий Linux) - компилятор вызовов Free переделает в обычное обнуление. procedure TObject.Free; begin // under ARC, this method isn't actually called since the compiler translates // the call to be a mere nil assignment to the instance variable, which then calls _InstClear {$IFNDEF AUTOREFCOUNT} if Self <> nil then Destroy; {$ENDIF} end; Кстати в вашем случае, как написали выше лучше использовать дженерик TObjectList из System.Generics.Collections. Кстати он уничтожает объекты при помощи DisposeOf. Насчет DisposeOf. Эта конструкция явно вызывается деструктор объекта, но не освобождает память которая выделена под объект. Т.е. при обращении к такому "уничтоженному" объекту, не произойдет нарушения доступа (Access Violation). Такой объект называется зомби объект. Вот интересная статья, очень советую http://www.gunsmoker.ru/2013/05/modern-delphi.html Там описаны и слабые weak ссылки ,которые не увеличивают счетчик - удобно использовать когда классы хранят ссылки друг на друга.. У себя в проекте я в основном использую free (или FreeAndNil - в случае когда нужно проверять был ли уже создан ли объект (MyTObj <> nil).
  17. Да кстати это плохая практика. К примеру под iOS если программа потребляет много памяти сначала получает didReceiveMemoryWarning, затем автоматом убивается системой. Android попроще в этом плане, но тоже особо не жалует, и если такая прога будет в фоне, и как только потребуется память, то первыми на вылет. В общем это не Винда с ее "бесконечным" виртуальным свопом.. И хотя игрушки тянут гораздо больше памяти, а FMX гораздо меньше, но все такие вы должны быть в курсе.
  18. Офигеть. А для пуша нужно подключение к интернет верно? А для пуша нужен свой сайт на хостинге? Или можно как -то использовать сервера Apple?
  19. Можно об этом поподробнее? На днях как раз собираюсь iOS версию делать, и там нужен будет Alarm Manager. Т.е. там его нет? Как тогда можно запускать запланированные задания? Сервис в фоне?
  20. Поменяйте цвет этих иконок. В любой редакторе можно сдвинуть HUE (я обычно использую Axialis Icon Workshop и Photoimpact) - смещение цветов. И вам будет удобно, и не должны отказать. Можно также поискать Online Image\photo editor - но они как правило очень бедные по функционалу, и там может не быть изменения HUE.
  21. Обратите внимание на мой Broadсast Receiver, как мне кажется более удачный, адаптированный под Delphi XE 10+
  22. Мой вариант Broadcast Receiver, на мой взгляд наиболее оптимизирован и удачен. По сравнению с известным кодом от barisatalay . Отличия - исправлена утечка, чуть быстрее работает, за счет того что создается один фильтр в него добавляется несколько Actions и одна регистрация на него, нет лишних конвертирований с Jstring to string и обратно, адаптирован под Delphi 10 (JFMXBroadcastReceiver) , упрощена работа с классом (не нужно помнить о регистрации и вызывать ее заранее) , и самое главное - может получать getResultCode текущего ресивера (к примеру он нужен при получении статуса смс сообщения и в других случаях.). unit BroadcastReceiver; interface {$IFDEF ANDROID} uses Androidapi.JNI.Embarcadero, Androidapi.JNI.GraphicsContentViewText, Androidapi.helpers, Androidapi.JNIBridge, FMX.Helpers.Android, Androidapi.JNI.JavaTypes, System.Classes, System.SysUtils; type TBroadcastReceiver = class; TListener = class(TJavaLocal, JFMXBroadcastReceiverListener) private fOwner: TBroadcastReceiver; fReceiver: JFMXBroadcastReceiver; public constructor Create(aOwner: TBroadcastReceiver); destructor Destroy; override; procedure onReceive(context: JContext; intent: JIntent); cdecl; end; TOnReceive = procedure (aContext: JContext; aIntent: JIntent; aResultCode: integer) of object; TBroadcastReceiver = class private fListener : TListener; fRegistered: boolean; fOnReceive: TOnReceive; public constructor Create(aOnReceiveProc: TOnReceive); destructor Destroy; override; procedure AddActions(const Args: array of JString); procedure SendBroadcast(const aValue: string); end; {$ENDIF} implementation {$IFDEF ANDROID} { TBroadcastReceiver } constructor TBroadcastReceiver.Create(aOnReceiveProc: TOnReceive); begin inherited Create; fListener := TListener.Create(Self); fOnReceive := aOnReceiveProc; end; destructor TBroadcastReceiver.Destroy; begin fListener.Free; inherited; end; procedure TBroadcastReceiver.AddActions(const Args: array of JString); var vFilter: JIntentFilter; i: Integer; begin if fRegistered then TAndroidHelper.context.getApplicationContext.UnregisterReceiver(fListener.fReceiver); vFilter := TJIntentFilter.JavaClass.init; for i := 0 to High(Args) do vFilter.addAction(Args[i]); TAndroidHelper.context.getApplicationContext.registerReceiver(fListener.fReceiver, vFilter); fRegistered := true; end; procedure TBroadcastReceiver.SendBroadcast(const aValue: string); var Inx: JIntent; begin Inx := TJIntent.Create; Inx.setAction(StringToJString(aValue)); TAndroidHelper.Context.sendBroadcast(Inx); end; constructor TListener.Create(aOwner: TBroadcastReceiver); begin inherited Create; fOwner := aOwner; fReceiver := TJFMXBroadcastReceiver.JavaClass.init(Self); end; destructor TListener.Destroy; begin TAndroidHelper.context.getApplicationContext.unregisterReceiver(fReceiver); inherited; end; // usually android call it from "UI thread" - it's not main Delphi thread procedure TListener.onReceive(context: JContext; intent: JIntent); begin if Assigned(fOwner.fOnReceive) then fOwner.fOnReceive(Context, Intent, fReceiver.getResultCode); end; {$ENDIF} end. Как использовать // указывать нужно сразу все нужные вам Actions в Add через запятую, не по одной. fBroadcast := TBroadcastReceiver.Create(OnReceiveBroadcast); fBroadcast.AddActions([StringToJString(SENT_ACTION)]); << Custom action ------------- // или например сразу несколько Actions fBroadcast.AddActions([TJIntent.JavaClass.ACTION_SCREEN_OFF, TJIntent.JavaClass.ACTION_SCREEN_ON]);
×
×
  • Создать...