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

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

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

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

  • Посещение

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

    100

Весь контент Евгений Корепов

  1. Прикрепил тестовый проект на котором воспроизводится ошибка. Код дублирую для наглядности: 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.ScrollBox, FMX.Memo, FMX.Controls.Presentation, FMX.StdCtrls, System.Net.HTTPClient, System.Net.Mime, System.Net.URLClient; type TFormMain = class(TForm) ButtonPost: TButton; Memo: TMemo; procedure FormCreate(Sender: TObject); procedure ButtonPostClick(Sender: TObject); private { Private declarations } FHTTPClient: THTTPClient; FMultipartFormData : TMultipartFormData; HTTPResponse: IHTTPResponse; procedure HTTPClientValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; const Certificate: TCertificate; var Accepted: Boolean); public { Public declarations } end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); begin FHTTPClient:=THTTPClient.Create; FHTTPClient.HandleRedirects:=False; FHTTPClient.AllowCookies:=True; FHTTPClient.MaxRedirects:=3; FHTTPClient.Accept:='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'; FHTTPClient.AcceptEncoding:='gzip, deflate'; FHTTPClient.AcceptLanguage:='ru,en-US;q=0.8,en;q=0.6'; FHTTPClient.ContentType:='application/x-www-form-urlencoded'; FHTTPClient.UserAgent:='Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36'; FHTTPClient.OnValidateServerCertificate:=HTTPClientValidateServerCertificate; FMultipartFormData:=TMultipartFormData.Create; FMultipartFormData.AddField('action','login'); FMultipartFormData.AddField('id_domain', '21'); FMultipartFormData.AddField('login', '102355555'); FMultipartFormData.AddField('password', 'n7icyq34783q'); end; procedure TFormMain.ButtonPostClick(Sender: TObject); Var ALocation : String; begin try HTTPResponse:=FHTTPClient.Post('https://cabinet.komiesc.ru/cabinet',FMultipartFormData); except on E : Exception do begin if Not (E.Message.Contains('302') or E.Message.Contains('403')) then begin Memo.Lines.Add(E.Message); Exit; end; end; end; // Код ниже можно игнорировать, это обработка редиректов при удачной авторизации if Assigned(HTTPResponse) then begin if HTTPResponse.StatusCode=302 then begin HTTPResponse.Headers; HTTPResponse.Date; FreeAndNil(FMultipartFormData); FMultipartFormData:=TMultipartFormData.Create; ALocation:=HTTPResponse.HeaderValue['Location']; ALocation:='https://cabinet.komiesc.ru/input_controlchecks'; ALocation:='http://cabinet.komiesc.ru/input_controlchecks'; if Not ALocation.IsEmpty then begin HTTPResponse:=FHTTPClient.Post('https://cabinet.komiesc.ru/input_controlchecks', FMultipartFormData); Memo.Lines.Text:=HTTPResponse.ContentAsString; end; end; end; end; procedure TFormMain.HTTPClientValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; const Certificate: TCertificate; var Accepted: Boolean); begin Accepted:=True; end; end. test061 https.7z
  2. Вопрос решился по другому - доступ по http тоже работает, никакого принудительного перевода на https. На ФЗ "О персональных данных" видимо плевать с большой колокольни...
  3. Есть сайт просроченным сертификатом безопасности (госконтора, такое у них в порядке вещей), сертификат могут обновить завтра, а могут и через год, но работать с ним надо. Var HTTPClient: THTTPClient; HTTPResponse: IHTTPResponse; begin HTTPClient:=THTTPClient.Create; HTTPClient.OnValidateServerCertificate:=HTTPClientValidateServerCertificate; ..... try HTTPResponse:=HTTPClient.Post(FHTTPRec.Query,FHTTPRec.PostData); except on E : Exception do begin FHTTPRec.ErrorCode:=-1; FHTTPRec.ErrorMsg:=E.Message; end; ..... end; procedure THTTPThread.HTTPClientValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; const Certificate: TCertificate; var Accepted: Boolean); begin Accepted:=True; end; Под Windows код работает идеально - вызывается HTTPClientValidateServerCertificate, где принудительно доверяем сертификату. Под Андроид HTTPClientValidateServerCertificate или игнорируется, или до процедуры не доходит. Получаю ошибку: First chance exception at $A06ECCE5. Exception class EJNIException with message 'java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.'. Process tratata.apk (25487) First chance exception at $A0EA44F5. Exception class ENetHTTPCertificateException with message 'Server Certificate Invalid or not present'. Process tratata.apk (25487) Как победить проблему? P.S. До этого проект работал на Indy, там подобные проблемы успешно игнорировались. Но решил перевести все на THTTPClient и вот результат :-(
  4. Да ошибка подтвердилась. MaxImageSize=4096, но ABitmap.Assign(ABitmapSurface) выдает ошибку "Bitmap size too big" при загрузке картинки 250x250 Больше идей у меня нет...
  5. А где можно купить 10.1? В онлайн магазинах только 10 и ни слова о подписке. Что то маркетинг не изменился и остался в стиле "давай перетрём темку за гаражами по емайлу". Хочется по человечески выбрать нужные продукты с ценой в рублях и оплатить, а не получать письма типа такого;
  6. К сожалению я рано радовался. Три недели тестов показали что ошибка "Bitmap size too big" продолжает появляться у не значительной части пользователей. Вышеприведенный код по видимому работает. Но ошибка появляется там где размер изображения заведомо меньше GetMaxImageSize end Else if Assigned(ABitmap) then ABitmap.Assign(ABitmapSurface); // Вот здесь ошибка Продолжаю наблюдение...
  7. Ура! Заработало с TBitmapSurface.StretchFrom : ABitmapSurface:=TBitmapSurface.Create; ABitmapSurfaceResize:=TBitmapSurface.Create; TBitmapCodecManager.LoadFromFile('d:\source.png',ABitmapSurface); // png 250x250 MaxImageSize:=50; ABitmapSurfaceResize.StretchFrom(ABitmapSurface,MaxImageSize,MaxImageSize); TBitmapCodecManager.SaveToFile('d:\source_resize.png', ABitmapSurfaceResize); Все работает отменно :-) Итоговый код для загрузки картинки из потока и устранения ошибки "Bitmap size too big": Uses FMX.Graphics, FMX.Surfaces; function GetMaxImageSize : Integer; begin Result:=TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize); end; procedure CheckAndLoadFromStream(const AStream : TStream; const ABitmap : TBitmap); Var MaxImageSize : Integer; ABitmapSurface,ABitmapSurfaceResize : TBitmapSurface; begin ABitmapSurface:=TBitmapSurface.Create; AStream.Position:=0; TBitmapCodecManager.LoadFromStream(AStream,ABitmapSurface); MaxImageSize:=GetMaxImageSize; if ABitmapSurface.Height>MaxImageSize then begin ABitmapSurfaceResize:=TBitmapSurface.Create; ABitmapSurfaceResize.StretchFrom(ABitmapSurface,MaxImageSize,MaxImageSize); if Assigned(ABitmap) then ABitmap.Assign(ABitmapSurfaceResize); ABitmapSurfaceResize.Free; end Else if Assigned(ABitmap) then ABitmap.Assign(ABitmapSurface); ABitmapSurface.Free; end; Всем спасибо за помощь! Особая благодарность Ярославу! P.S. Процедура для частного случая с квадратным изображением. Для меня осталось не до конца ясным значение возвращаемое TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize), исходил из догадки что это максимальный размер изображения по вертикали в пикселях. Может Ярослав поставит все точки и разъяснит этот вопрос?
  8. Сам себе отвечаю, процедура procedure TBitmapSurface.SetSize(const AWidth, AHeight: Integer; const APixelFormat: TPixelFormat), судя по коду: procedure TBitmapSurface.SetSize(const AWidth, AHeight: Integer; const APixelFormat: TPixelFormat); var NumOfBytes: Integer; begin FPixelFormat := APixelFormat; if FPixelFormat = TPixelFormat.None then FPixelFormat := TPixelFormat.BGRA; FBytesPerPixel := PixelFormatBytes[FPixelFormat]; FWidth := Max(AWidth, 0); FHeight := Max(AHeight, 0); FPitch := FWidth * FBytesPerPixel; NumOfBytes := FWidth * FHeight * FBytesPerPixel; ReallocMem(FBits, NumOfBytes); FillChar(FBits^, NumOfBytes, 0); end; изменяет размер и просто забивает нулями содержимое Bitmap. Пойду копать дальше...
  9. Огромное вам спасибо! Стало много понятнее. Повторюсь: картинки 250х250 png. Сделал процедуру: Uses FMX.Graphics, FMX.Surfaces, FMX.Types; function GetMaxImageSize : Integer; begin Result:=TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize); end; procedure CheckAndLoadFromStream(const AStream : TStream; const ABitmap : TBitmap); Var MaxImageSize : Integer; ABitmapSurface : TBitmapSurface; begin ABitmapSurface:=TBitmapSurface.Create; AStream.Position:=0; TBitmapCodecManager.LoadFromStream(AStream,ABitmapSurface); MaxImageSize:=GetMaxImageSize; // MaxImageSize:=64; if ABitmapSurface.Height>MaxImageSize then ABitmapSurface.SetSize(MaxImageSize,MaxImageSize,ABitmapSurface.PixelFormat); if Assigned(ABitmap) then ABitmap.Assign(ABitmapSurface); ABitmapSurface.Free; end; Все отлично работает, до момента раскоментирования строчки "MaxImageSize:=64" (имитация слабого устройства) - процедура ABitmapSurface.SetSize устанавливает новый размер, но изображение при этом теряется, на форме, в TImage пустота. Видимо я что то не так делаю :-( Перебрал все возможные ABitmapSurface.PixelFormat - результата нет. Следующий код ABitmapSurface:=TBitmapSurface.Create; TBitmapCodecManager.LoadFromFile('d:\source.png',ABitmapSurface); MaxImageSize:=250; ABitmapSurface.SetSize(MaxImageSize,MaxImageSize); TBitmapCodecManager.SaveToFile('d:\source_resize.png', ABitmapSurface); Из файла source.png размером 79642 байта делает файл source_resize.png размером 351 байт. Изображение исчезает. Что я делаю не так? Заранее благодарю за ответ!
  10. На тестовом устройстве с помощью кода Var MaxWidthHeight: Integer; begin MaxWidthHeight := TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize); получаю значение 4096. В каких попугаях это число? Судя по MaxWidthHeight это высота изображения? Как получить тогда ширину? Или его размер в байтах? Хотя это врядли, на этом устройстве успешно загружаются картинки в 200 килобайт. Подскажите наиболее правильный путь в моей ситуации - на форме лежит TImage и нужно загрузить в него картинку: Проверять максимальный размер картинки, если загрузить не удастся, то отлупливать пользователя фразой "Нищебродам вход воспрещен". Переписать класс TImage на использование TBitmapSurface вместо TBitmap Загружать картинку сначала в TBitmapSurface, изменять размер и копировать в визуальный Image.Bitmap. Вот тут облом - если не ошибаюсь TBitmapSurface не умеет абсолютно ничего, никаких LoadFromStream (как в него вообще загрузить внешнее изображение?) только readonly свойства и методы.
  11. В приложении можно раз в секунду включать вибрацию, а в сервисе читать сенсор движения ;-) Способ шуточный, но абсолютно работоспособный :-) А вообще в Uses SyncObjs есть TMutex и с Андроидом он дружит. Отпишитесь если удастся применить.
  12. На незначительном количестве устройств, менее 0,1%, получаю ошибку "Bitmap size too big" при AImage.Bitmap.LoadFromStream(AMemoryStream). Подозреваю что ошибка происходит на слабых устройствах. Картинка 250х250 png. Код выполняется в основном потоке (в интернетах были упоминания что глючит эта операция в отдельном потоке на каких то версиях Delphi). Как предотвратить подобное? Можно как то определить максимальный размер картинки для текущего устройства? Или может дело не в свободной памяти, а в чем то еще?
  13. Так вышло, что моё хобби - программирование на Delphi, стало приносить деньги. Хочу честно заплатить подоходный налог, как физическое лицо. Поделитесь опытом кто этим занимался. На данный момент удалось выяснить что при подаче декларации заполняется Лист Б (доходы за рубежом), но налоговая требует заполнения каждой транзакции, ладно у меня их несколько десятков, а если тысячи? Фуру заказывать для перевозки декларации? Так же обязательно нужен ИНН и если не ошибаюсь КПП зарубежных организаций, где их взять? Хотя бы Гугла и его AdMod? Так же налоговая требует справку НДФЛ2 приложить к декларации, хотя она уже у них есть - собственноручно отправлял с основного места работы. Забавно что сами работники налоговой смотрят как на дурака и в приватных разговорах рекомендуют забить на это дело ;-)
  14. Fonepad Fonepad 7 Fonepad 8 Fonepad ME371MG Fonepad Note 6 Lenovo Mobile K900 Lenovo TAB S8 MeMO Pad 7 MeMO Pad 8 MeMO Pad FHD 10 MeMO Pad ME181CX Transformer AiO P1801 P1801-T Transformer AiO P1802 P1802-T Transformer Pad (TF103C) K010 Transformer Pad (TF103C) K010_3 Transformer Pad (TF103CE) K010E Transformer Pad (TF103CE) K010E_1 Transformer Pad (TF103CG) K018 Transformer Pad (TF303CL) K014 Transformer Pad (TF303K) K01B Transformer Pad Infinity (TF701T) K00C Transformer Pad Infinity TF700KL Transformer Pad K010_1 Transformer Pad TF300T TF300T Transformer Pad TF300TG TF300TG Transformer Pad TF300TL TF300TL Transformer Pad TF502T TF502T Transformer Pad ‏(TF103C) Transformer Pad ‏(TF103CG) Transformer Pad ‏(TF303CL) Venue 7 VivoTab Note 8 ‏(M80TA) Xolo_X900 ZenFone 2 (ZE500CL) ASUS_Z00D ZenFone 2 (ZE550ML) Z008_1 ZenFone 2 (ZE551ML) Z00A ZenFone 2 (ZE551ML) Z00A_1 ZenFone 2 ‏(ZE550ML) ZenFone 2 ‏(ZE551ML) ZenFone 4 (A400CG) ASUS_T00I ZenFone 4 (A450CG) ASUS_T00Q ZenFone 4 ‏(A400CG) ZenFone 4 ‏(A450CG) ZenFone 5 (A500CG) ASUS_T00F1 ZenFone 5 (A501CG) ASUS_T00J1 ZenFone 5 (A502CG) ASUS_T00K ZenFone 5 ASUS_T00F ZenFone 5 ASUS_T00J ZenFone 5 ‏(A501CG) ZenFone 5 ‏(A502CG) ZenFone 6 (A600CG) ASUS_T00G ZenFone 6 (A601CG) ASUS_Z002 ZenFone 6 ‏(A600CG) ZenFone C (ZC451CG) ASUS_Z007 ZenFone C ‏(ZC451CG) Zenfone Go (ASUS_Z00SD) ASUS_Z00SD Zenfone Go (ASUS_Z00VD) ASUS_Z00VD Zenfone GO ASUS_X013D_1 Zenfone GO ASUS_X013D_2 Zenfone GO ASUS_X014D_1 Zenfone GO ASUS_X014D_2 Zenfone MAX (ZC550KL) ASUS_Z010 ZenFone Selfie (ZD551KL) ASUS_Z00U_1 ZenFone Selfie (ZD551KL) ASUS_Z00U_2 ZenFone Zoom ZenFone Zoom (ZX551ML) Z00X ZenFone Zoom (ZX551ML) Z00X_1 ZenFone Zoom ‏(ZX551ML) ZenPad 10 (Z300C) P023_1 ZenPad 10 (Z300C) P023_2 ZenPad 10 (Z300CG) P021 ZenPad 10 (Z300CG) P021_1 ZenPad 10 (Z300CL) P01T_1 ZenPad 7.0 (Z370C) P01W ZenPad 7.0 (Z370CG) P01V_1 ZenPad 7.0 (Z370CG) P01V_2 ZenPad 7.0 (Z370KL) P002_2 ZenPad 7.0(Z370KL) P002_1 Zenpad 8 LTE P024_2 Zenpad 8 LTE P024_3 Zenpad 8 LTE P024_4 Zenpad 8.0 (Z380C) P022_1 Zenpad 8.0 (Z380C) P022_2 Zenpad 8.0 (Z380KL) P024_1 ZenPad C 7.0 (Z170C) P01Z ZenPad C 7.0 (Z170C) P01Z_2 ZenPad C 7.0 (Z170CG) P01Y ZenPad C 7.0 (Z170CG) P01Y_2 ZenPad C 7.0 (Z170MG) P001 ZenPad C 7.0 (Z170MG) P001_2 ZenPad C 7.0 P01Y_S ZenPad S 8.0 ZenPad S 8.0 (Z580C) P01M_2 ZenPad S 8.0 (Z580CA) P01M_1 ZenPad S 8.0 (Z580CA) P01M_3 ZenPad S 8.0 ‏(Z580CA)
  15. Проблема решена. Но решена методом научного тыка. Сделал так: ATabItem:=TabControl.Add(); ATabItem.DisableDisappear:=True; и задержка исчезла совсем. Так же убрал все рекурсивные предварительные ApplyStyleLookup, тоже работает идеально. Help и сайты с документацией молчат по поводу DisableDisappear - это свойство науке не известно. По крупицам собраны сакральные знания,позволяют догадываться что отвечает оно за "запрет контролу выгружать стиль, когда он скрывается со сцены (С) Brovin Yaroslav"
  16. Добавлю еще одно важное наблюдение - смена табов без спецэффектов, с помощью TabControl.Next(TTabTransition.None,TTabTransitionDirection.Normal), не приводит к задержке при первой смене, все отрабатывается мгновенно.
  17. К сожалению это решение не помогает. Я это попробовал первым делом, включая не только ApplyStyleLookup, но и Repaint и все что смог применить к контролам. Задержка осталась на месте. Все таки причина видимо в анимации - подозреваю что задержка вызвана созданием и инициализацией объектов анимации. Вот только как до них добраться? Пойду ковырять исходники...
  18. Заметил в нескольких своих приложениях странное поведение TTabControl на Андроиде - первое переключение табов c TTabTransition.Slide вызывает фриз отсновного потока приложения примерно на секунду. Не зависит от содержания табов. Не зависит от метода создания табов и табконтрола. Последующие смены табов проходят гладко. Можно как нибудь передернуть заранее механизм анимации (думаю в нем причина)?
  19. Вот здесь, в самом низу вроде все расписано http://docwiki.embarcadero.com/RADStudio/XE8/en/Using_an_HTTP_Client#Handling_Client-side_Certificates Handling Server-side Certificates If the server provides an SSL certificate, but this certificate is invalid, the OnValidateServerCertificate event occurs. Provide an event handler for OnValidateServerCertificate so that you can check the server certificate (Certificate) and determine whether or not you accept the server certificate. If you accept the server certificate, change the value of the Accept parameter to True. Handling Client-side Certificates If the server requires a client certificate, the OnNeedClientCertificate event occurs. Provide an event handler for OnNeedClientCertificate so that you can check your list of client certificates (ACertificateList), and determine which certificate you want to send to the server. To send a given certificate from the list, change the value of AnIndex to the index of the target certificate in ACertificateList. Note: If the HTTP method of the first request to a server that requires a client-side certificate is not either HEAD or GET (e.g. it is POST), the status code of the server response is 413. Always send a HEAD or GET request first. Using a HEAD request is usually a better choice, since less data is transferred. А вообще зачем вам возня с сертификатами? Просто делайте Accept:=True в OnValidateServerCertificate если доверяете серверу и все. Трафик будет шифроваться. Или вы пытаетесь авторизацию сделать и сервер будет требовать клиентский сертификат?
  20. Задача следующая: есть ListView настроенный в дизайнтайме, во время работы приложения необходимо создавать в runtime и использовать несколько копий ListView. В каждом будет свой контент. Не могу придумать элегантное решение. Первый вариант - тупо создавать в runtime и кучей кода настраивать ListView до нужного состояния. Но это лениво ;-) Второй вариант - оставить в приложении настроенный вручную ListView и клонировать его по мере надобности, как то так наверное ListViewDestination.Assign(ListViewSource) ? Третий вариант - сериализация настроек и загрузка их в новые экземпляры ListView. Заранее благодарю за совет.
  21. Видимо из за наличия эпизодической эмуляции арма на Intel Atom, гугль решил что Intel Atom не совсем x86...
×
×
  • Создать...