Разработка кроссплатформенных мобильных приложений в Delphi #3

    Разработка кроссплатформенных мобильных приложений в DelphiЧасть #1
    Часть #2

    Настройка среды и создание нового мобильного приложения.


    В предыдущей части цикла мы определились с задачей и создали простейшее FM приложение, которое отображает список рецептов. При этом мы использовали библиотеку доступа к данным FireDAC и технологию связывания объектов LiveBinding. Также мы условились, что в рамках поставленной задачи будет создано два приложения, использующих единую кодовую базу. И теперь, настало время для, возможно, самой интересной части – создания первого Android приложения.

    Прежде всего, необходимо произвести настройку среды. Если при установке RAD Studio вы не устанавливали инструменты разработки Android (JDK/SDK/NDK), то вам следует сделать это вручную. Так же необходимо установить USB драйвер для того Android устройства, с помощью которого будет производиться разработка приложения. Стоит отметить, что далеко не для всех Android устройств можно найти USB драйвер. В таком случае можно воспользоваться возможностью отладки через Wi-Fi.

    При создании нового проекта нам предлагается воспользоваться одним из нескольких шаблонов мобильного приложения. Выберем шаблон Header/Footer, представляющий собой мобильную форму с двумя панелями инструментов (Toolbar). После выбора шаблона необходимо сохранить проект. Новый проект удобнее всего создавать с помощью Project Manafer (правая верхняя панель IDE), как это показано на рисунке. Таким образом, мы сможем работать сразу с двумя проектами в группе.

    Project manager Delphi

    Главная форма приложения для выбранного нами шаблона по умолчанию адаптирована под устройство Google Nexus 4. С помощью выпадающего списка в правой верхней части дизайнера формы можно выбрать другое устройство. Для нашего приложения выберем одно из наиболее популярных планшетных устройств Google Nexus 7. Сразу же изменим и текст заголовка на главной форме (свойство Text компонента HeaderLabel).

    Первый запуск приложения


    Как вы уже поняли, для отладки приложения мы будем использовать физическое устройство, подключенное по USB. Хотя возможны и другие варианты (подключение с помощью Wi-Fi или использование эмулятора). Если вы подключили свой планшет или телефон в соответствии с инструкцией и активировали режим разработчика, то название вашего «девайса» появится в списке целевых устройств (Targets). Активируем его.

    Список целевых устройств Delphi XE5

    Еще раз убедитесь в том, что Android SDK настроен для вашего устройства, а т. н. «режим разработчика» активирован. Подробно весь процесс настройки среды для разработки Android приложения описан здесь.

    Запускается мобильное приложение точно так же, как и обычное «настольное» (нажатием клавиши F9). Если вы все сделали правильно, то после компиляции вы увидите главную форму приложения на своем планшете.

    Теперь попробуем реализовать тот же функционал, который мы реализовали в предыдущей части. Для этого добавим в текущий проект уже существующий модуль данных из предыдущего проекта (меню Project | Add to Project…). Как и в первом проекте, модуль надо включить в секцию Uses главной формы.

    implementation
    {$R *.fmx}
    uses uDM;
    


    Собственно, теперь нам ничего не мешает использовать ту же процедуру установки соединения, которую мы использовали в «настольном» приложении:

    function TDM.ConnectToDB: Boolean;
    begin
    try
      FDConnection1.Connected := True;
      FDTRecipe.Open;
    except
    
    end;
     Result:= FDConnection1.Connected;
    end;
    
    procedure TDM.DataModuleCreate(Sender: TObject);
    begin
    DM.ConnectToDB;
    end;
    


    Таким образом, мы избавили себя от необходимости повторно писать код установки соединения.

    Главная форма приложения


    В принципе, разработка пользовательского интерфейса мобильного приложения это отдельная, весьма обширная тема. Зачастую, именно неправильно спроектированный GUI может стать причиной неудачи. И иногда программисты пытаются перенести свой опыт создания интерфейсов «настольных» приложений на мобильную разработку. Это не совсем правильно. Перед тем, как приступить к написанию мобильного приложения стоит внимательно изучить базовые принципы дизайна интерфейсов. И, конечно же, стоит изучить интерфейсы популярных программ.

    В нашем случае мы вполне можем организовать интерфейс главной формы мобильного приложения по образу «настольного» (на самом деле, интерфейс Windows приложения мы строили с учетом того, что нам придется делать мобильное приложение). Поместим на форму компоненты TPanel, TSplitter и TCalloutPanel. В Object Inspector поменяем их свойства следующим образом:

    Panel1: TPanel
        Align = alLeft
    Splitter1: TSplitter
        Align = alLeft
        Width = 16
    CalloutPanel1: TCalloutPanel
        Align = alClient
        Width = 630    TabOrder = 4
        CalloutPosition = cpLeft
    


    Для отображения списка рецептов мы точно также используем TListBox и TBindNavigator, которые расположим на левой панели. TTabControl расположим на компоненте TCalloutPanel и настроим для каждого из компонентов свойство Align.

    Как и в прошлый раз, используем механизм LiveBinding для подключения набора данных. Данная процедура полностью аналогична той, которую мы проделали в предыдущей части, создавая «настольное приложение».

    главная форма мобильного приложения. Delphi XE5

    Как и в прошлый раз, нам потребуется создать некий инструмент для ввода названия рецепта. Если в настольном приложении мы могли использовать модальную форму, то концепция мобильных приложений в большинстве случаев предлагает другое решение, более мягко регламентирующее действие пользователя. Однако здесь мы используем «диалог», который по сути можно расценивать как разновидность модальной формы.

    Создадим новую мобильную форму. На ней поместим панель, и уже на панели разместим те элементы управления, которые мы размещали на форме добавления рецепта в прошлый раз (TEdit и две кнопки). Значение свойства Align – alCenter. Для кнопок зададим значение свойства ModalResult (mrOk и mrCancel).
    image
    Для класса формы создадим следующий метод класса:

    class procedure TfAddRecipe.ShowDialog(DataSet: TDataSet);
    begin
       fAddRecipe.ShowModal(
        procedure(ModalResult: TModalResult)
        begin
          if ModalResult= mrOk then
          begin
          if DataSet.State in [dsInsert, dsEdit] then
            DataSet.Post;
    
            fAddRecipe.Close;
          end
          else
          begin
          if DataSet.State in [dsInsert, dsEdit] then
              DataSet.Cancel;
    
            fAddRecipe.Close;
           end;
        end
      );
    end;
    


    При запуске приложения назначим данный метод в качестве обработчика события AfterInsert для единственного пока набора данных в программе.

    procedure THeaderFooterForm.FormShow(Sender: TObject);
    begin
    DM.FDTRecipe.AfterInsert:= TfAddRecipe.ShowDialog;
    end;
    


    Данная форма будет вызываться при каждом добавлении записи в набор данных FDTRecipe.

    Естественно, такой код нуждается в оптимизации. Создавать экземпляр формы при запуске приложения — не лучшая идея. Особенно для мобильных приложений. Но это тема для отдельного разговора, а пока из соображений наглядности оставим все как есть.


    Развертывание (deployment) Android приложения


    Перед тем, как запустить приложение, работающее с БД на Android, следует сделать определенные настройки, которые позволят перенести базу данных на мобильное устройство, и дадут возможность приложению «увидеть» базу. Для этого следует использовать Deployment Manager (меню Project |Deployment).

    Убедитесь, что выбрана отладочная конфигурация для платформы Android. В выпадающем списке на верхней панели инструментов должно быть выбрано значение Debug configurationAndroid platform.

    Для того, что бы при развертывании приложения на устройство переносилась и база данных, следует воспользоваться кнопкой «Add files» (добавить файлы) и выбрать файл базы данных.

    Введите assets\ в качестве значения поля Remote Path, а значение поля Platform установите Android. Директория assets это специальная директория, предназначенная для хранения вспомогательных ресурсов приложения. В поле Platform следует выбрать Android.

    Delphi XE5. Deployment manager

    Вы можете нажать кнопку Deploy, что бы протестировать процесс развертывания приложения.

    И, наконец, для того, что бы приложение заработало, следует сделать еще один важный шаг – определить событие компонента FDConnection1 следующим образом:

    procedure TDM.FDConnection1BeforeConnect(Sender: TObject);
    begin
    {$IFDEF ANDROID}
      FDConnection1.Params.Values['Database'] := '$(DOC)/db.s3db';
    {$ENDIF}
    end;
    


    Директива компилятора {$IFDEF ANDROID} передается для того, что бы данный код выполнялся только на Android устройствах. Таким образом, мы указываем приложению относительный путь к БД.

    Запускаем приложение, и на экране устройства получаем практически полный аналог Windows приложения, которое мы создали в предыдущей части.



    В этой части мы построили первое мобильное приложение и разобрались с тем, насколько процесс создания мобильных приложений в Delphi схож и насколько он отличается от процесса создания «обычного» desktop приложения. Естественно, пока мы реализовали только базовый функционал. Это касается как логики программы, так и ее интерфейса. Но, всему свое время. В следующей части мы продолжим работу над Windows приложением и более углубленно познакомимся с возможностями и принципами работы механизма LiveBinding.

    Оставайтесь с нами.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 11

      +1
      И традиционный комментарий: что по поводу Express Edition?
        +2
        вот для теста решил написать простенькую программу, это тектовый редактор. И тут сразу столкнулся с вопросом: как реализовать opendialog & savedialog?
        image
          0
          TOpenFileDialog и TSaveFileDialog на форму и по клику на кнопки написать код.
            +1
            Я так и делал, но на Андроиде эти кнопки не вызывают опен дилог, они вообще не работают
              0
              Как ты мог обратить внимание — в приложениях Андроида как раз нет стандартных диалогов сохранения/открытия файлов.
              Посмотри, как в браузерах сохраняется файл, или в плеерах делается выбор файлов — каждый сам себе делает по своему вкусу.
              0
              Нет. Эти компоненты нельзя использовать в мобильных приложениях. О чем красноречиво свидетельствует тултип в панели компонентов.
                +1
                ну так а я о чем говорил??
            0
            if ModalResult= mrOk then
                  begin
                  if DataSet.State in [dsInsert, dsEdit] then
            

            procedure TDM.DataModuleCreate(Sender: TObject);
            begin
            DM.ConnectToDB;
            end;
            

            Отформатируйте код пожалуйста, невозможно серьезно воспринимать так.
              –1
              У серьёзных программистов на серьёзном Delphi нет времени форматировать код, серьёзно. Они решают серьёзные задачи.
              0
              Захожу в Deployment Manager, добавляю файл ICON_1.ico в assets\
              пытаюсь запустить приложение на телефоне с Андроид 4.2.3 в результате оно просто не запускается, как только отключаю в Deployment Manager мою добавленную строку то все запускается — это фича или баг?

              Расскажите как мне загрузить нужные мне иконки? В винде есть TImageList, но в Андроид его нет, я хотел грузить иконки из ico файлов, например так:

              function LoadImageFromResource(ResName: String): TBitmap;
              var
              BitMap: TBitmap;
              begin
              Bitmap := TBitmap.Create;
              try
              if FileExists(TPath.Combine(TPath.GetDocumentsPath, ResName+'.ico')) then
              Bitmap.LoadFromFile(TPath.Combine(TPath.GetDocumentsPath, ResName+'.ico'))
              else
              ShowMessage('Файл ' + TPath.Combine(TPath.GetDocumentsPath, ResName+'.ico') + ' не найден.');
              Result := Bitmap;
              finally
              Bitmap.Free;
              end;
              end;

              Опять же загвоздка, TPath.GetDocumentsPath указывает на /data/data/ru.моеприложение/files

                0
                Попробовал подключить файл ресурсов с ресурсами иконок

                {$IFDEF ANDROID}
                {$R PROTO.res}
                {$ENDIF}

                написал функцию

                function LoadImageFromResource(ResName: String): TBitmap;
                var
                InStream: TResourceStream;
                Img: TBitmap;
                begin
                Img := TBitmap.Create;
                InStream := TResourceStream.Create(HInstance, ResName, 'ICON');
                try
                Img.LoadFromStream(InStream);
                Result := Img;
                finally
                InStream.Free;
                Img.Free;
                end;
                end;

                Но при попытке прочитать ресурс мне говорят что его нет. Что делать? Никаких примеров как загружать и использовать иконки или картинки в приложении под андроид я не нашел, засада какая то.

                Only users with full accounts can post comments. Log in, please.