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

Pavel M

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

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

  • Посещение

Весь контент Pavel M

  1. Pavel M

    JAVA и Delphi

    Прошу помощи в определении моих ошибок при написании и использования обёртки (часть библиотеки) Или ответа типа "используемый 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. Разумеется. Там нет ответа на главный вопрос. "Как программно завершить вызов?"
  3. Задача отбить\завершить звонок. 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 представляю себе весьма туманно.
  4. Действительно бегло прочел Ваш пост и iOS9Fix не заметил. Сам переносил свой проект (под ведро) на 10.1 berlin, - была схожая проблема, думал помогу... Вместе с тем, если бы Вы соблюдали правила форума, то претензий и обвинений за мое желание помочь Вам, у Вас не было бы. Может будет кому полезно (константы кодов символов по названиям иконок): FontAwesomeCodes.zip
  5. Скопируйте файл FMX.FontGlyphs из 10.1 в папку своего проекта и отредактируйте его. Запускаемая программа должна искать шрифт в TPath.GetDocumentsPath (шрифт деплойдится в .\assets\internal) поскольку файл шрифта не найден символы не отображаются.
  6. Ярослав, спасибо этот способ я уже пробовал. в файле .style обнаружил PlatformTarget = [DARKSTYLE] 1) это флаг настроек или просто комментарий? Использовал и Light и Dark темы из BitmapStyleDesigner цвет шрифта у статус бара остается всегда белым. Проверял на Android 5.1.1 (Nexus 4) 2) Как сделать цвет шрифта статус бара чёрным? Как я указал выше цвет статус бара становится черным если у формы свойство Fill.Kind сменить на любое значение кроме None (иначе цвет шрифта и заливки статуса белые) однако при этом естественно не отражается беграунд формы из применяемой темы через StyleBook. 3) Как статус бар залить черным цветом не изменяя Fill. Kind ?
  7. Пожалуйста подскажите почему при третьем нажатии на кнопку возникает исключение: 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. В реальной программе многократное нажатие на разные кнопки вызывает исключение. Данный пример показывает суть проблемы.
  8. Спасибо, Я видел и это и схожие темы реализации заливки через FullScreen. Меня интересует возможность смены родительской темы на тёмную и замена цвета шрифта. Попытки редактирования Style.xml ни к чему не привели (он восстанавливается при компиляции), можно конечно отредактировать AndroidManifest.template.xml далее подгрузить свой Style.xml Но возможно есть более элегантные решения?
  9. Если залить основную форму любым цветом, то заливка TitleBar становится черной (шрифт белого цвета на ней становится виден). Но как всё таки как сменить заливку на светлую, а шрифт на тёмный пока не понятно.
  10. Использую любой стиль для Android из "FireMonkey Premium Styles Pack" Цвет шрифта статус бара и его заливка белые, видно только уровень батарейки зеленый. Как в .style или в run-time изменить тему (цвет заливки/шрифта) TitleBar на Dark?
  11. http://fontello.com Поищите здесь то что Вам нужно и скачайте себе шрифт только с необходимыми символами
  12. SQLite может быть собран в однопоточном варианте (параметр компиляции SQLITE_THREADSAFE = 0). Подробнее: https://m.habrahabr.ru/post/149635/
  13. я так и сделал, но полагаю это костыль. Неужели нет API для применения. Интересна так же причина возникающих ошибок у предложенного вами варианта после 30 кликов
  14. Спасибо, звук воспроизводиться. Однако при частом многократном обращении (поставил событие на клик по кнопке и покликал) появляются ошибки: java.lang.RuntimeExceprion: Init failed И я не нашел стандартного звука "чпок" , как будто все звуки только для работы с телефонией.
  15. Как проиграть стандартный звук системы "кнооцк" при нажатии на кнопку? Про вибрацию вроде уже нашел: 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;
  16. В программе использую вспышку 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; Как можно освободить камеру без щелканья объективом? Задача сделать фото максимального качества в галерею. (Фактически это стандартный экшен "сделать фото" - но он не работает после игры с фанариком) Буду раз за любые комментарии по коду.
  17. Если "клиент" - клиент, то достаточно. Если "клиент" - официант, то нюансов чуть побольше. Я хотел сказать, что для этой задачи FMX не самый удачный инструмент, учитывая что PHP и сервак всё равно будут....
  18. Я как дилетант дам свои видения: Такого рода приложения собираются на конструкторе или используют сайт с мобильной версией. Без привязки к платформам, размерам экрана обновлениям и пр. - будет дешевле и удобнее для всех. FMX дает возможность использовать железо и датчики(GPS, микрофон, камеру, сетевые интерфейсы и т.д.), всё это дает возможность взаимодействовать через устройство с другими устройствами, или пользователем. В вашем случае это сайт. Можно распарсить существующий если он уже есть, можно подгружать на телефон в SQLite и потом иметь возможно актуальное меню... обновлять его по мере возможности... Меню и бронь это слишком мало для FMX
  19. Подскажите более быстрый и менее затратный способ получить максимально возможный размер шрифта исходя из статических размеров.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;
  20. Pavel M

    Шрифт с обводкой

    Как реализовать отображение шрифта в TText с обводкой? ANDROID Игрался с тенью - близко но это не то.
  21. Ярослав, Спасибо! Изучение FMX.PhoneDialer.Android.pas дало мне нужный результат, хоть и не сразу ))
  22. Ярослав, спасибо за хороший совет, однако пока ни чего не получается: создал класс: 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); приложение запустилось результата - НЕТ <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> присутствуют
  23. Для понимания как это сделать я и написал. вот это компилиться но конечно не работает 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; Вот аналогий, в силу отсутствия опыта, я пока и не вижу.
  24. Ещё раз Вам спасибо. Я видел Ваш пост. Ваши значения получаются 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 ))
  25. Кто-то может показать как на Delphi создать, зарегистрировать PhoneStateListener и заменить функцию onSignalStrengthsChanged которая принимает обратные вызовы?
×
×
  • Создать...