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

Alex7wrt

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

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

  • Посещение

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

    31

Сообщения, опубликованные Alex7wrt

  1. Манифест нужно редактировать только в одном месте - в файле AndroidManifest.template.xml, который лежит непосредственно в папке вашего проекта

    На основе этого файла генерируется файл манифеста, который добавляется к приложению.

  2. 1 час назад, Ingalime сказал:

    Вот такие сейчас у меня пути в опциях:

    C:\Users\Public\Documents\Embarcadero\Studio\20.0\PlatformSDKs\android-sdk-windows\build-tools\29.0.1\zipalign.exe
    C:\Users\Public\Documents\Embarcadero\Studio\20.0\PlatformSDKs\android-sdk-windows\build-tools\29.0.1\aapt.exe
    Если файлы zipalign.exe и aapt.exe находяться в папке 29, то откуда в манифесте цифра 28? Или это просто цифра дефолтная? Какая Ваша рекомендация для SDK API-Level location?

    Сейчас там: Embarcadero\Studio\20.0\PlatformSDKs\android-sdk-windows\platforms\android-25

    но у меня есть уже установленные на компьютер android-28 и android-29. Надо ставить максимальную?

     

    Так как с 1 августа Google требует указывать targetSdkVersion 28 и выше, то логично будет использовать 28-ю версию.29-я это Android 10, который еще не вышел официально. Думаю, проблем с ней не должно быть, но я бы повременил с ее использованием.

    Обратите внимание, что использование все более новых targetSdkVersion может приводить к некоторым ограничениям, которые вводит Google в новых версиях андроида.

    Например, при переходе на targetSdkVersion 28 вы обнаружите, что ссылки, начинающиеся на "http" считаются небезопасными и по умолчанию не обрабатываются. Рекомендуется повсеместно переходить на "https".

    Так что, если вы в каком-нибудь THTTPClient или где-либо еще выполняли запрос на "http", а после перехода на targetSdkVersion 28 обнаружили, что ваш код перестал работать, то либо переходите на "https", либо, если все же необходимо выполнять запрос на "http",  внесите изменения в файле манифеста: в разделе application нужно добавить строку android:usesCleartextTraffic="true".

     

  3. 23 минуты назад, Ingalime сказал:

    Прошу прощения, но не до конца понимаю. Каким образом студия создает манифест с настройкой android:targetSdkVersion="28" если в опциях проекта в Options->SDK Manager по умолчанию стоит SDK Version->Android SDK 25.2.5. В моем неправильном понимании в манифесте получалось бы android:targetSdkVersion="25" :(

    Название SDK Version в FMX остается таким каким было при первой установке и не меняется при обновлении Android SDK. Если вы исправно обновляете Android SDK, то в SDK менеджере вы можете указать последние версии  ZipAlign Location и Aapt Location, в частности 28.

  4. 38 минут назад, Ingalime сказал:

    Правильно ли я понимаю, что такой проект нельзя будет опубликовать после августа так как android:minSdkVersion должен быть 26 или все нормально для публикации?

     

    В справке Google говорится исключительно о targetSdkVersion, а не о minSdkVersion. И targetSdkVersion="26" - это условие для прошлого года. В этом году нужно писать targetSdkVersion="28" 

  5. В первом примере, когда создаете наследника какого-либо класса (в вашем случае TObject), не забывайте наследовать параметры от родительского класса и переопределять базовые методы

    Constructor Create(NewId:integer;NewNGP:string); overload;

     

    constructor MyType.Create(NewId:integer;NewNGP:string);
    Var RectForButt:TRectangle;
    begin
        inherited Create;
    ......

     

  6. 36 минут назад, Felix сказал:

    Сегодня прочитал, что летом 2019 в планах Google Play выставить обязательное правило предоставления новых приложений и обновлений в 32 и 64-разрядном исполнении.  Интересно, а что со старыми? Мое приложение написано на Delphi Seattle, залито на PlayMarket и работает. Удовлетворяет ли Delphi Seattle написанию 64-разрядных Android-приложений?

    Написанию 64-битных приложений не удовлетворяет ни одна версия Rad Studio, включая и ту, которая еще не вышла (10.3). В планах Embarcadero добавить поддержку 64 бит под Android позже в 19-м году.

    Думаю, механизм внедрения этой фичи будет такой же, как сейчас с TargetSDK. То есть старые приложения, уже размещенные в маркете, никто трогать не будет, но обновления и новые приложения  уже нельзя будет выпускать только в 32-битном исполнении.

  7. Обнаружил, что на некоторых телефонах с вытянутым экраном не отображается Smart Banner (TBannerAD.Size = Auto). Оказалось, что причиной тому неверный расчет высоты баннера в исходниках FMX.Advertising.Android. 

    Может быть, эта информация кому-нибудь поможет

     

    В документации Android высота баннера должна вычисляться так:

    1.PNG.7deb908fcd7d73c79db594430f070b6d.PNG

    Тогда как в коде FMX.Advertising.Android она вычисляется в процедуре UpdateControlMetrics следующим образом:

    const
      AdHeightPortrait = 90;
      AdHeightLandscape = 90;
      AdHeightPhonePortrait = 50;
      AdHeightPhoneLandscape = 32;
      AndroidSW600DP = 600;
      AndroidSW600DPLandscape = 552;
      AdMobBannerHeight = 50;
      AdMobFullBannerHeight = 60;
      AdMobLeaderboardHeight = 90;
    begin
      if (FAdControl <> nil) and not Assigned(FAdControl.OnResize) then
      begin
        case FAdControl.AdSize of
          TBannerAdSize.Auto:
            begin
              if Screen.Size.Height > Screen.Size.Width then
                if Screen.Size.Width < AndroidSW600DP then
                  FAdControl.Height := AdHeightPhonePortrait
                else
                  FAdControl.Height := AdHeightPortrait
              else
                if Screen.Size.Height < AndroidSW600DPLandscape then
                  FAdControl.Height := AdHeightPhoneLandscape
                else
                  FAdControl.Height := AdHeightLandscape;
            end;

    Также, учитывая, что на вытянутых экранах (по крайней мере на тех устройствах, на которых я тестил), Screen.Width и Screen.Height далеко не всегда дают верные значения, то более правильный код процедуры TAndroidBannerAd.UpdateControlMetrics будет таким:

    procedure TAndroidBannerAd.UpdateControlMetrics;
    var
      Frame: TRectF;
      Form: TCommonCustomForm;
      Disp: JDisplayMetrics;
      Window: JWindow;
      h: integer;
    const
      AdHeightLandscape = 90;
      AdHeightPhoneLandscape = 32;
      AndroidSW600DP = 600;
      AndroidSW600DPLandscape = 552;
      AdMobBannerHeight = 50;
      AdMobFullBannerHeight = 60;
      AdMobLeaderboardHeight = 90;
    begin
      if (FAdControl <> nil) and not Assigned(FAdControl.OnResize) then
      begin
    
        Disp := TJDisplayMetrics.Create;
        Window:=TJWindow.Wrap((MainActivity.getWindow as ILocalObject).GetObjectID);
        Window.getWindowManager.getDefaultDisplay.getRealMetrics(disp);
        h:=round(Disp.heightPixels/Disp.density);
    
    
        case FAdControl.AdSize of
          TBannerAdSize.Auto:
            begin
              if Screen.Size.Height > Screen.Size.Width then begin
                if h <= 400 then FAdControl.Height := 32
                else if (h>400) and (h<=720) then FAdControl.Height:=50
                else FAdControl.Height := 90
              end
              else
                if Screen.Size.Height < AndroidSW600DPLandscape then
                  FAdControl.Height := AdHeightPhoneLandscape
                else
                  FAdControl.Height := AdHeightLandscape;
            end;
          TBannerAdSize.Small:
            FAdControl.Height := AdMobBannerHeight;
          TBannerAdSize.Medium:
            FAdControl.Height := AdMobFullBannerHeight;
          TBannerAdSize.Large:
            FAdControl.Height := AdMobLeaderboardHeight;
        end;
    
        if Screen.ActiveForm <> nil then
          Form := Screen.ActiveForm
        else if Application.MainForm <> nil then
          Form := Application.MainForm
        else
          Form := nil;
        if Form <> nil then
        begin
          Frame := WindowHandleToPlatform(Form.Handle).Bounds;
          FAdControl.Width := Round(Frame.Width);
        end;
      end;
    end;

     

  8. Если не ошибаюсь, автор писала, что OpenDialog работает нормально, но ей нужен диалог выбора папки, а не файла. SelectDirectory не устраивает по интерфейсу, поэтому пришлось использовать TFileOpenDialog из VCL, с которым и проблемы.
    Но у меня есть подозрения, что при использовании TFileOpenDialog из VCL, SelectDirectory берется из модуля VCL.FileCtrl, а не FMX.Dialogs, из-за чего у него "устаревший" интерфейс.

    Для автора: попробуйте такой код, посмотрите, изменится ли внешний вид диалога

    procedure TForm1.Button1Click(Sender: TObject);
    var st: string;
    begin
        FMX.Dialogs.SelectDirectory('Открыть папку','C:\',st);
    end;

     

  9. В 23.10.2018 в 14:28, Shippo сказал:

    TOPenDialog не дает выбрать именно папку, надо обязательно файл указывать, поэтому используется TFileOpenDialog. Но поскольку он VCL его не кинешь на форму -  мне дельфи в палитре компонентов не дает закладки с ними, поэтому он вызывается динамически. Как я писала - SelectDirectiry нам не подходит из за своего дизайна - очень неудобно. 

    Не совсем понятно насчет неудобного дизайна SelectDirectory (В первом сообщении темы вы пишете, что у него слишком устаревший вид)
    Вот выбор файла через TOpenDialog

    1.PNG.64be637fa1789fa3cefa02957b2c8d1e.PNG

    А вот выбор папки через SelectDirectory:
    2.PNG.04480918e1718e76355aba1f8d7d2c62.PNG

    По-моему дизайн у них один и тот же. 

    UPD. Может быть, вы используете Vcl.FileCtrl.SelectDirectory, а не FMX.Dialogs.SelectDirectory?

  10. Возможно, проблема в том что в VCL и FMX по-разному реализована работа с окнами. Пока в голову приходят два варианта и оба касаются исходного кода компонентов TFileOpenDialog либо TOpenDialog:

    1. В исходниках кода TFileOpenDialog переделать работу с контекстом родительского окна  под FMX. Вместо Handle окна использовать WindowHandleToPlatform(Handle).Wnd

    2. В исходниках TOpenDialog разрешить нажатие на 'ОК' без выбора файла.

    Для этого скопируйте в папку проекта модули, в которых реализован функционал TFileOpenDialog или TOpenDialog и поэкспериментируйте с ними.

     

  11. Добрый день

    Проверил поведение TOpenDialog в своей программе в полноэкранном режиме. При переключении на другие программы и обратно окно диалога никуда не исчезает. Сложно сказать, чем вызвано подобное поведение диалога в вашем случае. Возможно стоит проверить код в обработчиках событий формы.

    Также, рекомендую поиграться со свойствами формы BorderStyle, FullScreen, WindowState. В частности, попробуйте BorderStyle = None; FullScreen = true; WindowState = wsMaximized.

  12. var Player: JMediaPlayer;

    Единожды создаете плеер и готовите файл:

    Player:=TJMediaPlayer.Create;
    Player.setDataSource(StringToJString('Путь_к_файлу'));
    Player.prepare; 

    И, когда потребуется, запускаете воспроизведение

    Player.start;

    В uses нужно добавить что-то из этого:

    FMX.Helpers.Android, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, 
      Androidapi.JNI.Media, Androidapi.JNI.JavaTypes, Androidapi.JNI.AdMob, 
      Androidapi.JNI.App, Androidapi.JNIBridge, FMX.Advertising, FMX.Platform.Android,
      Androidapi.JNI.Embarcadero

    Не помню уже, что именно. Ненужные уберите

  13. 23 минуты назад, Юрий Гусач сказал:

    Интересно, как получить коэффициент масштабирования во время работы программы(у пользователя может быть любое устройство). 

    var     ScreenService: IFMXScreenService;
            scale: single;
    
    begin
        if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then
        scale:=ScreenService.GetScreenScale;
    end;

     

    23 минуты назад, Юрий Гусач сказал:

    И все-таки было бы очень интересно узнать, что именно добиваются разработчики Fire monkey под Андроидом урезанием разрешения экрана.

    По видимому, какой то смысл в этом есть, но какой именно? 

       

    Эту фишку придумали не разработчики FireMonkey. Коэффициент масштаба экрана используется и в iOS, и в Android. Введен он для более удобного перевода ПО под новые экраны.

    Смысл в том, что оперируя тем же логическим размером экрана, ПО автоматически отрисовывает изображение на другом физическом разрешении.

  14. Да все норм. Мне самому рисунок не очень понравился ))

    Рисовал его в ворде года два назад, когда хотел понять, как удобнее рисовать звезду. Когда понял, то рисунок уже не было смысла доводить до ума, так что таким он и остался.

    Но вот щас все-таки решил доделать. Исправил изображение )

  15. 2 часа назад, Anatoliy сказал:

    Моя проблема как эти 5 звезд в мобильном приложении организовать и показать наиболее правильным и красивым образом ну и конечно понять на какой звезде был клик, ну и раскрасить предыдущее в желтый цвет для красоты, а не делать радиобатоны вместо звезд...

    Надеюсь, что в предыдущем посте помог ответить на первую часть вопроса.

    Если каждая звезда организована отдельным компонентом, то, соответственно, вы всегда можете узнать по какой звезде был клик и раскрасить все звезды до нее (включительно) в желтый цвет.

    Ниже скинул программку для герерации TPathData звезды, может пригодится

    star generator.zip

    Можно использовать генерируемую строку TPathData, или использовать код
     

    procedure star;
    var i: byte;
        a1,a2: single;
    begin
        Path.Clear;
        Path.MoveTo(PointF(0,-r));
        a1:=Pi/5-Pi/2; a2:=-Pi/2;
        for i:=1 to 5 do begin
            Path.LineTo(PointF((r*cos(Pi/5)-d)*cos(a1+(i-1)*2*Pi/5),(r*cos(Pi/5)-d)*sin(a1+(i-1)*2*Pi/5)));
            Path.LineTo(PointF(r*cos(i*2*Pi/5+a2),r*sin(i*2*Pi/5+a2)));
        end;
        Path.ClosePath;
        path.Translate(r*cos(Pi/10),r);
    end;

    Где R - радиус описанной окружности вокруг звезды. В програме он равен 100. d - Разность радиусов внешней и внутренней окружности согласно рисунка

    4.PNG.abfe8504a95ba539c8ee790c4d05a43e.PNG

     

     

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