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

Pavel M

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

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

  • Посещение

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

  1. Прошу помощи в определении моих ошибок при написании и использования обёртки (часть библиотеки)
    Или ответа типа "используемый JAR непригоден для использования с DELPHI".

    Подробности ниже:

    Мне предоставили developer kit кассы (работает на андройде).
    Приложение Delphi типа Hello world на кассу поставил легко, но пока не получается работать со встроенным функционалом (пользователи, товары, чеки и пр).

    Библиотека кассы написана на Kotlin, я скомпилировал её целиком Android Studio в файл ".aar", затем распаковал как архив и вытащил ".jar", затем надеюсь создал корректную обёртку.
    (JAR закидываю как библиотеку к проекту на Delphi 10.1 update 2, вызываю как статик так и просто - либо не видит метод, либо приложение вылетает)

    Java2OP при создании обёртки вообще вылетает с ошибкой, буду признателен если подскажите как ему или чему то ещё правильно скормить эту библиотеку.

    Пример обёртки которую я использую:

    unit jdelphi;
    
    interface
    
    uses
      AndroidAPI.JNIBridge,
      Androidapi.JNI.JavaTypes;
    
    type
      JUser = interface;
    
      JUserClass = interface(JObjectClass)
        ['{A4B29440-8C8B-4C1F-A8E7-B7612D4FEEB4}']
       
        function getUuid : JString; cdecl;                                         
        function hashCode : Integer; cdecl;                                        
        function init(uuid : JString; secondName : JString; firstName : JString; inn : JString; phone : JString; pin : JString; roleUuid : JString; roleTitle : JString) : JUser; cdecl; overload;
        function init(uuid : JString; secondName : JString; firstName : JString; phone : JString; pin : JString; roleUuid : JString; roleTitle : JString) : JUser; cdecl; overload;
        function toString : JString; cdecl;                                     
      end;
    
      [JavaSignature('ru/evotor/framework/users/User')]
      JUser = interface(JObject)
        ['{2558685B-2BDC-4FCE-901F-3B53604E37C6}']
        function equals(JObjectparam0 : JObject) : boolean; cdecl;                 
        function hashCode : Integer; cdecl;                                       
        function toString : JString; cdecl;                                       
      end;
    
      TJUser = class(TJavaGenericImport<JUserClass, JUser>)
      end;
    
    implementation
    
    procedure RegisterTypes;
    
    begin
      TRegTypes.RegisterType('jdelphi.JUser', TypeInfo(jdelphi.JUser));
    end;
    
    initialization
      RegisterTypes;
    end.

     

    Программа Hello World!:

    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.StdCtrls, FMX.Objects,
      FMX.Platform.Android, Androidapi.JNI.JavaTypes, Androidapi.Helpers;
    
    type
      TForm1 = class(TForm)
        btnExit: TButton;
        StyleBook1: TStyleBook;
        Text1: TText;
        btnGet: TButton;
        lbResult: TLabel;
        procedure btnExitClick(Sender: TObject);
        procedure btnGetClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    uses jdelphi;
    
    procedure TForm1.btnExitClick(Sender: TObject);
    begin
      MainActivity.finish;
    end;
    
    procedure TForm1.btnGetClick(Sender: TObject);
    // var
    // TestClass: JUser;
    begin
      // TestClass := TJUser.Create;
      // lbResult.Text:= JStringToString(TestClass.getUuid);
    
      lbResult.Text := JStringToString(TJUser.JavaClass.getUuid);
    
    end;
    
    end.

     

    Спасибо, за любые комментарии, мысли или советы.

     

  2. Задача отбить\завершить звонок.

    uses
      FMX.Memo, FMX.Memo.Types, FMX.Media, FMX.Helpers.Android,
      System.SysUtils, System.Types, System.UITypes, System.Classes,
      System.Variants, System.IOUtils, Androidapi.Helpers,
      Androidapi.JNI.JavaTypes, Androidapi.JNI.Os,
      Androidapi.JNI.App, Androidapi.JNIBridge,
      Androidapi.JNI.GraphicsContentViewText, System.Threading,
      Androidapi.JNI.Telephony, Androidapi.JNI.Provider,
    Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText;
    
    
    function getdeclaredMethod(Cls: Jlang_class; const Name: JString): JMethod;
    var
      Arr: TJavaObjectArray<JMethod>;
      Meth: JMethod;
      I: Integer;
    begin
      Result := nil;
      Arr := Cls.getDeclaredMethods;
      for I := 0 to Arr.Length-1 do
      begin
        Meth := Arr.Items[I];
        if Meth.getName.compareTo(Name) = 0 then
        begin
          Result := Meth;
          Exit;
        end;
      end;
      raise Exception.CreateFmt('method not found: %s', [Name]);
    end;
    
    function killCall(context: JContext): Boolean;
    var
      obj: JObject;
      telephonyManager: JTelephonyManager;
      classTelephony: Jlang_Class;
      methodGetITelephony: JMethod;
      telephonyInterface: JObject;
      telephonyInterfaceClass: Jlang_Class;
      methodEndCall: JMethod;
    begin
      try
        // Get the boring old TelephonyManager
        obj := context.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
        telephonyManager := TJTelephonyManager.Wrap((obj as ILocalObject).GetObjectID);
    
        // Get the getITelephony() method
        classTelephony := TJlang_Class.JavaClass.forName(telephonyManager.getClass.getName);
        methodGetITelephony := getDeclaredMethod(classTelephony, StringToJString('getITelephony'));
    
        // Ignore that the method is supposed to be private
       // methodGetITelephony.setAccessible(True);
        JAccessibleObject(methodGetITelephony).setAccessible(True);
    
        // Invoke getITelephony() to get the ITelephony interface
        telephonyInterface := methodGetITelephony.invoke(telephonyManager);
    
        // Get the endCall method from ITelephony
        telephonyInterfaceClass := TJlang_Class.JavaClass.forName(telephonyInterface.getClass.getName);
        methodEndCall := getDeclaredMethod(telephonyInterfaceClass, StringToJString('endCall'));
    
        // Invoke endCall()
        methodEndCall.invoke(telephonyInterface);
    
        Result := True;
      except
        on E: Exception do // Many things can go wrong with reflection calls
        begin
          //
          Result := False;
        end;
      end;
    end;

    Это я нешел отсюда: stackoverflow

    Соответственно вопрос с invoke():

        telephonyInterface := methodGetITelephony.invoke(telephonyManager);

    в вышеуказанной теме остался открытым.

    Как отловить входящий звонок (необходимый момент) через BroadcastReceiver понятно.

    Как решить задачу с завершением текущего звонка?

    P.S.: Как писать на JAVA и экспортировать функции что бы использовать их из Delphi представляю себе весьма туманно.

     

     

  3. 12 минуты назад, master webs сказал:

    вы посты набираете ? или читать сообщение  нет необходимости ? iOS9Fix  на ведре нет !!! разговор шел об ios 

    переношу проект на 10.1 berlin  получил ошибку в файле FMX.FontGlyphs заменил оригинальным 

    Действительно бегло прочел Ваш пост и iOS9Fix не заметил.
    Сам переносил свой проект (под ведро) на 10.1 berlin, - была схожая проблема, думал помогу...

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

    Цитата

    Пункт.2: Одна тема — один вопрос. Два вопроса в одной теме задавать запрещено.


    Может будет кому полезно (константы кодов символов по названиям иконок):

    FontAwesomeCodes.zip

  4. 1 час назад, master webs сказал:

    Добрый день переношу проект на 10.1 berlin  получил ошибку в файле FMX.FontGlyphs заменил оригинальным там изменений практически нет проект  компилируется но иконок нет также заметил что iOS9Fix не делает запись так как должен  шрифт вообще не вписан в файл

    может  в Берлине что изменилось со шрифтами

    Скопируйте файл FMX.FontGlyphs из 10.1 в папку своего проекта и отредактируйте его.

    Запускаемая программа должна искать шрифт в TPath.GetDocumentsPath (шрифт деплойдится в .\assets\internal) поскольку файл шрифта не найден символы не отображаются.

  5. Ярослав, спасибо этот способ я уже пробовал.

    в файле .style обнаружил

    PlatformTarget = [DARKSTYLE]

    1) это флаг настроек или просто комментарий?

    Использовал и Light и Dark темы из BitmapStyleDesigner цвет шрифта у статус бара остается всегда белым.
    Проверял на Android 5.1.1 (Nexus 4)
    2) Как сделать цвет шрифта статус бара чёрным?

    Как я указал выше цвет статус бара становится черным если у формы свойство Fill.Kind сменить на любое значение кроме None (иначе цвет шрифта и заливки статуса белые) однако при этом естественно не отражается беграунд формы из применяемой темы через StyleBook.

    3) Как статус бар залить черным цветом не изменяя Fill. Kind ?

     

     

  6. Пожалуйста подскажите почему при третьем нажатии на кнопку возникает исключение:

    java.lang.RuntimeException: Init failed.

     

    unit Main;
    
    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.StdCtrls;
    
    type
      TFormMain = class(TForm)
        ButtonDtmf0: TButton;
        procedure ButtonDtmf0Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      FormMain: TFormMain;
    
    implementation
    
    uses Androidapi.JNI.Media;
    
    {$R *.fmx}
    
    procedure Play(Tone, Volume, DurationMs: Integer); overload;
    var ToneGenerator: JToneGenerator;
    begin
      ToneGenerator := TJToneGenerator.JavaClass.init(TJAudioManager.JavaClass.STREAM_MUSIC, Volume);
      ToneGenerator.StartTone(Tone, DurationMs);
    end;
    
    procedure TFormMain.ButtonDtmf0Click(Sender: TObject);
    var
      I: Integer;
    begin
    for I := 1 to 15 do
      begin
      Play(TJToneGenerator.JavaClass.TONE_DTMF_0, TJToneGenerator.JavaClass.MAX_VOLUME div 2, 50);
      sleep(100);
      end;
    end;
    end.

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

  7. 18 минут назад, master webs сказал:

    пользуйтесь поиском по форуму

    Спасибо,
    Я видел и это и схожие темы реализации заливки через FullScreen.

    Меня интересует возможность смены родительской темы на тёмную и замена цвета шрифта.
    Попытки редактирования Style.xml ни к чему не привели (он восстанавливается при компиляции),
    можно конечно отредактировать AndroidManifest.template.xml далее подгрузить свой Style.xml
    Но возможно есть более элегантные решения?

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

    Но как всё таки как сменить заливку на светлую, а шрифт на тёмный пока не понятно.

  9. Использую любой стиль для Android из "FireMonkey Premium Styles Pack"

    Цвет шрифта статус бара и его заливка белые, видно только уровень батарейки зеленый.
    Как в .style или в run-time изменить тему (цвет заливки/шрифта) TitleBar на Dark?

     

  10. В 04.04.2016 в 10:05, Rusland сказал:

    Да, это удобно. Тоже использую FontAwesome. Но понадобилось мне добавить свою картинку в шрифт и тут затык - программы редакторы не могут отредактировать этот шрифт. Кто-нибудь пробовал добавить свой символ?

    http://fontello.com

    Поищите здесь то что Вам нужно и скачайте себе шрифт только с необходимыми символами

  11. Спасибо, звук воспроизводиться.

    Однако при частом многократном обращении (поставил событие на клик по кнопке и покликал) появляются ошибки:

    java.lang.RuntimeExceprion: Init failed

    И я не нашел стандартного звука "чпок" :), как будто все звуки только для работы с телефонией.

  12. Как проиграть стандартный звук системы "кнооцк" при нажатии на кнопку?

    Про вибрацию вроде уже нашел:

    uses
      FMX.Helpers.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Os,
      Androidapi.JNI.App, Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText;
    
    implementation
     
    {$R *.fmx}
     
    uses
      FMX.Helpers.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Os,
      Androidapi.JNI.App, Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText;
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      VibratorObj: JObject;
      Vibrator: JVibrator;
    begin
      VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
      Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
      Vibrator.vibrate(StrToInt(ClearingEdit1.Text));
    end;

     

  13. В программе использую вспышку

    Camera.TorchMode := TTorchMode.ModeOn;
    После этого до камеры невозможно достучаться через IFMXCameraService.TakePhoto без предварительного включения затем выключения компонента.

    т.е. при любом обращении к свойствам компонента камера остается занятой для IFMXCameraService (даже при обращении к AvailableCaptureSettings)

    procedure TfrmMain.btnMakePhotoTap(Sender: TObject; const [Ref] Point: TPointF);var  xService: IFMXCameraService;  xParams: TParamsPhotoQuery;  xCtrl: TControl;  xCamera: TCameraComponent;  xCamSettings: TArray<TVideoCaptureSetting>;  xMaxResH, xMaxResW: Integer;begin   //контрол для вызова IFMXCameraService.TakePhoto(AControl, AParam)   xCtrl := TControl.Create(SELF);   xCamera := TCameraComponent.Create(SELF);   xCamSettings := xCamera.AvailableCaptureSettings;   //получаем максимальное разрешение   xMaxResH := xCamSettings[Low(xCamSettings)].Height;   xMaxResW := xCamSettings[Low(xCamSettings)].Width;   ////////////////////////////////////////////////   // БЕЗ ЭТОГО xService.TakePhoto НЕ ЗАПУСКАЕТСЯ   ///////////////////////////////////////////////   xCamera.Active := True;   //<- Именно сначала doStart   xCamera.Active := False;  //   ////////////////////////////   FreeAndNil(xCamera);  if TPlatformServices.Current.SupportsPlatformService(IFMXCameraService,    xService) then  begin    xParams.Editable := False;  //ИНАЧЕ НЕ СОХРАНЯЕТ В АЛЬБОМ!!!    xParams.NeedSaveToAlbum := True;    xParams.RequiredResolution := TSize.Create(xMaxResH,xMaxResW );    xService.TakePhoto(xCtrl, xParams);  end  else    ShowMessage('This device does not support the camera service');    FreeAndNil(xCtrl);end;
    Как можно освободить камеру без щелканья объективом?

    Задача сделать фото максимального качества в галерею.

    (Фактически это стандартный экшен "сделать фото" - но он не работает после игры с фанариком)

    Буду раз за любые комментарии по коду.

  14.  

    Меню и бронь это слишком мало для FMX

    Если "клиент" - клиент, то достаточно. Если "клиент" - официант, то нюансов чуть побольше.

     

     

    Я хотел сказать, что для этой задачи FMX не самый удачный инструмент, учитывая что PHP и сервак всё равно будут....

  15. Я как дилетант дам свои видения:

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

    Без привязки к платформам, размерам экрана обновлениям и пр. - будет дешевле и удобнее для всех.

     

    FMX дает возможность использовать железо и датчики(GPS, микрофон, камеру, сетевые интерфейсы и т.д.),

    всё это дает возможность взаимодействовать через устройство с другими устройствами, или пользователем.

    В вашем случае это сайт. Можно распарсить существующий если он уже есть, можно подгружать на телефон

    в SQLite и потом иметь возможно актуальное меню... обновлять его по мере возможности...

    Меню и бронь это слишком мало для FMX

  16. Подскажите более быстрый и менее затратный способ

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

    исходя из статических размеров.TLabel

    (с центрованием текста и без переноса строк)

    
    procedure TfrmMain.MaxFontSize(xLabel: TLabel);
    
    var
      xFntSize: Single;
      xW, xH: Single;
    
    begin
      xW := 0;
      xH := 0;
      xFntSize := 1;
    
      xLabel.ResultingTextSettings.Font.Size := xFntSize;
    
      while (xLabel.Size.Width > xW) and (xLabel.Size.Height > xH) do
    
      begin
        xLabel.ResultingTextSettings.Font.Size := xFntSize;
        xFntSize := xFntSize + 1;
        xLabel.Canvas.Font.Size := xFntSize;
        xW := xLabel.Canvas.TextWidth(xLabel.Text);
        xH := xLabel.Canvas.TextHeight(xLabel.Text);
      end;
    end;
    
    
  17. Посмотрите исходник FMX.PhoneDialer.Android.pas в нем есть пример создания листенера 

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

     

    создал класс:

    type
      TPhoneStateListener = class(TJavaGenericImport<JPhoneStateListenerClass, JPhoneStateListener>)
          private
          public
        Constructor Create;
        Destructor Destroy; Override;
        procedure onCallForwardingIndicatorChanged(cfi: Boolean); cdecl;
        procedure onCallStateChanged(state: Integer; incomingNumber: JString); cdecl;
        procedure onCellInfoChanged(cellInfo: JList); cdecl;
        procedure onCellLocationChanged(location: JCellLocation); cdecl;
        procedure onDataActivity(direction: Integer); cdecl;
        procedure onDataConnectionStateChanged(state: Integer);  overload; cdecl;
        procedure onDataConnectionStateChanged(state: Integer; networkType: Integer);overload; cdecl;
        procedure onMessageWaitingIndicatorChanged(mwi: Boolean); cdecl;
        procedure onServiceStateChanged(serviceState: JServiceState); cdecl;
        procedure onSignalStrengthChanged(asu: Integer); cdecl;//Deprecated
        procedure onSignalStrengthsChanged(signalStrength: JSignalStrength); cdecl;
    end; 

    описал все процедуры пустыми, самую нужную:

    procedure TPhoneStateListener.onSignalStrengthsChanged(signalStrength: JSignalStrength);
    begin
      frmMain.txtSignal.text := intToStr(signalStrength.getGsmSignalStrength);
    end;
    

    попытался получить данные.

      Listner := TPhoneStateListener.Create;
    
      TelephonyObj := SharedActivityContext.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
      TelephonyManager := TJTelephonyManager.Wrap((TelephonyObj as ILocalObject).GetObjectID);
    
       TelephonyManager.listen(Listner.JavaClass.init, Listner.JavaClass.LISTEN_SIGNAL_STRENGTHS);
    

    приложение запустилось результата - НЕТ  :unsure:

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    присутствуют

  18. Вы смотрели компонент, который я написал? Аналогично нужно сделать, только используя JPhoneStateListener

     

     

    Для понимания как это сделать я и написал.

     

    вот это компилиться но конечно не работает

     

    function TfrmMain.SignalStrength: integer;
    var
      mTelephonyManagerObj: JObject;
      mTelephonyManager: JTelephonyManager;
      mListener: JPhoneStateListener;
      mSignal: JSignalStrength;
    begin
      mTelephonyManagerObj := SharedActivityContext.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
      mTelephonyManager := TJTelephonyManager.Wrap((mTelephonyManagerObj as ILocalObject).GetObjectID);
    
      mTelephonyManager.listen(mListener, 256); //LISTEN_SIGNAL_STRENGTHS Constant Value: 256 (0x00000100)
      mListener.onSignalStrengthsChanged(mSignal);
    
      Result := mSignal.getGsmSignalStrength;
    end;

    Вот аналогий, в силу отсутствия опыта, я пока и не вижу.

  19. Меня интересует именно уровень приема от вышки (не тип или скорость интернета).

     

    Ещё раз Вам спасибо. Я видел Ваш пост.

    Ваши значения получаются  mTelephonyManager.getNetworkType и добраться до них легко.

    Такие же простые запросы (getGsmSignalStrength) есть у JSignalStrength он связан с JPhoneStateListener и как до них добраться из Delphi совсем не понятно.

    .

    Пробовал и по другому используя 

    https://github.com/barisatalay/delphi-android-broadcast-receiver-component

    procedure TfrmMain.FormCreate(Sender: TObject);begin
      SignalRcvr := TBroadcastReceiver.Create(self);
      SignalRcvr.onReceive := SignalReceiver;
      SignalRcvr.RegisterReceive;  SignalRcvr.Add('android.intent.action.SIG_STR');
    end;
    
    procedure TfrmMain.SignalReceiver(Context: JContext; Intent: JIntent);
    var
      Signal: Integer;
    begin
     signal := Intent.getIntExtra(StringToJString('asu'), -1);
     Memo1.Text := asu.toString;
    end;

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

    Кстати оч. удобно через него вешать ресиверы по событиям. 

     

    Было бы здорово если бы кто-то опытный вообще дал совет какую книгу почитать, пусть и используя google translite ))

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