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

Лидеры

  1. krapotkin

    krapotkin

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


    • Баллы

      373

    • Постов

      2 179


  2. Евгений Корепов

    Евгений Корепов

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


    • Баллы

      258

    • Постов

      738


  3. Brovin Yaroslav

    Brovin Yaroslav

    Администраторы


    • Баллы

      184

    • Постов

      2 124


  4. ENERGY

    ENERGY

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


    • Баллы

      153

    • Постов

      568


Популярный контент

Показан контент с высокой репутацией за 02.01.2018 во всех областях

  1. Привет Вчера была выпущена финальная версия RAD Studio 10.3 Rio, в которой много нововведений для Андройд. Но вот про статусбар снова "забыли". Хотя не совсем, добавили файлик styles-v21.xml, который превносит новую материальную тему на устройствах под управлением Android 5.0 и выше вместо устаревшей Holo. Но все равно свойство формы SystemStatusBar так и не реализовали. Поэтому при запуске статус бар будет окрашен в унылый серый цвет (см. скриншот). Для того, чтобы сделать статусбар прозрачным и поместить под него содержимое формы, то достаточно сделать несколько несложных шагов: 1. Убираем из деплоймента (Project -> Deployment) файл styles-v21.xml (можно просто снять галочку рядом с именем файла) 2. Добавить в деплоймент проекта новый файл styles-v21.xml (styles-v21.zip) и прописать ему путь res\values-v21\ 3. В результате получится следующий вид P.S. В новом файле по сравнению со стандартным добавилась строчка <item name="android:windowTranslucentStatus">true</item>, которая и отвечает за прозрачный статусбар P.P.S. Чтобы определять размер статус бара, все также можно воспользоваться решеним ZuBy - http://blog.rzaripov.kz/2016/12/android-ios.html P.P.P.S. Тестовый проектик - StatusBar.zip
    17 баллов
  2. Всем привет! После долгого творческого запоя я запилил альфу либы, которая позволяет юзать обычный, не-генномодифицированный ListView. Данные подаются в виде модели данных, описание раскладки итема лежит в JSON. Для работы пишется примитивный наследник класса-адаптера, который биндит данные модели на элементы из JSON. Я решил, что руками делать это дешевле чем через RTTI { TMyAdapter } procedure TMyAdapter.SetupDrawableContent(const ADrawable: TListItemDrawable; const AData: TMyData); begin if SameText( ADrawable.Name, 'text') then begin (ADrawable as TListItemText).Text := AData.Text; end else if SameText( ADrawable.Name, 'detail') then begin (ADrawable as TListItemText).Text := AData.Detail; end else if SameText( ADrawable.Name, 'balance') then begin (ADrawable as TListItemText).Text := FormatFloat('0.00', AData.Balance); end else if SameText( ADrawable.Name, 'reserved') then begin (ADrawable as TListItemText).Text := FormatFloat('0.00', AData.Reserved); end end; Главная хитрость и отличие от стандартного DynamicAppearance+LiveBinding - переменная высота итемов ListView и использование арифметики в описании раскладки. Можно указать Detail.Y = Text.Bottom + 5, ItemHeight = Detail.Bottom + 10, Detail.W = ItemWidth/2 - X {"Kind":"rect","Name":"BonusRect","Value":"", "Place":{"X":"itemwidth*3/4","Y":"Text.Y","W":"ItemWidth/4-5","H":"50"}, "BorderColor":"#FF005500", "Color":"lime", "LineWidth":3}, {"TextHAlign":2,"TextVAlign":1,"Kind":"text","Name":"Balance","Value":"", "Place":{"X":"BonusRect.x+5","Y":"Text.Y","W":"BonusRect.w-10","H":"50"}, "WordWrap":true, "Color" :"Black", "Font":{"Size":18,"Style":""}} ], "ItemHeight":"detail.bottom+10", Это дает довольно гибкую систему. Не на все случаи жизни, но все, что нужно, можно после автоматической раскладки дополнительно приписать в OnUpdateObjects Код для работы примерно такой procedure TForm1.FormCreate(Sender: TObject); begin data:= TMyDataList.CreateFromFile(ExePath()+'data.json'); // загрузка в модель данных Adapter := TMyAdapter.Create(lvWallets, data.Items, ExePath()+'pattern.json'); // создание адаптера и загрузка шаблона Adapter.Pattern.SetupListView(lvWallets); // задать отступы и разную мелочь Adapter.ResetView(); // здесь в цикле из модели данных создается нужное количество итемов ListView end; procedure TForm1.lvWalletsUpdatingObjects(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean); begin Adapter.SetupContent(AItem); // загрузить текст, картинки и другое содержимое в элементы итема Adapter.Pattern.DoLayout(AItem); // поправить раскладку в соответствии с содержимым элементов итема end; Для использования кроме стандартных - текст, картинка, кнопка - создано несколько дополнительных элементов итема - прямоугольник, круг, уголок, линия. Отличие от ModernLV - , 1) все происходит без правки системных файлов 2) пока нет колонок и других особых изысков. На результат работы смотреть тут. Исходники пока не причесаны, будут чуть позже UPD. ссылки на репозитории ниже
    13 баллов
  3. Как сделать текст с подобными атрибутами? Очень просто! (Цвет текста не работает в XE8) Вот весь код: unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.UIConsts, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.TextLayout; type TForm1 = class(TForm) Button1: TButton; Text1: TText; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} type TTextAccess = class(TText); procedure ClearTextAttribute(Text: TText); begin TTextAccess(Text).Layout.ClearAttributes; end; procedure AddTextAttribute(Text: TText; Pos,Length: Integer; FontStyles: TFontStyles; FontColor: TAlphaColor); var Font: TFont; begin Font:=TFont.Create; Font.Assign(Text.Font); Font.Style:=FontStyles; TTextAccess(Text).Layout.AddAttribute( TTextRange.Create(Pos,Length), TTextAttribute.Create(Font,FontColor)); end; procedure TForm1.Button1Click(Sender: TObject); begin AddTextAttribute(Text1,10,17,[TFontStyle.fsBold],claRed); AddTextAttribute(Text1,34,8,[TFontStyle.fsUnderline],claBlue); AddTextAttribute(Text1,47,8,[TFontStyle.fsStrikeOut],claGreen); Text1.Repaint; end; end.
    12 баллов
  4. В конце концов получилось исправить. Для interlaced гифок проблема была вообще пустяковая. Одна строчка не в том месте. А вот для optimized все оказалось несколько сложней, но в итоге теперь все гифки отображаются правильно. Пользуйтесь на здоровье! FMX.GifUtils.zip
    12 баллов
  5. У меня в работе два приложения, и оба они не предназначены для Play market, так как имеют ограниченный круг использования, по сути, чисто внутрикорпоративные. Так что нежелательно и выкладывание их и на альтернативные магазины приложений. Автоматически возникает вопрос обновления. Если в первый раз мы можем установить приложение сами при помощи админов, то обновлять их не так просто. А контингент пользователей не справится с "скачайте APK по ссылке, найдите, куда его скачал браузер, и запустите вручную именно последний скачанный, а не какой попало"... Простейший способ - дать приложению скачать свежую копию с сайта и натравить на полученный файл системный инсталлер. Вот только свежие Andoird делать это напрямик запрещают. Нужен filepropvider. Целый день шуровал по мануалам и YT, Вот то что получилось в результате. Если у вас 10.3.3 как у меня, уже можно не вносить <provider>...</provider> в манифест и свой файл file_paths.xml (или как вам его советуют назвать в интернетах) в деплой. Теперь все это делается хоть несколько странно и однобоко, но автоматически, путем установки галочки Secure File Sharing после этого в манифесте автоматически пропишется один из вариантов размещения файлов, которые вы можете найти в интернете. Используется алиас external-path файл, показанный на рисунке, создается автоматически самой делфи. теперь остается отгадать, какой путь реально подставится вместо "." Как показала практика, все пути выглядят не так, как кажется, если исходить из простого здравого смысла. Целый день использования GetHomeDir и других полезных методов TPath завел меня совсем в тупик. Оказалось все проще (?) st:TMemoryStream; OutputDir: JFile; ApkFile: JFile; ApkUri: Jnet_Uri; path, filename: string; ... OutputDir := TAndroidHelper.Context.getExternalCacheDir(); path := JStringToString(OutputDir.getAbsolutePath); filename := path+'/ASDroid2.apk'; ApkFile := TJfile.JavaClass.init( StringToJstring(filename)); FApkUri := TAndroidHelper.JFileToJURI(ApkFile); st.Position := 0; st.SaveToFile(filename); обратите внимание, в provider_paths мы задаем external-paths, а в коде ищем ExternalCacheDir.!!! (For.Unbelievably.Creative.Knowers!) Потом все просто. FApkUri передаем в интент и запускаем итоговый код примерно таков. (скачивание в потоке с использованием небольшого собственного API, но там ничего важного, можно не обращать внимания) procedure TasdSettingsFrame.bDownloadClick(Sender: TObject); begin {$IFDEF ANDROID} bDownload.Enabled := False; DownloadAndRun(); {$ENDIF} end; {$IFDEF ANDROID} procedure TasdSettingsFrame.DownloadAndRun(); begin ttask.Run(procedure var aapi:TasdAPI; st:TMemoryStream; OutputDir: JFile; ApkFile: JFile; ApkUri: Jnet_Uri; path, filename: string; begin st := TMemoryStream.Create; aapi := TasdAPI.Clone(_API); try aapi.OnReceiveData := OnReceiveData; aapi.getApk(st); if aapi.Err.Code=0 then begin OutputDir := TAndroidHelper.Context.getExternalCacheDir(); path := JStringToString(OutputDir.getAbsolutePath); filename := path+'/ASDroid2.apk'; ApkFile := TJfile.JavaClass.init( StringToJstring(filename)); FApkUri := TAndroidHelper.JFileToJURI(ApkFile); st.Position := 0; st.SaveToFile(filename); TThread.Synchronize(nil,procedure begin bDownload.Enabled := true; StartActivity(FApkUri); end); end; finally st.Free; aapi.Free; end; end); end; procedure StartActivity(ApkUri: Jnet_Uri); var Intent: JIntent; begin Intent := TJIntent.Create(); Intent.setAction(TJIntent.JavaClass.ACTION_VIEW); Intent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK or TJIntent.JavaClass.FLAG_ACTIVITY_CLEAR_TOP or TJIntent.JavaClass.FLAG_GRANT_WRITE_URI_PERMISSION or TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION); Intent.setDataAndType(apkuri, StringToJString('application/vnd.android.package-archive')); TAndroidHelper.Activity.startActivity(Intent); end; procedure TasdSettingsFrame.OnReceiveData(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean); begin tthread.Synchronize(nil, procedure begin pb1.Max := AContentLength; pb1.Value := AReadCount; end); end; {$ENDIF} Вопросы остались конечно, почему так странно с каталогами, но выяснять пока нет желания. Работает - не трожь. Всем удачи. UPD. Для того, чтобы системный инсталлер запускался, нужно не забыть отметить еще одну галочку
    11 баллов
  6. Расскажу о том как я добился нормальной фоновой работы приложения. В моем понимании нормальная фоновая работа приложения - это сохранять геокоординаты и систематически (по мере их накопления передавать на сервер). По сути у нас получился трекер. Те кто считают что iOS такое не умеет делать, и все что будет написано ниже это фейк лучше закройти эту тему. Итак начнем, по пунктам: 1) Добавляем к проекту ключ NSLocationAlwaysAndWhenInUseUsageDescription - для новых иОС это обязательно, начиная с 11 или 12 версии уже не помню 2) Сообщаем приложению о намерении что мы будем использовать геокоординаты в фоне (редактируем ключ UIBackgroundModes выставляя галочку напротив location) 3) Далее для того чтобы не поломать другие приложения которые используют геолокацию создаем специальную дерективу, которая будет сообщать о том что наше приложение будет использовать геолокацию в фоне, я ее назвал iOS_RequestAlwaysAuthorization 4) Дальше намного сложнее, нам нужно исправить исходники самой Delphi, а именно System.iOS.Sensors. Изменять будем процедуру TiOSLocationSensor.DoStart, все что отличается от стандартного у меня в рамках описания моей директивы: function TiOSLocationSensor.DoStart: Boolean; var I: Integer; begin {$ifdef iOS_RequestAlwaysAuthorization} if TOSVersion.Check(8) and (FLocater <> nil) then FLocater.requestAlwaysAuthorization; {$else iOS_RequestAlwaysAuthorization} if TOSVersion.Check(8) and (FLocater <> nil) then FLocater.requestWhenInUseAuthorization; {$endif iOS_RequestAlwaysAuthorization} // check authorization if Authorized = TAuthorizationType.atUnauthorized then SensorError(SLocationServiceUnauthorized); // check if location sensor is enabled if not FLocater.locationServicesEnabled then SensorError(SLocationServiceDisabled); // start location updates if (LocationChange = TLocationChangeType.lctLarge) and CanUseSignifChangeNotifs then FLocater.startMonitoringSignificantLocationChanges else FLocater.startUpdatingLocation; // start heading updates if CanUseHeading then begin FLocater.startUpdatingHeading; end; // start monitoring regions if CanMonitorRegions then for I := 0 to Regions.Count - 1 do FLocater.startMonitoringForRegion(ConvLocationRegion(Regions[I])); Result := FLocater.locationServicesEnabled; if Result then Result := Authorized = TAuthorizationType.atAuthorized; {$ifdef iOS_RequestAlwaysAuthorization} FLocater.setAllowsBackgroundLocationUpdates(True); FLocater.setPausesLocationUpdatesAutomatically(False); {$endif iOS_RequestAlwaysAuthorization} end; Собственно усе, можно наслаждаться фоновой работой. Все это работает под Delphi 10.2.3. На телефоне iPhone 6s под управлением iOS 11. Как было сказано выше, работает как геолокация так и инет и вообще все остальные процессы внтури приложения, такие как TTimer Собственно вот результат данного трекера: Если приблизить то можно увидеть насколько точно и часто он обновляет координаты: И да, огромное спасибо человеку с ником Artyom Karapetyan, именно он натолкнул на мысль того как надо правильно все сделать
    11 баллов
  7. Принцип работы такой: На форму кладете стандартный TImage Создаете экземпляр TGifPlayer Задаете свойство FGifPlayer.Image:=Image; где Image это лежащая на форме TImage Загружаете гифку FGifPlayer.LoadFromFile('D:\Embarcadero\Projects\ShareCode\FMX.GifUtils\GIF_Example.gif'); Запускаем проигрывание гифки FGifPlayer.Play; Вот код: unit UnitFormMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.GifUtils, FMX.Objects; type TFormMain = class(TForm) Image: TImage; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } FGifPlayer : TGifPlayer; end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); begin FGifPlayer:=TGifPlayer.Create(Self); FGifPlayer.Image:=Image; FGifPlayer.LoadFromFile('D:\Embarcadero\Projects\ShareCode\FMX.GifUtils\GIF_Example.gif'); FGifPlayer.Play; end; end. Вот демо проект во вложении: FMX.GifUtils.Demo.zip
    10 баллов
  8. yooSee

    Runtime permissions in Delphi 10.3 Rio

    Всем привет, вот и я решил внести свою лепту в жизнь форума и сегодня мы разберемся с разрешениями на Delphi Rio под Андроид. Для примера мы будем использовать разрешения на чтение и запись с памяти устройства, для начала в нашем проекте выставим в Delphi>Project>Application>Uses Permissions галочки на Read External Storage и Write External Storage. в uses проекта добавьте следующее uses System.Permissions, Androidapi.Jni.Os, Androidapi.Helpers, далее создадим переменные var Form: TForm; .... FPermissionWrite: string; FPermissionRead: string; в Form.Create добавим следующий код procedure TForm.FormCreate(Sender: TObject); begin FPermissionWrite := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); //Значение на запись FPermissionRead := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE); //Значение на чтение end; и теперь сам не посредственно запрос на подтверждение наших прав procedure TForm.Button1Click(Sender: TObject); begin PermissionsService.RequestPermissions ([FPermissionWrite, FPermissionRead], nil); end; //это вызовет окно с запросом разрешения прав ну и для проверки бросим на форму TMemo и пару TButton , в них реализуем сохранение и чтение из файла с памяти устройства procedure TForm.Button1Click(Sender: TObject); begin Memo1.Lines.LoadFromFile(TPath.Combine(TPath.GetSharedDocumentsPath, 'test.txt')); end; procedure TForm.Button2Click(Sender: TObject); begin Memo1.Lines.SaveToFile(TPath.Combine(TPath.GetSharedDocumentsPath, 'test.txt')); end; P.S. Напоминаю что для работы TPath нам понадобится подключить в Uses uses System.system.ioutils; Надеюсь материал будет полезен! video_2019-02-08_00-11-36.mp4 Permissions.zip
    9 баллов
  9. Хочу от всей души поздравить с днем рождения нашего модератора Андрея Ефимова @Andrey Efimov. Человек, на которого можно положиться и который всегда готов прийти на помощь. Из года в год помогает нашему форуму становиться лучше. С днем рождения! Успехов тебе в работе, в личных делах. И не забывать про Делфи!
    9 баллов
  10. Задался вопросом, нашел ответ, может кому пригодится. uses Androidapi.JNI.Media, Androidapi.Helpers, Androidapi.JNIBridge, AndroidApi.Jni.JavaTypes, Androidapi.JNI.GraphicsContentViewText; .... procedure TFormMain.PlaySoundEffects(const ASoundID : Integer; AVolume : Single = 1.0); var AudioObj: JObject; Audio: JAudioManager; begin AudioObj:= TAndroidHelper.Context.getSystemService(TJContext.JavaClass.AUDIO_SERVICE); Audio:= TJAudioManager.Wrap((AudioObj as ILocalObject).GetObjectID); Audio.loadSoundEffects; Audio.playSoundEffect(ASoundID, AVolume); end; Константы звуковых эффектов тут https://developer.android.com/reference/android/view/SoundEffectConstants Правда у меня только звук "чпок" на всех константах. Но мне он и был нужен )
    9 баллов
  11. Ну вот набросал примерчик. Он упрощенный, но смысл такой же примерно (код листвью со скриншота выше выложить не могу просто из-за того, что там идут зависимости от модели данных). Лично я все рисую кодом - так полный контроль того, что выводится на экран. И собственно так можно выводить практически что угодно. И не нужны никакие монструозные ТМС компоненты ListView_Schedule_Sample.zip
    9 баллов
  12. В общем удалось решить проблему с кнопками пульта. Теперь приложение распознает все кнопки с пульта. Если кому-то нужно, прикрепил архив. (Delphi 10.3.1 Rio) fmx_androidkey_fix.zip
    8 баллов
  13. OnePeople

    Монополия

    Делал чисто для себя! И только для своего удовольствия! Возможны ошибки!*(вернее точно есть))) Графика не окончательная! Скриншоты сервер: Скриншоты клиент: Сервер на комп, клиент Android (должны находиться в одной сети) P/S И так как все устройства у меня Full HD, проверял только на них( Monopoly.rar
    8 баллов
  14. Тема: "Сравнение возможностей кроссплатформенных мобильных библиотек нативных приложений FMX и FGX Native" Дата и время: 20 декабря 2018 года в 12:00 (по московскому времени) Участники: @Brovin Yaroslav, Андрей Совцов Регистрация: ссылка Ссылка на официальный телеграмм канал: https://t.me/fgx_native Участие бесплатное Под конец уходящего нового года сравним текущие возможности кроссплатформенной библиотеки мобильной разработки FGX Native и FMX. Поговорим о перспективах развития и ознакомимся с ближайшим планом до выпуска публичной бета версии. Посмотрим в живую на новый функционал библиотеки, разработанный за последнее время. У вас будет возможность задать любые вопросы автору. Не пропусти эту возможность!
    8 баллов
  15. brunnengi

    Android 10 (API уровня 29)

    Здравствуйте. Некоторые пользователи Delphi 10.3 столкнулись с тем что даже при указании SDK 29 в манифесте проекта, при запуске скомпилированного приложения на платформе Android 10 происходило его падение. В августе 30 числа 2020 года было дано решение как пофиксить эту проблему. Переход на версию Delphi 10.4 не для всех является приемлемым решением, по разным причинам, к примеру у кого то платные компоненты и нет возможности обновиться до актуальных версий. Ниже представлен перевод статьи. В конце будет ссылка на оригинал. Приведенное здесь решение нацелено на обновление функции 'dlopen' в файле 'ICU.inc' (он включен в файл 'System.pas'). Вот шаги, необходимые для решения указанной проблемы: Откройте проводник и перейдите в папку по следующему пути: C:\Program Files (x86)\Embarcadero\Studio\20.0\source Скопируйте файлы из архива "missing_source_files.zip", который приложен в посту, в папку source из пункта "1" (комментарий от переводчика: в "missing_source_files.zip" лежит папка "rtl" в которой две папки - "posix", "sys". Лично я сделал сначала backup папки rtl из папки source, что и вам советую. Затем скопировал rtl папку из "missing_source_files.zip" и вставил в папку source) Переходим по пути: C:\Program Files (x86)\Embarcadero\Studio\20.0\source\rtl\sys Открываем файл "ICU.inc" в текстовом редакторе (пожалуйста, сделайте backup файла 'ICU.inc' для пущей безопасности). (комментарий от переводчика: орудовать в этой папке без прав админа не вариант. Поэтому я советую сначала скопировать файл "ICU.inc" куда нибудь в другое место, к примеру в папку Documents и там уже открыть его в том же Блокноте и сделав необходимые изменения сохранить файл и затем уже переместить его в C:\Program Files (x86)\Embarcadero\Studio\20.0\source\rtl\sys с заменой) В текстовом редакторе надо изменить функцию InitICU: Было вот так: А сделать надо что было вот так: Сохраняем сделанные изменения в файле "ICU.inc" Возвращаемся в проводник и переходим в папку %USERPROFILE% Скопируйте файл "build.bat" из архива "build_script.zip" , который приложен в этому посту в папку из пункта 7. Запустите от имени Администратора файл "build.bat". (Он создаст папку %USERPROFILE%\build в которой будет несколько папок с файлами. Из них нам нужны будут только System.o, но об этом ниже) Возвращаемся в проводник и переходим в папку C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\debug Скопируйте файл "System.o" из папки %USERPROFILE%\build\android\debug в папку из шага 10 (не забывайте сделать backup всех файл что вы заменяете, на всякий случай). Теперь переходим в проводник в папку C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\release Скопируйте файл "System.o" из папки %USERPROFILE%\build\android\release в папку из шага 12 (не забывайте сделать backup всех файл что вы заменяете, на всякий случай). Переходим в проводник в папку C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android64\debug Скопируйте файл "System.o" из папки %USERPROFILE%\build\android64\debug в папку из шага 14 (не забывайте сделать backup всех файл что вы заменяете, на всякий случай). Переходим в проводник в папку C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android64\release Скопируйте файл "System.o" из папки %USERPROFILE%\build\android64\release в папку из шага 16 (не забывайте сделать backup всех файл что вы заменяете, на всякий случай). На этом всё. Автор данного перевода лично прошел по всем шагам и сделал всё как было сказано, а также протестил на приложении что уже было в PlayMarket'е но не запускалось под Android 10. Я его обновил и запустил как на Android ниже 10, так и на Android 10. ЕСЛИ ВЫ НЕ ДОВЕРЯЕТЕ ПЕРЕВОДУ И/ИЛИ ВЫЛОЖЕННЫМ ФАЙЛАМ, ТО НИЖЕ ДАНА ССЫЛКА НА ОРИГИНАЛ СТАТЬИ // файлы выложенные здесь, взяты с форума где оригинал статьи. Ссылка на оригинал https://quality.embarcadero.com/browse/RSP-27218 Если нет логина, то под споллером скрины экрана с форума ссылки выше: Отдельное спасибо пользователю Stanislau Ihnatovich за сообщение в Telegram о том что есть решение build_script.zipmissing_source_files.zip
    7 баллов
  16. krapotkin

    Переезд на 10.3 Rio

    сколько бед принесла уже стрельба в ногу под названием ProcessMessages как хорошо, что в Андроиде наконец всех отучат от этого крайне вредного трюка давайте формально все что там у вас "высоконагруженное" выносите в потоки и пусть они работают. Ваши "потоки" пасутся в главном (Synchronize) и никакого толка нет концепцию надо поменять. запустили поток и занимайтесь своим делом. например покажите Splash а вернется поток - вот по возвращению и сделаете то, что этот Splash закроет. и уж точно потоки не должны ничего общего иметь с формами я писал статью про потоки, там про сплеши тоже есть в блоге и про ProcessMessages отдельная боль... http://www.cyberforum.ru/blogs/469693/blog4875.html
    7 баллов
  17. Для полноценной работы вам нужно добавить параметры в вызов (иначе вы не узнаете дал ли пользователь разрешение или нет) PermissionsService.RequestPermissions([FPermissionWrite, FPermissionRead], nil); Вот так: PermissionsService.RequestPermissions([FPermissionWrite, FPermissionRead], PermissionRequestResult, ExplainReason); PermissionRequestResult - это обработка ответа пользователя procedure TForm.PermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); begin if (Length(AGrantResults) = 2) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) then begin // Ура! Пользователь дал разрешение на оба наших запроса. Выставялем глобальные флаги (к примеру) которые сигнализируют что можно читать/писать карту памти end else TDialogService.ShowMessage('Не возможно продолжить работу, требуемые разрешения не получены') end; И ExplainReason - если пользователь сдуру не дал разрешение, то вам нужно объяснить ему что без этого приложение работать не будет. procedure TForm.ExplainReason(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc); begin TDialogService.ShowMessage('Приложению нужен доступ к карте памяти для таких то целей, иначе приложение не сможет работать. Зайдите в настроки Андроид и дайте разрешение на доступ', procedure(const AResult: TModalResult) begin APostRationaleProc; end) end;
    7 баллов
  18. Недавно решил одну проблемку, которая долго мучала - решил поделиться, может кому ещё пригодится. При работе с двумя мониторами или с монитором и проектором часто возникает необходимость запретить окну "исчезать" при наведении курсора мыши на миниатюру другого приложения в панели задач. Чтобы это сделать надо: uses ... Winapi.DwmApi ... TMainForm = class(TForm) ... protected procedure CreateHandle; override; ... end; ... procedure TMainForm.CreateHandle; var Val, Res: Integer; begin inherited CreateHandle; Val := 1; Res := DwmSetWindowAttribute(FormToHWND(Self), DWMWA_EXCLUDED_FROM_PEEK, @Val, SizeOf(Val)); {$IFDEF DEBUG} if Res <> S_OK then ShowMessage(SysErrorMessage(Res)); {$ENDIF} end; Спасибо @Alex7wrt за наводку
    7 баллов
  19. dnekrasov

    FMX Form

    Не за что. Маленькое уточнение - это хорошо работает только если один монитор. Вообще правильнее эмулировать максимизацию окна следующим образом: SetBounds(Screen.DisplayFromRect(Bounds).WorkAreaRect);
    7 баллов
  20. Написал в XE10.1 простой модуль для вывода кривых на TImage в виде графика - есть возможность вывода столбцов для диаграмм, меток с надписями и прочей мелочи. В виде компонента не оформлял... Смысл: вводим массив точек - график сам подбирает область вывода чтобы влезли надписи и выводит с указанными параметрами и стилем кривые (имею в виду зависимости Y от X). Есть комментарии в коде - есть пример для тестов - см. проект https://github.com/willi-spb/arTrassing желательно тестирование, возможно я что-то упустил - сам модуль: https://github.com/willi-spb/arTrassing/blob/master/FMX.arCurveClasses.pas
    7 баллов
  21. В этом участке кода есть одна маленькая ошибка. Иногда это приводит к тому, что на некоторых кадрах теряется прозрачность. Я заменил на вот такое : GIF_DISPOSAL_BACKGROUND: begin LFrame.FDisbitmap.Clear(LLocalPalette[LGraphicsCtrlExt.ColorIndex].Color); MergeBitmap(tmp, LFrame.FDisbitmap, Bounds(0, 0, LFrameWidth, LFrameHeight), LFrame.FPos.x, LFrame.FPos.Y); end;
    7 баллов
  22. Столкнулся с такой же проблемой, если любой компонент (в моем случае TImage ) лежит на фрейме не работает TFloatAnimation вообще. Решение: При создании фрейма нужно указывать Self формы, а не nil. : MyFrame := TMyFrame.Create(Self);
    7 баллов
  23. Задачу решил. Вот измененная процедура, ну и добавил вытягивание параметра sound private Builder buildNotification(String msgTitle, String msgText, String msgSound, PendingIntent contentIntent) { int icon = this.mContext.getApplicationContext().getApplicationInfo().icon; Builder mBuilder = new Builder(this.mContext); mBuilder.setSmallIcon(icon); mBuilder.setTicker(msgTitle); mBuilder.setContentTitle(msgTitle); mBuilder.setContentText(msgText); mBuilder.setContentIntent(contentIntent); // savage if (msgSound == "") { mBuilder.setSound(RingtoneManager.getDefaultUri(2)); } else { mBuilder.setSound(Uri.parse("android.resource://" + this.mContext.getPackageName() + "/raw/"+msgSound)); } // return mBuilder; } Звуковой файл надо добавить в Deployment Расположение res/raw/ При формировании push-сообщения имя файла указывается без расширения. К примеру, если звуковой файл был event1.mp3, то в пуше посылаем "sound":"event1" Во вложении патченый файл. Сборка fmx.jar и classes.dex как в этой теме NotificationPublisher.zip
    7 баллов
  24. Набросал простенькую программу для создания стилей под все платформы на основе указанного. Программа только меняет информацию о платформе, никаких других измений со стилем не делает. К примеру есть стиль для Android - указываем его программе, - она создает стили для Windows, Mac, iOs на основе указанного. Затем их можно добавлять в StyleBook, запускать и отлаживать этот Android стиль под Windows, что сэкономит массу времени. Exe файл находится в \Win32\Release\Styles4Platforms.exe An app to convert current firemonkey style to other platforms based on the specified *.Style file. App only changes the information about the platform and does not do any other changes with the style. Styles 4 Other Platforms.7z
    7 баллов
  25. Не обманывай людей . Это что: procedure onReceivePermissionsResult(const ASender: TObject; const AMessage: TMessage); ?
    7 баллов
  26. Год назад в одной из веток проскочила ссылка на китайский сайт (http://www.raysoftware.cn/?p=559), где предлагалось готовое решение для показа анимированных гифок средствами FireMonkey на любых платформах. Сейчас эта ссылка, как и весь сайт raysoftware.cn, упорно не открывается; по счастью, контент сохранился в гугловском кэше. Я скопировал оттуда код юнита и перевел гуглом все китайские комментарии на английский, добавив их в скобках. Там был еще сопроводительный текст, в котором автор излагал мотивы, побудившие его взяться за эту проблему; каких-то важных технических деталей я в этом тексте не увидел. Привожу весь юнит ниже и очень надеюсь, что кто-нибудь из продвинутых коллег объяснит мне, как именно этим кодом можно воспользоваться, чтобы показать пользователю анимированный файл в формате GIF. Моей программерской квалификации, к сожалению, не хватает.
    6 баллов
  27. сделано на Datasnap - 3х звенка MsSql- Сервис Https - Клиент ( Андроид, Ios, Win, Mac) Личный кабинет пациента клиники (www.familydoctor.ru) открывает зарегистрированным пользователям доступ к медицинской карте (результаты лабораторных исследований и функциональной диагностики, описание приемов врачей, направления и рекомендации, истории посещений клиники (дата, время, специалист), программам медицинского наблюдения (перечень, период прикрепления), информации о движении средств по депозитам. Для пересылки выписок (файлов) из медицинской карты используется электронная почта (в системе должен быть настроенный Майл Агент на отправку почты).Полной версией приложения могут воспользоваться только пациенты, подключившие услугу "Личный кабинет" в регистратуре любого корпуса клиники "Семейный доктор".В новой версии изменен дизайн, появились новые функции и разделы:вход по номеру медкарты или ФИО;запрос нового пароля;заявка на онлайн запись;отмена приема;прейскурант услуг клиники;справочник адресов клиники. сервис оплаты услуг клиники через приложение.В ближайшем будущем функционал личного кабинета будет дополнен онлайн расписанием специалистов, возможностью электронной записи на приём. в гугл плее https://play.google.com/store/apps/details?id=com.familydoctor.FD Есть тестовый вход, обращайтесь.
    6 баллов
  28. Это приложение для OS Windows выполняет: 1.Расчёт сцепления: -расчёт и подбор геометрических параметров нажимного и ведомого дисков, муфты выключения; -проверка параметров по теплонагруженности пар трения; -расчёт всех наиболее нагруженных деталей сцепления (пружины, пластины, подшипник). 2.Расчёт пневмогидравлического привода сцелпения: -подбор и проверка управляющего и исполнительного органов; -объём жидкости. 3.Возможность вноса и редактирования исходных данных и результатов в БД. 4.Распечатку всего расчёта с исходными данными, формулами, графиками, используемой литературой и результатами в MS Word. 5.Просмотр и изучение нажимного, ведомого дисков и муфты выключения в 3D. Изначально для работы в приложении необходимы некоторые знания конструкции сцепления и теории расчёта. Автор: Олег Киреев-ведущий инженер-конструктор, kireevoleg1966@gmail.com, +375 29 676 13 84 БЕЛАРУСЬ, г.Минск. Приму Ваши замечания и предложения. По совету Равиля Зарипова РАЗМЕСТИЛ на файлообменнике 12.08.2019г по этой: https://mega.dp.ua/a27WmeXKwY ссылке. На этом ресурсе обещают хранить 90 дней. Интересно услышать Ваши отзывы.
    6 баллов
  29. Пока тестировал хелпер в боевом проекте он потихоньку оброс исрпавлениями/улучшениями: Загрузка из потока сделана через TBitmapSurface - это позволяет избежать множества глюков. LoadFromStream вынесен из Synchronize (основного потока) в поток HTTPClient - по результатам бенчмарка операция оказалась самая жручая. После исправления интерфейс перестал залипать совсем. Добавлен overload вариант с передачей в процедуру TListItemImage - для использования в TListView и корректной перерисовки подгруженных картинок через AListItemImage.Invalidate. unit BitmapAsyncLoader; interface uses FMX.Graphics, FMX.Surfaces, System.Net.HttpClient, System.Types, System.Classes, FMX.ListView.Types, FMX.ListView.Appearances; type TBitmapAsyncLoader = class helper for TBitmap procedure LoadFromURLAsync(const AUrl : String); overload; procedure LoadFromURLAsync(const AUrl : String; const AListItemImage : TListItemImage); overload; end; implementation var AHTTPClient : THTTPClient; procedure TBitmapAsyncLoader.LoadFromURLAsync(const AURL : String); begin try AHTTPClient.BeginGet( procedure (const ASyncResult: IAsyncResult) var AHTTPResponse : IHTTPResponse; ABitmapSurface : TBitmapSurface; begin if Not ASyncResult.IsCompleted then exit; try AHTTPResponse:=THTTPClient.EndAsyncHTTP(ASyncResult); except end; if Assigned(AHTTPResponse) and (AHTTPResponse.StatusCode = 200) then begin ABitmapSurface:=TBitmapSurface.Create; if TBitmapCodecManager.LoadFromStream(AHTTPResponse.ContentStream, ABitmapSurface, CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize)) then TThread.Synchronize(Nil, procedure begin if Assigned(Self)then Assign(ABitmapSurface); ABitmapSurface.Free; end ) else ABitmapSurface.Free; end; end, AURL ); except end; end; procedure TBitmapAsyncLoader.LoadFromURLAsync(const AURL : String; const AListItemImage : TListItemImage); begin try AHTTPClient.BeginGet( procedure (const ASyncResult: IAsyncResult) var AHTTPResponse : IHTTPResponse; ABitmapSurface : TBitmapSurface; begin if Not ASyncResult.IsCompleted then exit; try AHTTPResponse:=THTTPClient.EndAsyncHTTP(ASyncResult); except end; if Assigned(AHTTPResponse) and (AHTTPResponse.StatusCode = 200) then begin ABitmapSurface:=TBitmapSurface.Create; if TBitmapCodecManager.LoadFromStream(AHTTPResponse.ContentStream, ABitmapSurface, CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize)) then TThread.Synchronize(Nil, procedure begin if Assigned(Self) and Assigned(AListItemImage) then begin AListItemImage.BeginUpdate; Assign(ABitmapSurface); AListItemImage.Invalidate; AListItemImage.EndUpdate; end; ABitmapSurface.Free; end ) else ABitmapSurface.Free; end; end, AURL ); except end; end; initialization AHTTPClient:=THTTPClient.Create; finalization if Assigned(AHTTPClient) then AHTTPClient.DisposeOf; end. Тестовый проект, на этот раз с ListView (по кнопке добавляется 100 итемов) прилагаю. BitmapAsyncLoaderListView.7z
    6 баллов
  30. Делаем как обычно, если надо переопределить какое-то событие окна interface uses {$IFDEF MSWINDOWS} Winapi.Windows, Winapi.Messages, FMX.Platform.Win, {$ENDIF} System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs; type TMainForm = class(TForm) private procedure CreateHandle; override; {$IFDEF MSWINDOWS} procedure WMIMENotify(var Msg: TMessage); message WM_IME_NOTIFY; {$ENDIF} public end; var MainForm: TMainForm; implementation {$R *.fmx} {$IFDEF MSWINDOWS} var OldWndProc: Pointer = nil; function NewWndProc(Wnd: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall; var Mess : TMessage; begin case Msg of WM_IME_NOTIFY: begin Mess.Msg := Msg; Mess.WParam := wParam; Mess.lParam := lParam; Mess.Result := 0; MainForm.Dispatch(Mess); Result := Mess.Result; end; else Result := CallWindowProc(OldWndProc, Wnd, Msg, WParam, LParam); end; end; {$ENDIF} { TMainForm } procedure TMainForm.CreateHandle; begin inherited CreateHandle; {$IFDEF MSWINDOWS} OldWndProc:= Pointer(SetWindowLong(WindowHandleToPlatform(Handle).Wnd, GWL_WNDPROC, Integer(@NewWndProc))); {$ENDIF} end; {$IFDEF MSWINDOWS} procedure TMainForm.WMIMENotify(var Msg: TMessage); begin {что-то делаем} end; {$ENDIF}
    6 баллов
  31. @Alex7wrt, устанавливают в том числе и новые пользователи на старых версиях андроида, и у них работает. minSdkVersion для этого. Что касается targetSDK, то этим значением приложение уведомляет операционку, что возможно будет использовать api вплоть до данной версии. targetSDK 27 пока не использовал, только 26, и все что надо работает. В самом коде делаю анализ текущей версии SDK, и в зависимости от нее возможно делаю дополнительные действия. Вот например, работа с правами: {$IFDEF ANDROID} // для Android 6+ требуется дополнительная работа с правами if TJBuild_VERSION.JavaClass.SDK_INT >= 23 then begin if (TAndroidHelper.context.checkSelfPermission( StringToJString(PERMISSION_FILE_READ) ) = TJPackageManager.JavaClass.PERMISSION_DENIED) or (TAndroidHelper.context.checkSelfPermission( StringToJString(PERMISSION_FILE_WRITE) ) = TJPackageManager.JavaClass.PERMISSION_DENIED) then begin // необходимо запросить разрешение на использование галереи LIsWaitPermissions := True; TAndroidHelper.Activity.requestPermissions( CreateJavaStringArray([PERMISSION_FILE_READ, PERMISSION_FILE_WRITE]), BUTTON_FILE ); end; end; {$ENDIF}
    6 баллов
  32. есть более интересный и по-мне, более правильный способ по нажатию в меню не сразу выполняете что-то, а ЗАПИСЫВАЕТЕ действие, которое ВЫПОЛНИТСЯ по событию закрытия мультивью тогда реакция наступает визуально правильная и дальше крутите колеса, запускайте потоки и все такое
    6 баллов
  33. Delphi хоронят уже лет 15, это все слова. Нет идеальных инструментов. У всех какие то косяки, втч и у нативных средств, ведь все это придумывают люди, люди не роботы. На деле Delphi отличное средство для мультиплатформенной разработки вполне сложных программ. Мне как фрилансеру вполне хватает. Производительность гораздо лучше чем у Angular\Ionic, которые по факту WebView - веб в браузере - очень тормозное решение и подходит только для формочки "логин\пароль". Также по производительности и глюкам Delphi имхо лучше чем ReactJS, и Xamarin aka Mono. Во фрилансе огромная конкуренция, в основном индусы, в этом плане с Delphi можно быстрее разработать ПО чем предлагают сроки остальные. Проблема Делфай в том что оно дорогое, и не так распространено - (это взаимосвязанный фактор) - таким образом сложно найти команду и мало проектов на нем разрабатывается, меньше сообщество и меньше документации и библиотек с готовыми решения Поэтому для одиночек это больше подходит. Но конечно нужно смотреть на развитие - вот Токио получилась очень сырым продуктом, я до сих пор на Берлине пишу под 4 платформы, если следующая версия выйдет такой же ультраглючной, то следует задуматься. А вообще хороший программист - это тот кто знает несколько языков, не бойтесь учить новое - опыт ускорит разработку с любым инструментом.
    6 баллов
  34. С помощью маски можно любую форму.TBitmap.CreateFromBitmapAndMask(). В результате получим изображение с прозрачностью, в данном случае звезда и прозрачный фон. procedure TForm1.Button1Click(Sender: TObject); var ImageRes: TResourceStream; Result: TBitmap; tmpMS : TMemoryStream; begin ImageRes := TResourceStream.Create(HInstance, 'IMAGE', RT_RCDATA); try Image1.Bitmap.CreateFromStream(ImageRes); Image2.Bitmap.LoadFromFile('c:\temp\MaskedBitmap\Images\Mask.png'); Result := TBitmap.Create; Result.CreateFromBitmapAndMask(Image1.Bitmap, Image2.Bitmap); // applying alpha channel to Bitmap - workaround. If you can improve write here how tmpMS := TMemoryStream.Create; Result.SaveToStream(tmpMS); Result.LoadFromStream(tmpMS); tmpMS.Free; Image3.Bitmap.Assign(Result); finally ImageRes.Free; Result.Free; end; end; MaskedBitmap.zip
    6 баллов
  35. Вот пример того, как писать и читать BLOB procedure SaveToFireDACBlob; var MemStream: TMemoryStream; begin FireDAC.Connected := True; MemStream := TMemoryStream.Create; try Image1.Bitmap.SaveToStream(MemStream); MemStream.Seek(0,0); FDQueryInsert.ParamByName('Media').LoadFromStream(MemStream,ftBlob); FDQueryInsert.ParamByName('MType').AsString := '0'; FDQueryInsert.ExecSQL(); except on e: Exception do begin ShowMessage(e.Message); end; end; MemStream.Free; FireDAC.Connected := False; end; procedure LoadFromFireDACBlob; var BlobStream: TStream; begin FireDAC.Connected := True; try FDQuerySelect.Open; FDQuerySelect.First; while(not FDQuerySelect.EOF)do begin // access a stream from a blob like this BlobStream := FDQuerySelect.CreateBlobStream(FDQuerySelect.FieldByName('Media'),TBlobStreamMode.bmRead); // access a string from a field like this if (FDQuerySelect.FieldByName('MType').AsString='0') then begin // load your blob stream data into a control ImageViewer.Bitmap.LoadFromStream(BlobStream); end; BlobStream.Free; FDQuerySelect.Next; end; except on e: Exception do begin //ShowMessage(e.Message); end; end; FireDAC.Connected := False; end; {источник http://www.fmxexpress.com/read-and-write-a-blob-field-using-firedac-with-firemonkey-on-android-and-ios/} Касательно работы с изменением качества/размера, считаю что необходимо использовать TBitmapSurface (unit FMX.Surfaces)
    6 баллов
  36. slav_z

    FMX: Скроллинг и нажатия

    Все разработчики при работе с FMX рано или поздно сталкиваются с одной и той же проблемой: необходимо исключить "случайное" срабатывание нажатий элементов внутри скроллбокса во время его скроллинга. Идут годы, а решения так и нет. Давайте попробуем это исправить. Поехали! Запускаем IDE, создаем новый проект, кидаем на форму TVertScrollBox и на него чего-нибудь побольше... запускаем на мобильном устройстве, пытаемся скроллировать, получаем проблемы в виде срабатывания разных событий типа OnClick элементов. Решение состоит в том, чтобы сделать элементы "невидимыми" для событий связанных с действиями пользователя с экраном во время скроллинга. Делаем следующее: Все. Переносим код в базовую форму, делаем его более гибким, убираем все те костыли, которые мы уже успели сделать ранее... Удачи! https://github.com/slav-libx/scroll-click.git
    5 баллов
  37. Линковка Kotlin (Котлин) библиотек в Delphi, как делаю: Хедеры линкуемых библиотек обычно громадны описанием всех типов... Я обычно делаю свой jar на java в нем линкую зависимости и наружу для дельфи оставляю один объект с простыми функциями. Хедер дельфи получается компактным и понятным: package com.MyCompany.evotor; public interface J2DCallback { void Log(String str); String Trans(String str); String GetValue(String name); void SetValue(String name, String value); Activity GetActivity(); Context GetContext(); } public class FiscalCoreConnection { final private Global Instance; public FiscalCoreConnection(J2DCallback aj2d) throws NullPointerException { Instance = new Global(aj2d); } public String SendJSON(String JSON){ try{ return Instance.SendJson(JSON); } catch (Exception e) { return FiscalCoreException.MakeJson(e); } } } type J2DCallbackClass = interface(IJavaClass) ['{856654D5-7939-44DF-ACD5-E2EF8C6D3AA4}'] end; [JavaSignature('com/MyCompany/evotor/J2DCallback')] J2DCallbackIntf = interface(IJavaInstance) ['{025B14E9-C041-4105-9E85-83CC127CC340}'] procedure Log(str:JString); cdecl; function Trans(str:JString):JString; cdecl; function GetValue(name:JString):JString; cdecl; procedure SetValue(name:JString; value:JString); cdecl; function GetActivity():JActivity; cdecl; function GetContext():JContext; cdecl; end; TJ2DCallbackImp = class(TJavaGenericImport<J2DCallbackClass, J2DCallbackIntf>) end; [JavaSignature('com/MyCompany/evotor/FiscalCoreConnection')] JFiscalCoreConnection = interface(JObject) ['{5797747D-D61D-4EF6-94F7-5E8994545CC2}'] function SendJSON(JSON:JString):JString; cdecl; end; JFiscalCoreConnectionClass = interface(JObjectClass) ['{81782882-DFCF-4FA9-BD37-02CCCF2409EA}'] function init(j2d : J2DCallbackIntf) : JFiscalCoreConnection; cdecl; end; TJFiscalCoreConnection = class(TJavaGenericImport<JFiscalCoreConnectionClass, JFiscalCoreConnection>) end; TJ2DCallback = class(TJavaLocal, J2DCallbackIntf) public procedure Log(str:JString); cdecl; function Trans(str:JString):JString; cdecl; function GetValue(name:JString):JString; cdecl; procedure SetValue(name:JString; value:JString); cdecl; function GetActivity():JActivity; cdecl; function GetContext():JContext; cdecl; end; Все зависимости в build.gradle: dependencies { implementation 'com.github.evotor:integration-library:v0.4.50' implementation 'com.google.zxing:core:3.4.0' } В Дереве External Libraries забираем jarы зависимостей ПКМ Show in Explorer. Копируем в папку своего проекта и даем осознанное имя. Там же забираем kotlin-stdlib ПКМ Show in Explorer. Копируем в папку своего проекта и даем осознанное имя. Но в kotlin-stdlib.jar есть "лишний" файл kotlin-stdlib-1.5.10.jar\META-INF\versions\9\module-info.class Открываем архиватором и удаляем файл или всю папку versions Почти все готово... Но котлин еще и посыпан сахаром и не хочет Дельфей dexится, хочет -min-sdk-version=26 Поможем Delphi: Ищем CodeGear.Common.Targets, у меня он в "C:\Program Files (x86)\Embarcadero\Studio\21.0\bin"\ Ищем в нем --output, и перед ним вставим все про sdk. У меня получилось так: <DxCmd>PATH $(JDKPath)\bin;$(PATH); %26 set JAVA_HOME=$(JDKPath)%26 "$(JavaDxPath)" --dex --min-sdk-version=26 --output=</DxCmd> Далее цепляем все jar в проект Либа производителя, Либа своя обертка, и котлин Иии собираем! Если есть еще зависимости делаем аналогично: находим jar, выпиливаем META-INF\versions\9\module-info.class, линкуем в проект и собираем... Не все зависимости используются и нужны, поэтому добавляем поштучно до тех пор пока не заведется.
    5 баллов
  38. gonzales

    поломались ПУШи в 10.4

    Нашел причину, В недрах класса TPushService TPushService = class abstract public type TPropPair = TPair<string, string>; TPropArray = TArray<TPropPair>; // commonly used names TServiceNames = record public const GCM = 'gcm'; // deprecated 'Is not available anymore. Please use FCM instead'; // Google cloud messaging FCM = 'fcm'; // Google Firebase cloud messaging APS = 'aps'; // Apple end; Соответственно нужно исправить FPushService := TPushServiceManager.Instance.GetServiceByName(TPushService.TServiceNames.GCM); на FPushService := TPushServiceManager.Instance.GetServiceByName(TPushService.TServiceNames.FCM); Все работает
    5 баллов
  39. krapotkin

    Не подключается Huawei

    Короче, действуем примерно так. Я надеюсь, что базовые действия - скачать google latest adb driver - мы уже провели, но наш No- или Brand- name телефон недоступен Тогда 1) идем в диспетчер устройств, находим там наше невстающее устройство, кликаем дважды, и на закладке Сведения выбираем свойство ИД оборудования. Копируем себе что-то типа 2) идем к файлам того самого драйвера, открываем android_winusb.inf находим разделы [Google.NTx86] и [Google.NTamd64] и вписываем туда, прямо в оба ;galaxy tab a 2019 %SingleAdbInterface% = USB_Install, USB\VID_04E8&PID_6866 %CompositeAdbInterface% = USB_Install, USB\VID_04E8&PID_6866&MI_01 3) делаем обновить драйвер, выбираем вариант Вручную, и указываем тот модифицированный файл если не берет автоматом, то "Выбрать из списка уже установленных..." --> "Есть диск" --> "Да, мне пофиг что он не подписан" 4) The End
    5 баллов
  40. Результат следующий Мой проект корректно работает под 1) Windows 32/64 2) Android 32/64 3) iOS 32/64 (обязательно настроить сертификаты, которые можно создать и прикрепить в Xcode + настроить их в Rad Studio в разделе Project-Deployment-Provisioning, выбрать там ключи как вы их настроили на вашем маке + ОБЯЗАТЕЛЬНО в version info удалить текст в CFBundleIdentifier, должно быть пусто) 4) MacOS 32/64 5) iOS 32/64 simulator - не работает!!!
    5 баллов
  41. Обновлена серия статей на тему использования Uses Permissions. Uses Permissions: Теория Uses Permissions: Добавляем метод onRequestPermissionsResult в приложение (для Delphi 10.1/10.2) Uses Permissions: Практика (для Delphi 10.3) Автор: Андрей Ефимов
    5 баллов
  42. Собственно понадобился подобный компонент для FMX, но готового решения найти не смог - пришлось ваять свой. Использовать проще простого: var scenaries: TDictionary<TFmxObject, string>; begin scenaries := TDictionary<TFmxObject, string>.Create; scenaries.Add(btn_1, '1 Button'); scenaries.Add(btn_2, '2 Button'); scenaries.Add(btn_3, '3 Button'); scenaries.Add(rctngl, 'Rectangle'#13#10'Rectangle'#13#10'Rectangle'#13#10'Rectangle'#13#10'Rectangle'#13#10'Rectangle'#13#10'Rectangle'); scenaries.Add(pnl_1, 'Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel'#13#10'Panel'); scenaries.Add(nil, 'Msg without target control!'); try instructor.LoadSteps(scenaries); finally FreeAndNil(scenaries); end; Репозиторий GitHub: https://github.com/ange007/TInstructor/
    5 баллов
  43. Протокол SNTP Помимо NTP, существует упрощенная версия этого протокола - SNTP (Simple Network Time Protocol). Он реализован для синхронизации времени конечным клиентом, поскольку все преимущества протокола NTP проявляются именно в сети серверов, а для получения показаний конечным пользователем NTP излишне сложен. Поэтому для синхронизации времени конечными компьютерами и серверами был предложен протокол SNTP (SNTPv3: 1992 г., RFC1361 и 1995 г., RFC1769; SNTPv4 включён как подпротокол в NTPv4). На самом деле SNTP - это не новый протокол, а способ использования NTP-пакетов и NTP-серверов в приложениях, где не требуется высокоточное время, либо оно недостижимо. В этом случае клиент использует только часть информации UDP-пакета NTP-сервера. SNTP-клиент может работать с любыми версиями NTP-серверов, и кроме них - с особыми SNTP-серверами, которые в откликах заполняют только необходимые данные UDP-пакета. Таким образом, "облегченный" SNTP образует не сеть синхронизирующихся серверов, а пары "клиент-сервер". Любой NTP-сервер является одновременно SNTP-сервером. Клиент, который не передаёт полученное время дальше, может работать как NTP- или SNTP-клиент, в зависимости от условий. Для SNTP, как и для NTP, зарезервирован 123-й UDP-порт. Uses IdSNTP, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient; .... procedure TForm1.Button2Click(Sender: TObject); Var IdSNTP: TIdSNTP; begin IdSNTP:=TIdSNTP.Create(Self); IdSNTP.Host := 'ntp1.stratum2.ru'; ShowMessage(DateTimeToStr(IdSNTP.DateTime)); IdSNTP.Free; end;
    5 баллов
  44. Тема: FGX Native. Новейшая кроссплатформенная платформа для мобильной разработки на Delphi Дата и время: 27 марта 2018 года в 12:00 Участники: @Brovin Yaroslav, Андрей Совцов Регистрация: ссылка Ссылка на официальный телеграмм канал: https://t.me/fgx_native Участие бесплатное На вебинаре познакомимся с текущей разработкой новой кроссплатформенной платформы, позволяющей создавать нативные приложения с быстрым откликом, плавной анимацией, продвинутой системой выраванивания, поддержкой RTL языков, оптимизированной работой с изображениями, быстрой канвой и многим другим. RAD Studio, Android/iOS В вебинаре принимает участие автор разработки Ярослав Бровин
    5 баллов
  45. Slym

    Артефакты на экране (Android)

    Боролись как-то с артефактами отображения (мы их прозвали "крокодилами" из-за сходства на первом скриншоте с этим багом)... Могли отображаться также левые спрайты, или обрезки скролившихся контролов... Коллега выяснил что не надо трогать Form.Fill, из-за переключения в недрах FMX нативной и не нативной канвы: если нужен фон - брось Rect по контенту и в нем делай заливку...
    5 баллов
  46. Fedor K

    JAVA и Delphi

    @Pavel M, Судя по вашей обертке класса и самой JAR: Нужно удалить все не статические методы из описания интерфейса наследуемого от JObjectClass: JUserClass = interface(JObjectClass) ['{A4B29440-8C8B-4C1F-A8E7-B7612D4FEEB4}'] function init(uuid : JString; secondName : JString; firstName : JString; inn : JString; phone : JString; pin : JString; roleUuid : JString; roleTitle : JString) : JUser; cdecl; overload; function init(uuid : JString; secondName : JString; firstName : JString; phone : JString; pin : JString; roleUuid : JString; roleTitle : JString) : JUser; cdecl; overload; end; У класса User нету конструктора по умолчанию, поэтому вызов такого кода вызовет ошибку: //неправильный вариант с ошибкой TestClass := TJUser.Create; //правильный вариант TestClass := TJUser.JavaClass.init( StringToJString('uuid'), StringToJString('secondName'), StringToJString('firstName'), StringToJString('phone'), StringToJString('pin'), StringToJString('roleUuid'), StringToJString('roleTitle') ); Если к проекту подключаете любые JAR файлы, то следите, чтобы вместе с ними были подключены и все остальные .jar библиотеки с классами, на которые ссылаются исходники. Например, в Вашем примере при вызове вышеприведенного конструктора первым делом выскочит ошибка: Вам нужно найти все такие подключения и найти сборки, в которых они валяются: Если в проекте в Android Studio включено копирование всех сторонних библиотек в папку libs, то после компиляции всего преокта практически все либы можно найти: папка libs; output папке проекта; папка Android SDK. п.с. Тему лучше перенести в раздел Android, так больше шансов получить помощь.
    5 баллов
  47. Всем привет. Смотрю сегодня тренд на публикацию приложений разработанных на Emb'e. Вот наше приложение которое тоже на днях поедет в маркеты Регаемся по номеру подтверждаем эСэМэСиной. Придумываем пин код и подтверждаем его После входа приложение покажет магазины в радиусе 500м Заходим в меню магазина Выбираем категорию для жалобы ---- жалуемся , если надо прикладываем фото Еще кое что подтверждаем отправку жалобы PROFIT!
    5 баллов
  48. С++ ваше всё, наше всё Делфи
    5 баллов
  49. Как я понимаю модуль FMX.FontGlyphs.Android.pas подключен из Берлинской версии студии. Вам нужен этот файлик для Токио. Как я понимаю, используете что-то типа FontAwesome. Например, на гитхабе Равиля этот файл есть версии и для Берлин и для Токио.
    5 баллов
Эта таблица лидеров рассчитана в Москва/GMT+03:00
×
×
  • Создать...