Перейти к содержанию

Tumaso

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

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

  • Посещение

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

    21

Активность репутации

  1. Like
    Tumaso получил репутацию от Ingalime в Не помпилируеться под Ios   
    Не, этот патч устанавливается на всё, от delphi 1 до 10.3.3. И не важно, что это патч исключительно для 10.4.1))))
  2. Like
    Tumaso получил репутацию от Ingalime в XSuperObject   
    Скажи, а зачем вообще использовать библиотеку, которая не развивается?
  3. Like
    Tumaso выдал репутацию gonzales в закодировать строку в UTF8 для передачи в GET запросе   
    Переделал только немного под себя, чтобы строку в ответ выдавал
    function TForm1.Get(const ASession: TIdHTTP; const AUrl: string):string; begin result:=ASession.Get(ASession.URL.URLEncode(AUrl)); end;  
  4. Like
    Tumaso получил репутацию от gonzales в закодировать строку в UTF8 для передачи в GET запросе   
    попробуй вот так:
     
    procedure Get(const ASession: TIdHTTP; const AUrl: string; const AResult: TStringStream); begin ASession.Get(ASession.URL.URLEncode(AUrl), AResult); end; где AUrl - твой урл с параметрами
  5. Like
    Tumaso получил репутацию от Ingalime в После обновления на Андроид 6.01   
    а причем тут способ доступа к серверу FTP, если проблема в записи в локальный файл? Кто его знает, какой там у вас код записи.
    UPD. Может быть проблема и не в записи, а в сетевом доступе. Под отладкой вообще запускали?
  6. Thanks
    Tumaso получил репутацию от Ingalime в [Android]RAD10.4.1   
    @Ingalime
    у меня в 10.4.1 sdk лежит в C:\Users\Public\Documents\Embarcadero\Studio\21.0\CatalogRepository\AndroidSDK-2525-21.0.38860.1461 (так инсталлятор установил), соответственно всё лежит там, включая Android SDK Manager
    в 10.3.3 sdk лежит в C:\Users\Public\Documents\Embarcadero\Studio\20.0\PlatformSDKs\android-sdk-windows
  7. Like
    Tumaso выдал репутацию krapotkin в После обновления на Андроид 6.01   
    на всех андроид устройствах нет смысла пользоваться прямым указанием папки
    доступные программе папки перечислены в class TPath из System.IOUtils.pas
    пример
    uses System.IOUtils; fname := TPath.combine(TPath.GetDocumentsPath, 'myfile.txt');  
  8. Like
    Tumaso получил репутацию от Ingalime в А не сделать ли уроки по стилям FMX for free?   
    Да, для десктопных приложений курс до сих пор актуален, убеждаюсь по переходящим из VCL и задающим кучу одних и тех же вопросов. А FGX Native увы только для Android и (скоро) для iOS.
  9. Like
    Tumaso выдал репутацию Yarpda в А не сделать ли уроки по стилям FMX for free?   
    Заметил что ссылка на уроки по стилям FMX уже не доступна. Как я понял Ярослав не планирует больше продавать эти уроки, т.к. ушел в FGX Native, но по сути там довольно интересный материал (я их проходил в свое время и много раз использовал то, что узнал на них), и раз он уже не продается, может быть сделать доступ к этим урокам бесплатным? Я полагаю это могло бы популяризировать FMX. Там действительно без бутылки видео-уроков не разберешься
  10. Like
    Tumaso выдал репутацию OnePeople в Программное одноразовое применение InnerGlowEffect к изображению   
    Поздно, но может кому пригодится
    function TForm1.Blur(sbit: TBitmap): TBitmap; var   FilterClass: TFilterClass;   FFilter: TFilter;   FFilterParams: TFilterRec;   BitmSource, BitmDest: TBitmap; begin       BitmSource:=TBitmap.Create;       BitmSource.Assign(sbit);       Result:=TBitmap.Create;       FFilter := TFilterManager.FilterByName('GaussianBlur');       FilterClass := TFilterManager.FilterClassByName('GaussianBlur');       FFilterParams := FilterClass.FilterAttr;       FFilter.ValuesAsFloat['BlurAmount']:=5.7;       FFilter.Apply;       FFilter.ValuesAsBitmap['Input'] := BitmSource;       Result.Assign(FFilter.ValuesAsBitmap['output']);       FreeAndNil(FFilter);       FreeAndNil(BitmSource); end; function TForm1.Tint(sbit: TBitmap; tintColor: TAlphaColor): TBitmap; var   FilterClass: TFilterClass;   FFilter: TFilter;   FFilterParams: TFilterRec;   BitmSource, BitmDest: TBitmap; begin       BitmSource:=TBitmap.Create;       BitmSource.Assign(sbit);       Result:=TBitmap.Create;       FFilter := TFilterManager.FilterByName('FillRGB');       FilterClass := TFilterManager.FilterClassByName('FillRGB');       FFilterParams := FilterClass.FilterAttr;       FFilter.ValuesAsColor['Color']:=tintColor;       FFilter.Apply;       FFilter.ValuesAsBitmap['Input'] := BitmSource;       Result.Assign(FFilter.ValuesAsBitmap['output']);       FreeAndNil(FFilter);       FreeAndNil(BitmSource); end;  
  11. Like
    Tumaso получил репутацию от Ingalime в [Android] Воспроизводить аудио   
    А причем тут твой фаервол? Вопрос совсем о другом, о принципиальной возможности  воспроизведения аудиопотока с указаного адреса/порта в FMX
    Стандартный TMediaPlayer из FMX полное убожесто, не работает нормально даже в 10.4.1, поэтому про него можно забыть. Если еще кто то в него верит и надеется на чудо.
    Теоретически это могут делать FFMPEG VCL (поддерживает и FMX) и Alcinoe
  12. Like
    Tumaso выдал репутацию slav_z в Расположение нажатого элемента управления по отношению к экрану   
    не ClientToScreen а LocalToScreen... оно есть у фрейма...
    Пример:
    LocalToScreen(TPointF.Zero) - левый верхний угол фрейма в координатах экрана,
    LocalToAbsolute(TPointF.Zero) - левый верхний угол фрейма в координатах формы.
     
  13. Thanks
    Tumaso получил репутацию от Ingalime в Посоветуйте компонет   
    @Ingalime
    1. если высота фрейма зависит от данных, то да, вычисляйте высоту
    2. по расположению создаваемых фреймов друго под другом - самый простой вариант использовать свойство Align у фреймов (устанавить в Top), для этого размещайте создаваемые фреймы на общем контейнере для них (например на VertScrollBox)
    условно говоря примерно так:
    procedure TForm1.AddFrame(const AParent: TFmxObject; const AData: TFrameData); var LFrame: TMyFrame; begin LFrame := TMyFrame.Create(Self); // или nil, если в дальнейшем будете сами уничтожать фреймы LFrame.Parent := AParent; LFrame.Align := TAlignLayout.Top; LFrame.Data := AData; // этим кодом предполагается заполнение фрейма данными, при котором фрейм заполнит выводимые компоненты и настроит свою высоту end; procedure TForm1.FillFrames; var I: Integer; begin for I := 0 to Data.Count - 1 do AddFrame(vsbFrames, Data[I]); // vsbFrames - TVertScrollBox для размещения фреймов, Data - список данных для отображения, каждый элемент - данные для отдельного фрейма end;  
  14. Like
    Tumaso выдал репутацию krapotkin в Гибкие аналоги TListBox и TListView   
    вот мой вариант со свистелками
  15. Like
    Tumaso получил репутацию от Ingalime в Гибкие аналоги TListBox и TListView   
    Почему вы решили, что стандартный TListView не подойдет? Прекрасно подойдет.
    Посмотрите демо, идущее с делфи, в каталоге C:\Users\Public\Documents\Embarcadero\Studio\версия\Samples\Object Pascal\Multi-Device Samples\User Interface\ListView\VariableHeightItems. Для вашей задачи - идеальный старт
  16. Thanks
    Tumaso получил репутацию от Ingalime в Посоветуйте компонет   
    Другой вариант - использование TListView
  17. Thanks
    Tumaso получил репутацию от Ingalime в Посоветуйте компонет   
    Я бы сделал шаблонный фрейм, в котором бы выводил текст с помощью TText (или TLabel или другой), если нужно выводить картинки - TImage и т.д.
    Далее для каждой карточки создаете свой экземпляр фрейма и в качестве параметров передаете значения отображаемых полей.
    Легко в реализации, гибко, работает на всех платформах, включая Linux через FmxLinux
     
  18. Like
    Tumaso получил репутацию от Ingalime в TMapView маркер при старте   
    ImageLocationSample это банально TImage, в котором я храню изображение маркера - заказчик хотел, чтобы маркеры отображались в его корпоративном стиле
    у меня был загружен в TImage как .png
  19. Thanks
    Tumaso получил репутацию от Ingalime в TMapView маркер при старте   
    Я делал так, маркер устанавливался в заданную позицию при создании:
    var LLocation: TMapCoordinate; LMarker: TMapMarkerDescriptor; LLocation := TMapCoordinate.Create(DEFAULT_LATITUDE, DEFAULT_LONGITUDE); LMarker := TMapMarkerDescriptor.Create(LLocation, 'Название метки'); LMarker.Icon := ImageLocationSample.Bitmap; MapView.AddMarker(LMarker); MapView.Zoom := DEFAULT_ZOOM; где DEFAULT_LATITUDE и DEFAULT_LONGITUDE это мои константы с нужной координатой маркера
  20. Like
    Tumaso выдал репутацию slav_z в Разработка кросплатформенных приложений в одном проекте   
    ну как так то? условная компиляция! посмотрите в исходных кодах дельфи... там куча примеров...  КУЧА!!!

     
  21. Like
    Tumaso выдал репутацию Евгений Корепов в Создание сервиса (демона) нового стиля для Linux   
    В прошлой теме я показал как делать демонов старой школы - серьезных и самодостаточных. Но это все в прошлом. Теперь существуют системы управления процессами, где все намного, намного проще.
    Исходники тут https://github.com/EvgeniyKorepov/LinuxDaemonNewStyle
    Заметьте, теперь никаких потоков, все элементарно, systemd сделает всю работу за нас.
    Половина кода - разбор параметров командной строки. Вторая половина - бесконечный цикл, ожидающий сигналов от экземпляра класса демона нового стиля . Код самого класса сократился на треть.
    Если запустите приложения в консоли - будет самое обычное приложение, которые умрет при закрытии консоли. Запуск в качестве бессмертного демона - через systemd, причем он сможет автоматически перезапускать вашего демона при крахе. Эти параметры задаются в текстовом файле /etc/systemd/system/DaemonNewStyleTest.service
    program DaemonNewStyleTest; {$APPTYPE CONSOLE} uses System.SysUtils, System.IOUtils, System.SyncObjs, Posix.Stdlib, Posix.SysStat, Posix.SysTypes, Posix.Unistd, Posix.Signal, Posix.Fcntl, Posix.Syslog in 'Posix.Syslog.pas', UnitDaemonNewStyle in 'UnitDaemonNewStyle.pas'; var AEvent : TEventType; begin if ParamCount = 0 then begin syslog(LOG_ERR, 'No parameters'); ExitCode := EXIT_FAILURE; exit; end; if ParamStr(1).ToLower.Equals('stop') then begin if Daemon.Stop(30) then ExitCode := EXIT_SUCCESS else ExitCode := EXIT_FAILURE; exit; end; if ParamStr(1).ToLower.Equals('reload') then begin if Daemon.Reload() then ExitCode := EXIT_SUCCESS else ExitCode := EXIT_FAILURE; exit; end; if not ParamStr(1).ToLower.Equals('start') then begin syslog(LOG_ERR, 'Unknow parameters'); ExitCode := EXIT_FAILURE; exit; end; syslog(LOG_NOTICE, 'main START'); while Daemon.IsRunning do begin syslog(LOG_NOTICE, 'main LOOP'); Daemon.Execute(AEvent); if AEvent <> TEventType.None then syslog(LOG_NOTICE, 'main Daemon receive signal'); case AEvent of TEventType.Start : begin syslog(LOG_NOTICE, 'main Event START'); end; TEventType.Reload : begin // Reload config syslog(LOG_NOTICE, 'main Event RELOAD'); end; TEventType.Stop : begin syslog(LOG_NOTICE, 'main Event STOP'); ExitCode := EXIT_SUCCESS; Sleep(10); // simulate destroy delay break; end; end; Sleep(1000); end; end. systemctl start DaemonNewStyleTest.service systemctl reload DaemonNewStyleTest.service systemctl stop DaemonNewStyleTest.service  
  22. Like
    Tumaso получил репутацию от Ingalime в Требуется приложение на на все смартфоны   
    @Sashar333
    если вы из потока меняете визуальные компоненты в основном потоке приложения, то вам нужно оборачивать изменения визуальных компонентов в синхронизацию.
    А правильнее будет в потоке получить только данные, а созданием компонентов и их заполнением должен заниматься главный поток. Т.е. в потоке считываете данные в TStringList, а код парсинга этого текста переносите в форму
  23. Like
    Tumaso выдал репутацию Евгений Корепов в Создание сервиса (демона) в Linux   
    Я написал класс для демонизации приложения в linux. Класс форкает процесс, обрабатывает поступающие сигналы и передает их в основной поток через потокобезопасную очередь.
    Исходники https://github.com/EvgeniyKorepov/LinuxDaemon
    Для использования просто подключите модуль UnitDaemon в свое консольное приложение:
    program DaemonTest; {$APPTYPE CONSOLE} uses System.SysUtils, System.IOUtils, System.SyncObjs, Posix.Stdlib, Posix.SysStat, Posix.SysTypes, Posix.Unistd, Posix.Signal, Posix.Fcntl, Posix.Syslog in 'Posix.Syslog.pas', UnitDaemon in 'UnitDaemon.pas'; var AEventType : TEventType; begin syslog(LOG_NOTICE, 'main START'); while True do begin syslog(LOG_NOTICE, 'main LOOP'); if UnitDaemon.QueueEvent.PopItem(AEventType) = System.SyncObjs.TWaitResult.wrSignaled then begin syslog(LOG_NOTICE, 'main UnitDaemon.QueueEvent.PopItem'); case AEventType of TEventType.StopProcess : begin syslog(LOG_NOTICE, 'main Event StopProcess'); ExitCode := EXIT_SUCCESS; exit; end; TEventType.Start : begin syslog(LOG_NOTICE, 'main Event START'); end; TEventType.Reload : begin // Reload config syslog(LOG_NOTICE, 'main Event RELOAD'); end; TEventType.Stop : begin syslog(LOG_NOTICE, 'main Event STOP'); ExitCode := EXIT_SUCCESS; exit; end; end; end; Sleep(50); end; end. Так же поддерживается systemd - для этого положите  DaemonTest.service в /etc/systemd/system/ и используйте :
    systemctl start DaemonTest.service systemctl reload DaemonTest.service systemctl stop DaemonTest.service  
  24. Like
    Tumaso выдал репутацию 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
     
  25. Like
    Tumaso выдал репутацию krapotkin в Свой APK updater. Использование Fileprovider   
    У меня в работе два приложения, и оба они не предназначены для 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.
    Для того, чтобы системный инсталлер запускался, нужно не забыть отметить еще одну галочку

     
     
     
     
     
×
×
  • Создать...