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

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

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

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

  • Посещение

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

    100

Сообщения, опубликованные Евгений Корепов

  1. В 24.09.2018 в 21:35, ENERGY сказал:

    Необходимый минимум -

    iPhone или iPad. iPhone нужен от 5s и выше. 5 уже не пойдет, т.к. 32 битный. 

    100$  - купить сертификат разработчика у Apple.

    MacOS можно запускать на виртуальной машине, готовые образы Vmware, с установленой системой, есть на рутрекере. Для работы нужен реальный процесор Intel, с AMD не пойдет.

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

    Погуглил по фразе "macos vmware amd", выдало кучу решений, вот к примеру https://hackintosher.com/guides/how-to-install-macos-sierra-on-a-ryzen-pc-virtual-machine-vmware/ . Откуда информация о несовместимости проца AMD? 

  2. 17 часов назад, ENERGY сказал:

    Необходимый минимум -

    iPhone или iPad. iPhone нужен от 5s и выше. 5 уже не пойдет, т.к. 32 битный. 

    100$  - купить сертификат разработчика у Apple.

    MacOS можно запускать на виртуальной машине, готовые образы Vmware, с установленой системой, есть на рутрекере. Для работы нужен реальный процесор Intel, с AMD не пойдет.

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

    Значит нужно:

    1. Сертификат разработчика. С этим все ясно.

    2. Любой телефон с 64 битной ОС.

    3. Устройство с MacOS. Тут конечно вопросы есть. Машин с Интелом нет в принципе, железа куча, но везде AMD.  Мне кажется проще будет купить Mac mini типа такого https://www.dns-shop.ru/product/9054c969697c3120/nettop-apple-mac-mini-mgem2rua/characteristics/ , потом продать как станет не нужен.

    Хватит такого комплекта на ближайшие 2-3 года? Не ожидается никаких хитрых изменений? А то Эппл новое правило выкатит и все это превратится в тыкву.

  3. Вот как то так:

    uses
      .........
      Androidapi.JNI.JavaTypes,
      Androidapi.Helpers,
      Androidapi.JNI.GraphicsContentViewText;
    
    .......
    
    procedure TForm1.FormCreate(Sender: TObject);
    Var DownloadManager : JObject;
    begin
      DownloadManager:=SharedActivityContext.getSystemService(TJContext.JavaClass.DOWNLOAD_SERVICE);
      if DownloadManager <> nil then
      begin
        Используем...
      end;
    end;

    Вот как именно использовать - тут можно голову сломать, может кто и подскажет

    На java это делается вот так примерно:

    DownloadManager downloadmanager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    Uri uri = Uri.parse("http://www.example.com/myfile.mp3");
    DownloadManager.Request request = new DownloadManager.Request(uri);
    request.setTitle("My File");
    request.setDescription("Downloading");
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationUri(Uri.parse("file://" + folderName + "/myfile.mp3"));
    downloadmanager.enqueue(request);

    Подозреваю что вам придется самостоятельно описать класс (интерфейс) DownloadService.

  4. Ну а в тему - если это винда, то можете попробовать открыть ссылку на файл с помощью ShellExecute, если андроид, то запустить активити как тут https://stackoverflow.com/questions/49200962/delphi-10-2-how-can-i-open-a-url-in-androids-web-browser-from-my-application (вместо TJIntent.JavaClass.ACTION_VIEW можете попробовать использовать другие экшены). В ios не подскажу...

  5. В 09.09.2018 в 10:56, sinuke сказал:

    да!

    Надо отвечать 42 ? https://ru.wikipedia.org/wiki/Ответ_на_главный_вопрос_жизни,_вселенной_и_всего_такого

    А автору топика совет - хотите получить ответ, задавайте вопросы правильно и подробно. Какая платформа? Что такое "стандартный загрузчик"? И так далее...

  6. 5 часов назад, CodeWriter сказал:

    Благодарю за код, для windows может пригодиться. Но нужен код с использованием кроссплатформенных компонентов. Для Android компонент System.Win.ScktComp.TClientSocket не подходит.

    System.Net.Socket.TSocket работает и отправляет, всё как положено. Но ума не приложу, почему принять ответ, который приходит (WireShark тому свидетель) не получается?

    Сейчас только увидел в тексте " и для Android", сорри. 

    Вы кусок кода отправки/получения покажите, может кто увидит в чем проблема.

  7. Выдернул из рабочего проекта кусок, надеюсь вам поможет.

    Процедура SendCommand(Var ASendingData : TSendingData), в блокирующем режиме посылает текст на сервер и получает результат.

    unit UnitExcavatorWinTCPThread;
    
    interface
    
    uses
      classes,
      SysUtils,
      System.Types,
      System.Generics.Collections,
      System.Win.ScktComp,
      UnitExcavatorThread,
      UnitExcavatorTypes;
    
      type
        TExcavatorWinTCPThread = class(TExcavatorThread)
        protected
          FClientSocket : TClientSocket;
    
          CStream : TWinSocketStream;
          procedure CreateNetwork; override;
          procedure DestroyNetwork; override;
          procedure SendCommand(Var ASendingData : TSendingData); override;
        public
        end;
    
      implementation
    
    procedure TExcavatorWinTCPThread.CreateNetwork;
    begin
      FClientSocket:=TClientSocket.Create(Nil);
      FClientSocket.Host:=FExcavatorInstance.Host;
      FClientSocket.Port:=FExcavatorInstance.PortTCP;
      FClientSocket.ClientType:=TClientType.ctBlocking;
    
      CStream:=TWinSocketStream.Create(FClientSocket.Socket, FTimeouts.ConnectTimeout);
    end;
    
    procedure TExcavatorWinTCPThread.DestroyNetwork;
    begin
      if Assigned(CStream) then
        FreeAndNil(CStream);
      if Assigned(FClientSocket) then
        FreeAndNil(FClientSocket);
    end;
    
    procedure TExcavatorWinTCPThread.SendCommand(Var ASendingData : TSendingData);
    Var AReaded, ACount : integer;
        ABuffer : TBytes;
        ACommand, AStringBuffer : AnsiString;
        ACommandIdString : String;
        ADone : Boolean;
    begin
      ACommandIdString:='"id":' + ASendingData.CommandId.ToString;
      ASendingData.Error:=False;
      ACommand:=AnsiString(ASendingData.Value) + #10;
      ASendingData.Value:='';
      if Not FClientSocket.Active then
        try
          FClientSocket.Open;
        except
          on E:Exception do
          begin
            ASendingData.Error:=True;
            ASendingData.Value:=E.Message;
            exit;
          end;
        end;
      if FClientSocket.Active then
      begin
        try
          // Считываем из буфера все что там есть.
          while CStream.WaitForData(CStream.TimeOut) do
            AStringBuffer:=FClientSocket.Socket.ReceiveText;
        except
        end;
        try
          FClientSocket.Socket.SendText(ACommand);
        except
          on E:Exception do
          begin
            ASendingData.Error:=True;
            ASendingData.Value:=E.Message;
            exit;
          end;
        end;
        try
          ADone:=False;
          ACount:=0;
          repeat
            if CStream.WaitForData(CStream.TimeOut) then
              ASendingData.Value:=ASendingData.Value + FClientSocket.Socket.ReceiveText;
            if ASendingData.Value.Contains('"id":1') then
              break;
            if ASendingData.Value.Contains(ACommandIdString) then
              break;
            Inc(ACount);
            if ACount > 2 then
              break;
          until ADone;
        except
          on E:Exception do
          begin
            ASendingData.Error:=True;
            ASendingData.Value:=E.Message;
            exit;
          end;
        end;
      end
      else
      begin
        ASendingData.Error:=True;
        ASendingData.Value:='Not connected';
      end;
    end;
    
    end.

     

  8. В 03.11.2017 в 14:13, Wovan2 сказал:

    Не могу найти ни одного примера использования. Даже в хелпе Delphi:huh:

    Посмотрите в идущих в комплекте примерах:

    Тут \Object Pascal\Multi-Device Samples\Device Sensors and Services\App Tethering\ :

    • MediaPlayer
    • PhotoWall

    И тут \Object Pascal\RTL\Tethering\ :

    • BDShoppingList
    • DesktopBeaconCast
    • DesktopCast
    • MediaPlayer
    • PhotoWall

    А в общих чертах как то так:

    Вы получаете на "сервере" данные ни где нибудь, а в событии

    procedure TForm1.TetheringAppProfile1ResourceReceived(const Sender: TObject;  const AResource: TRemoteResource);

    Переменная AResource - все что вам нужно. Там и полученные данные AResource.Value определенного типа AResource.Value.DataType. И профиль отправителя AResource.Profile позволяющий точно его идентифицировать. 

     

     

  9. Я уперся рогом и все таки смог найти решение для вас. Гугль любит разработчиков, и обычно оставляет им возможность пользоваться сервисами бесплатно. И в этот раз чутьё не подвело. Вот решение:

    unit Unit1;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo,
      System.JSON,
      System.Net.HTTPClient,
      System.NetEncoding;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        procedure FormShow(Sender: TObject);
      private
        { Private declarations }
    
      public
        { Public declarations }
        function GoogleTranslate(const AValue : String) : String;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm1.FormShow(Sender: TObject);
    Var S : String;
    begin
      S:=GoogleTranslate('Hello world!');
      Memo1.Lines.Add(S);
    end;
    
    function TForm1.GoogleTranslate(const AValue : String) : String;
    const ConstSourceLang  = 'en';
          ConstTargetLang  = 'ru';
    var AResponce : IHTTPResponse;
        FHTTPClient : THTTPClient;
        AAPIUrl : String;
    begin
      AAPIUrl:='https://translate.googleapis.com/translate_a/single?client=gtx&sl=' + ConstSourceLang +
                '&tl=' + ConstTargetLang + '&dt=t&q=' + TNetEncoding.URL.Encode(AValue);
      FHTTPClient:=THTTPClient.Create;
      FHTTPClient.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) Gecko/20100625 Firefox/3.6.6';
      Result:='Translate Error : ';
      AResponce:=FHTTPClient.Get(AAPIUrl);
      if Not Assigned(AResponce) then
      begin
        Result:=Result + 'unknow.';
        Exit;
      end;
      if AResponce.StatusCode <> 200 then
      begin
        Result:=Result + AResponce.StatusText;
      end;
      try
        Result:=TJSONArray(TJSONArray(TJSONArray(TJSONObject.ParseJSONValue(AResponce.ContentAsString)).Items[0]).Items[0]).Items[0].Value;
      except
        Result:=Result + 'error parse JSON.';
        Exit;
      end;
    end;
    
    end.

    Подправил код, сделал покрасивее и убрал deprecated encode.

  10. Вот сделал аналог на THTTPClient:

    function TForm1.GoogleTranslate(const AValue : String) : String;
    const ConstGoogleUrl = 'http://translate.google.ru/translate_a/t';
    var ASource: TStringList;
        AResponce : IHTTPResponse;
        FHTTPClient : THTTPClient;
    begin
      FHTTPClient:=THTTPClient.Create;
      FHTTPClient.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) Gecko/20100625 Firefox/3.6.6';
      Result:='Translate Error : ';
      ASource:=TStringList.Create;
      ASource.Add('client=x');
      ASource.Add('text=' + AValue);
      ASource.Add('hl=en');
      ASource.Add('sl=en');
      ASource.Add('tl=ru');
      AResponce:=FHTTPClient.Post(ConstGoogleUrl, ASource);
      if Not Assigned(AResponce) then
      begin
        Result:=Result + 'unknow.';
        Exit;
      end;
      if AResponce.StatusCode <> 200 then
      begin
        Result:=Result + AResponce.StatusText;
      end;
        Result:=AResponce.ContentAsString;
    end;

    Получаю вполне очевидный ответ:

    Цитата

    Наши системы обнаружили необычный трафик из вашей компьютерной сети. Эта страница проверяет, действительно ли вы отправляете запросы, а не робот.
    Эта страница появляется, когда Google автоматически обнаруживает запросы, поступающие из вашей компьютерной сети, которые, как представляется, нарушают <a href="//www.google.com/policies/terms/"> Условия обслуживания </a>. После истечения этих запросов блок истечет. В то же время решение вышеуказанного CAPTCHA позволит вам продолжать использовать наши сервисы. <br> <br> Этот трафик может быть отправлен вредоносным программным обеспечением, подключаемым модулем браузера или скриптом, который отправляет автоматические запросы. Если вы сообщаете свое сетевое подключение, обратитесь к вашему администратору за помощью & mdash; другой компьютер, использующий один и тот же IP-адрес, может быть ответственным. <a href="//support.google.com/websearch/answer/86640"> Подробнее ... <br> <br> Иногда вас могут попросить решить CAPTCHA, если вы используете расширенные термины, которые роботы которые часто используются или отправляют запросы очень быстро.

    Конечно подбор HTTP Headers и других параметров может и обманет не надолго сервис, но на это надеяться не стоит. В Гугле работают отнюдь не дураки, и вряд ли они создавали свой сервис перевода (с отличным API кстати) просто так. Сервис платный (20 долларов США за 1 000 000 символов , но с пробным бесплатным периодом. Если вы хотите 100% работающее решение, то лучше воспользоваться им https://translate.google.com/intl/ru/about/forbusiness.html

  11. 9 минут назад, Евгений Гайдук сказал:

    Серверный ПК - виртуальная машина под управлением Windows Server 2012. Доступ к нему есть, но управление ограничено политикой невмешательства, то есть могу вносить минимальные изменения в фаловой структуре; Запрещено устанавливать какое-либо дополнительное ПО без муторной и долгой процедуры согласования. ☹️

     

    В это операционке уже есть встроенный FTP сервер. Кривой, но работать будет. Включить его и настроить очень просто.

  12. Вот, по моему мнению, самый просто и быстрый способ:

     Устанавливаете на сервере FTP сервер. К примеру SlimFTPd (http://www.whitsoftdev.com/slimftpd/), его можно запустить как сервис. Не забываете настроить папку, пользователя (с паролем) и остальное. Там все просто.

    В своем приложении отправка файла на FTP сервер займет у вас несколько строчек:

      IdFTP:=TIdFTP.Create;
      IdFTP.Host:=Host;
      IdFTP.Username:=ALogin;
      IdFTP.Password:=APassword;
      IdFTP.Passive:=True;
      IdFTP.TransferType:=ftBinary;
      IdFTP.ReadTimeout:=ConstFTPTimeout;
      IdFTP.TransferTimeout:=ConstFTPTimeout;
      try
        IdFTP.Connect;
      except
        on E : Exception do
        begin
          Error:=True;
          ErrorMessage:=E.Message;        
        end;
      end;
      AFilePathLocal:='Путь к файлу который хотите отправить';
      AFilePathRemote:='/Download/';
      if TFile.Exists(AFilePathLocal) then
        try
          IdFTP.Put(AFilePathLocal, AFilePathRemote);
        except
          on E : Exception do
          begin
            Error:=True;
            ErrorMessage:=E.Message;        
          end;
        end;
      IdFTP.Disconnect;
      IdFTP.Free;

    Вот как то так.

    P.S. Не верно написал путь для отправки.

    Исправил AFilePathRemote:='ftp://192.168.0.150/Download/'; на AFilePathRemote:='/Download/';

  13. Только что, Евгений Гайдук сказал:

    Все было бы хорошо, но у сети нет выхода на широкий интернет и на сервере развернуть HTTP врядли позволят. Уперся в стену. 

     

    Давайте определимся что из себя представляет ваш "Серверный ПК". Операционная система? Если у вас к нему доступ? Можете ли вы управлять им по своему усмотрению?

  14. Я думаю тут вы самый опытный по вопросу UWP-приложений ? Так что маловероятно кто то поможет. Может стоит задать этот вопрос на англоязычном форуме Эмбаркадеро? Мне эта тема тоже очень интересна, даже купил у Микрософта сертификат разработчика, но руки не доходят заняться.

    Очень бы хотелось от вас увидеть статью по размещению приложений в Microsoft Store. С пошаговыми инструкциями и скриншотами. Заранее благодарю!

  15. Заметил что у подсветки особенно активно съезжает крыша если в листинге есть вызовы анонимных процедур. Там вообще все в гирлянду превращается. А компилятор при этом говорит что все хорошо.

  16. 6 часов назад, Игорь Маринин сказал:

    в манифесте всё это прописал, но всё равно кнопка не активна. 

    ещё вопрос - как перехватить кнопки на пульте? в onKey приходят только стрелки (точнее в обработчик приходит Key и KeyChar = 0 других кнопок). интересует центральная между стрелок (enter) и кнопка микрофона.

     

    img.jpg.66d5caf3af44410b0c2f5f65ba69dc4d.jpg

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

    А еще можно читать поступающие данные непосредственно с устройства ввода, нужно только найти нужное, они в папке /dev/*

  17. 1 час назад, Игорь Маринин сказал:

    спасибо за подсказки, правда что-то так и не получилось )

    что интересно, если при установке нажать на пульте кнопку микрофона и вернуться назад, то кнопка установки становится активной и приложение нормально устанавливается и работает.

    Тогда посмотрите какие разрешения вы устанавливаете приложению (Your app uses hardware features (such as a touchscreen or camera) that are not available on TV)  . Может вы требуете что то, что нет физически на приставке.

  18. unit SharedGlobals;
    
    interface
    
    const
      ConstMyConstant = 30;
    
    type
      TMyType = record
        AValue : String;
      end;
    
    var
      MyVariable: Boolean=False;
    
      function MyFunction(AValue : String) : String;
    
    implementation
    
    function MyFunction(AValue : String) : String;
    begin
    
    end;
    
    end.

    И использование этого:

    unit Unit1;
    
    interface
    
    uses
      SharedGlobals,
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        АMyType : TMyType;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      АMyType.AValue:=ConstMyConstant;
      MyFunction(АMyType.AValue);
    end;
    
    end.

     

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