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

petyaas

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

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

  • Посещение

Активность репутации

  1. Like
    petyaas отреагировална Dmitry_4501 в [РЕШЕНО]: Как отловить кнопки пульта ДУ   
    В общем удалось решить проблему с кнопками пульта. Теперь приложение распознает все кнопки с пульта. Если кому-то нужно, прикрепил архив. (Delphi 10.3.1 Rio)
     
    fmx_androidkey_fix.zip
  2. Like
    petyaas отреагировална Brovin Yaroslav в Получаем разрешение экрана устройства, логические и физические размеры экрана в FireMonkey   
    Введение
    Появление экранов повышенной плотность физических точек, привело с одной стороны к проблеме адаптации графического интерфейса под разные разрешения экранов при их одинаковых физических размерах, с другой к увеличению четкости и качества картинки.
     
    Например, если раньше на iPhone 3 при размере экрана 3,5 дюйма позволял отобразить 320х480 точек, то на устройстве iPhone 4 при таком же физическом размере экрана, экран мог уже отображать 640х960 точек. Это хорошо видно на увеличенном изображении обычного экрана и ретина экрана на рисунке ниже (слева - не ретина, справа - ретина (2х)). Справа количество физических точек ровно в четыре раза больше, чем слева:

     
    Для разработчика это могло означать, что интерфейс привязанный к разрешению 320х480 на Retina экране будет занимать только четверть экрана. Естественно, что использование разрешения экрана в физических координатах не удобно с этой точки зрения. Именно по этому появились логические координаты, которые гарантируют, что тот же пользовательский интерфейс для iPhone 3, будет иметь такие же размеры (физические) и на экране с ретиной.
     
    FireMonkey работает в логических координатах. Это означает, что на iPhone 3 - 4 мы работаем с логическим разрешением 320x480 точек. Однако, при отображении интерфейса на iPhone 4 c (с двойной плотностью пикселей по сравнению с iPhone 3), интерфейс автоматически масштабируется на физическое разрешение 640х960 с коэффициентом масштабирования равным 2. 
     
    Практика
    Теперь посмотрим, как получить всю эту информацию. Вся информация об экране (логический размер и коэффициент масштабирования) находится в сервисе IFMXScreenService. 
    Чтобы получить физическое разрешение экрана, нужно логический размер умножить на коэффициент масштабирования.
     
    Код ниже показывает, как получить доступ к этому сервису и извлечь требуемые параметры:
    var ScreenService: IFMXScreenService; LogicScreenSize: TPoint; ScreenScale: Single; begin // Запрашиваем сервис экрана, для получения информации о размере и текущем коэффициенте масштабирования if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then begin LogicScreenSize := ScreenService.GetScreenSize.Round; ScreenScale := ScreenService.GetScreenScale; LabelLogicScreenSize.Text := Format('Логический размер: %d, %d', [LogicScreenSize.X, LogicScreenSize.Y]); LabelPhysicScreenSize.Text := Format('Физический размер: %f, %f', [LogicScreenSize.X * ScreenScale, LogicScreenSize.Y * ScreenScale]); LabelScreenScale.Text := Format('Коэффициент масштабирования: %f',[ScreenService.GetScreenScale]); end; end; Результат кода приведен на снимке экранов ниже для iPad устройств с ретиной экраном и без:

  3. Like
    petyaas отреагировална Равиль Зарипов (ZuBy) в TLocationSensor - километраж   
    встроенных нету, по прямой можно рассчитать так
    function GetDistance(const aStart, aEnd: TMapCoordinate): Real; const Radius = 6372795; PiDiv180 = Pi / 180; var CosLatStart, SinLatStart, CosLatEnd, SinLatEnd, Delta, CosDelta, SinDelta, X, Y: Real; begin try CosLatStart := Cos(aStart.Latitude * PiDiv180); CosLatEnd := Cos(aEnd.Latitude * PiDiv180); SinLatStart := Sin(aStart.Latitude * PiDiv180); SinLatEnd := Sin(aEnd.Latitude * PiDiv180); Delta := (aEnd.Longitude * PiDiv180) - (aStart.Longitude * PiDiv180); CosDelta := Cos(Delta); SinDelta := Sin(Delta); Y := Sqrt(((CosLatEnd * SinDelta) * (CosLatEnd * SinDelta)) + ((CosLatStart * SinLatEnd - SinLatStart * CosLatEnd * CosDelta) * (CosLatStart * SinLatEnd - SinLatStart * CosLatEnd * CosDelta))); X := SinLatStart * SinLatEnd + CosLatStart * CosLatEnd * CosDelta; Result := Round(ArcTan2(Y, X) * Radius); except Result := MaxSingle; // сравнивать с MaxSingle, вдруг ошибка произошла end; end;  
  4. Like
    petyaas отреагировална estra в Как определить цвет пикселя?   
    В первую очередь нужно научиться пользоваться поиском.
     
    > Определить цвет нужного мне пикселя (X,Y)...
    http://blogs.embarcadero.com/yaroslavbrovin/2013/06/17/firemonkey-bitmap-scanline/ > и нарисовать хотя бы линию этого цвета на форме используя обычный: Canvas.DrawLine
    http://fire-monkey.ru/topic/3-kak-narisovat-tochku-na-kanve-v-firemonkey/#entry7 http://fire-monkey.ru/topic/13-pochemu-na-mobilnykh-platformakh-u-menia-ne-risuet/  
    На всякий случай пример:
    var C: TAlphaColor; procedure TForm1.FormCreate(Sender: TObject); begin c := TAlphaColorRec.Null; end; ///<Summary> /// Получение цвета пикселя ///</Summary> procedure TForm1.Button1Click(Sender: TObject); var bm: TBitmap; M: TBitmapData; begin bm := TBitmap.Create; bm.LoadFromFile( 'c:\TROP002_w100h100.PNG' ); // Получение цвета пикселя bm.Map( TMapAccess.Read, M ); C := M.GetPixel( 10, 10 ); bm.Unmap( M ); // Принудительная перерисовка Invalidate; bm.Free; end; ///<Summary> /// Отрисовка линии ///</Summary> procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); begin Canvas.Stroke.Color := C; Canvas.Stroke.Kind := TBrushKind.Solid; Canvas.DrawLine( PointF( 0, 0 ), PointF( 100, 100 ), 1 ); end;
  5. Like
    petyaas отреагировална Yarpda в Ура! Вышла 10.3 Rio!   
    Если планируется выставлять на playmarket то Рио (поддержка 26 targetsdk), если нет то Берлин постабильнее как по мне. Хотя если начинать то лучше сразу на Рио. Переходить все равно придется ..
  6. Thanks
    petyaas отреагировална Евгений Корепов в скачать файл   
    Вот как то так:
    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.
  7. Thanks
    petyaas отреагировална AliZairov в Native Android VideoView   
    Привет, Готовы,
     
    unit VideoView; interface uses System.SysUtils, FMX.Types, FMX.Helpers.Android, Androidapi.Helpers, Androidapi.JNI.App, Androidapi.JNI.Net, Androidapi.JNI.VideoView, Androidapi.JNI.Widget; type TVideoView = class(TObject) private FDialog: JDialog; FVideoView: JVideoView; public procedure Play(Source: string); end; implementation { TVideoView } procedure TVideoView.Play(Source: string); begin CallInUIThread( procedure begin FDialog := TJDialog.JavaClass.init(TAndroidHelper.Activity, -1); FDialog.setCancelable(True); FVideoView := TJVideoView.JavaClass.init(TAndroidHelper.Activity); FVideoView.setVideoURI(StrToJURI(Source)); FVideoView.start; FDialog.setContentView(FVideoView); FDialog.show; end); end; end.
  8. Like
    petyaas получил реакцию от Евгений Корепов в исчезает #   
    разобрался:
    procedure tform1.nabor(num:string); var   Intent: JIntent;   URI: Jnet_Uri;   number:jstring;   number1:string; begin   Intent:=TJIntent.Create;   Intent.setAction(TJIntent.JavaClass.ACTION_DIAL);   number:=TJnet_Uri.JavaClass.encode(StringToJString(num));   number1:=jstringtostring(number);   Intent.setData(StrToJURI('tel:'+number1));   SharedActivity.startActivity(Intent); end;  
  9. Like
    petyaas получил реакцию от Ingalime в Переместить курсор   
    Тему можно закрыть edit.selstart ответ
  10. Like
    petyaas отреагировална Andrey Efimov в TEdit не понятное удаление последнего символа   
    Здравствуйте.
    Это баг, я сообщил о нём ещё в мае (RSP-14928 и RSP-14929), в тех. поддержке предложили временное решение (ответ ниже). (Тема В TEdit стирается предыдущий текст аналогичная).
    find FMX.Platform.Android.pas find procedure TTextServiceAndroid.SetCaretPosition(const Value: TPoint); change code to: procedure TTextServiceAndroid.SetCaretPosition(const Value: TPoint); var SelStart, SelEnd: Integer; begin if FCaretPosition <> Value then begin FCaretPosition := Value; CalculateSelectionBounds(SelStart, SelEnd); if (FTextView <> nil) and not FInternalUpdate then PlatformAndroid.SynchronizeOnUIThread( procedure begin //Fix By [龟山]Aone(1467948783) //https://quality.embarcadero.com/browse/RSP-14928 // if (SelEnd - SelStart) > 0 then // FTextView.setSelection(SelStart, SelEnd) // else FTextView.setCursorPosition(CaretPosition.X); end); end; end;  
     
  11. Like
    petyaas отреагировална Brovin Yaroslav в Как правильно запустить видео в плеере из своей программы?   
    Собственно говоря, Android - хоть и linux подобная система, но команда System не распространяется на проигрывание видео в стандартном видео плейeре.
     
    Поэтому как правильно заметил konung, проигрывание видео файла в стандартном проигрывателе на платформе Андроид осуществляется при помощи намерений (Intent).
    uses Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Net, Androidapi.Helpers, FMX.Helpers.Android; {$R *.fmx} procedure PlayVideo(const AFileName: string); var Intent: JIntent; Data: JNet_Uri; begin Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW); Data := StrToJURI(AFileName); Intent.setDataAndType(Data, StringToJString('video/avi')); SharedActivity.startActivity(Intent); end;
  12. Like
    petyaas отреагировална Brovin Yaroslav в [TTabControl] Как сделать плавное переключение двух вкладок в TTabControl?   
    Самый простой вариант использования эффекта прокручивания основывается на использовании компонента TTabControl, который реализует переключение табов (вкладок) с анимацией. Для этого достаточно:
    Поместить TTabControl на форму и растянуть его на всю область TTabControl.Align = alClient. Создать вкладки. Одну вкладку на один логический экран (слайд, представление и тд). На каждую вкладку помещаете любой контент. В вашем случае TListBox. Вызвать в нужный момент метод переключения вкладок с анимацией: TTabControl.SetActiveTabWithTransition(const ATab: TTabItem; ATransition: TTabTransition; const ADirection: TTabTransitionDirection = TTabTransitionDirection.tdNormal) Где, 
    ATab: TTabItem - Вкладка, которую нужно отобразить ATransition: TTabTransition - Отобразить вкладку мгновенно или с эффектом сдвига (В вашем случае нужно второе TTabTransition.ttSlide) ADirection: TTabTransitionDirection - направление эффекта сдвига: Слева на право (TTabTransitionDirection.tdNormal) или с права налево (TTabTransitionDirection.tdReversed). Второй способ
    Аналогично создаем Таб контрол с вкладками, но для переключения вкладок используем стандартное действие TChangeTabAction, которое выполняет те же действия, что и SetActiveTabWithTransition. Действия доступны в редакторе TActionList "New Standart Action..."
     

  13. Like
    petyaas отреагировална Brovin Yaroslav в Как правильно удалять контролы в RunTime?   
    Добрый вечер,
     
    Главное, что нужно помнить по теме время жизни объектов - это то, что в мобильных платформах (Android и iOS) процесс удаления объектов отличается от поведения на настольных платформах (Windows и OSX). В мобильных платформах появился механизм ARC (Automatic Reference Counting - автоматический подсчет ссылок). Почитать описание (на английском), как это работает можно тут: Apple Developer. Для нас же, это означает, что все объекты имеют поле - счетчик ссылок (RefCount). Когда счетчик ссылок равен нулю, объект автоматически удаляется. Если кто-то присваивает ссылку на объект, то счетчик автоматически увеличивается на 1.
    property RefCount: Integer read FRefCount; // Свойство TObject Можно ошибочно подумать, что это связано со сборщиком мусора. Однако, это не так. При компиляции, компилятор автоматически вставляет в код служебные команды по увеличению и уменьшению счетчика ссылок. Поэтому объект физически уничтожится в тот момент, когда счетчик ссылок станет равным 0. В то время как сборщик мусора, удаляет объекты по своему внутреннему расписанию.
     
    Теперь о вашем вопросе. Когда вы создаете объект и указываете ему родителя, автоматически ваш объект попадает как минимум в список дочерних объектов TabItem1. А значит, автоматически счетчик ссылок на TCircle будет увеличен. Когда вы сохраняете ваш объект в массиве, это опять же автоматически увеличивает счетчик ссылок. Поэтому, чтобы удалить объект есть два способа:
     
    1. Вызвать метод TObject.DisposeOf. Это форсирует вызов деструктора, но не очищает память выделенную под объект. Это означает, что выполниться код деструктора, TCircle будет удален из списков, все ресурсы, которые окружность захватила будут распущены. Но сама память, которая была выделена из кучи под его хранение будет распущена, только в момент, когда больше не будет ни одной ссылки. Например, так:
    c[r].DisposeOf; c[r] := nil; 2. Убрать все ссылки, которые указывают на ваш объект. Это приведет к автоматическому удалению объекта. Убрать объект из структуры объектов, путем удаления удаления его из родительcкого контроkа Parent = nil, и затем вызывать Free и занилилить уже ссылку на объект в массиве. 
    c[r].Parent := nil; c[r].Free; c[r] := nil; // Или FreeAndNil(c[r]), в зависимости от типа c. Если больше ссылок на ваш объект нету, то данный код автоматически удалит объект c[r].
    Дополнение от RAD Studio XE6. В этой версии компилятор автоматически после вызова метода Free очистит указатель на объект. По этой причине дополнительно присваивание nil указателю на объект не требуется на мобильных платформах
    var A: TObject; begin A := TObject.Create; A.Free; // В этом месте A = nil на мобильных платформах. // На настольных платформах: A указывает на мусор end;  Чтобы осталась совместимость с настольными платформами, лучше использовать второй подход.
     
    P.S. Никогда не вызывайте деструктор напрямую, вызовом метода Destroy.
  14. Like
    petyaas отреагировална Andrey Efimov в Не удаляет компонент   
    Как правильно удалять контролы в RunTime?
  15. Like
    petyaas отреагировална zairkz в С помощью каких компонентов проще всего реализовать онлайн чат?   
    Можно помучаться с TListView, но я остановился на TPresentedScrollBox и стилизованных Label'ах (облачки сообщений, под разные scale на png 9patch), скорость скролла хорошая, плюс есть боунсы и тд.
    Приложил исходники проекта, также в архиве отдельно chat.style
    procedure TForm2.ChatUp(UsID: integer; LastId: integer; CText: string); var   Labb: TLabel;   Marg: Single;   LT: TLayout; begin   LT := TLayout.Create(PR);   LT.Parent := PR.Content;   LT.Margins.Top := 2;   LT.Align := TAlignLayout.Top;   LT.Position.Y := PR.ContentBounds.Height + 50;   Marg := PR.Width * 0.20;   Labb := TLabel.Create(PR);   Labb.Parent := PR;   Labb.Align := TAlignLayout.Top;   Labb.AutoSize := True;   Labb.WordWrap := True;   Labb.TextSettings.WordWrap := True;   if UsID = 0 then   begin     Labb.Margins.Left := Marg;     Labb.Margins.Right := 4;     Labb.TextAlign := TTextAlign.Trailing;     Labb.StyleLookup := 'labelchat_green';   end   else   begin     Labb.Margins.Right := Marg;     Labb.Margins.Left := 4;     Labb.TextAlign := TTextAlign.Leading;     Labb.StyleLookup := 'labelchat_white';   end;   Labb.NeedStyleLookup;   Labb.Text := ' ' + CText + ' ';   LT.Height := Labb.Height + 4;   Labb.Parent := LT;   if UsID = 0 then     Labb.Align := TAlignLayout.Right   else     Labb.Align := TAlignLayout.Left; end; Первые признаки шизофрении:

    Chat.zip
  16. Like
    petyaas отреагировална Rusland в RAD 11 на подходе?   
    RAD Studio 10.1 Berlin Hotfix for DataSnap
    This hotfix resolves an issue with DataSnap servers failing with an error when applying updates from a client or requesting a refresh. The error raised is "Invalid variant type conversion".
    Updated on May 3rd, 2016 to remove extraneous files.
  17. Like
    petyaas получил реакцию от Pax Beach в Delphi.DataSnap. Провайдеры. Загрузка картинки   
    Проблема – не могу передать изображение с клиента  на сервер DataSnap и сохранить в СУБД MySQL
    procedure TForm2.Button1Click(Sender: TObject);
    var bmp:tbitmap; twic:twicimage;
    begin
    bmp:=tbitmap.Create; twic:=twicimage.Create;
    opendialog1.Execute;
    twic.LoadFromFile(opendialog1.FileName);
    bmp.Assign(twic);
    clientdataset1.append;
    clientdataset1.FieldByName('name').Asstring:='Hello';
    clientdataset1.FieldByName('Picture').Assign(bmp);
    clientdataset1.Post;
    clientdataset1.ApplyUpdates(0);
    //clientdataset1.Refresh;
    clientdataset1.Close;
    clientdataset1.Open;
    end;
     
     
  18. Like
    petyaas отреагировална Martifan в [Android] Как свернуть приложение?   
    Нашел еще один способ:
      Uses     Androidapi.Helpers; procedure TfMain.SpeedButton11Click(Sender: TObject); begin   SharedActivity.moveTaskToBack(True); end;
  19. Like
    petyaas отреагировална Martifan в Получить голос из микрофона потоками   
    Доброго времени сутки
    недавно для себя открыл что можно из микрофона получить данные потоками:
    Uses    ..., Androidapi.JNI.Media;   procedure TForm1.Button1Click(Sender: TObject); var bufferSize: integer;     buffer: TJavaArray<Byte>;     M: TMemoryStream;   begin   audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC,                                               44100,                                               TJAudioFormat.JavaClass.CHANNEL_IN_MONO,                                               TJAudioFormat.JavaClass.ENCODING_PCM_16BIT,                                               44100 * 2); (audioRecord as JAudioRecord).startRecording;   buffer := TJavaArray<Byte>.Create(8820); (audioRecord as JAudioRecord).read(buffer, 0, 8820);   (audioRecord as JAudioRecord).stop;   audioRecord.release;   buffer заполняется данными я проверил все работает (можно код прописать чтобы этот buffer проигрывал)
    audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC,                                               44100,                                               TJAudioFormat.JavaClass.CHANNEL_IN_MONO,                                               TJAudioFormat.JavaClass.ENCODING_PCM_16BIT,                                               44100 * 2); <--- как мне кажется здесь видно что это формат Wave 
     
     
    я пытаюсь передать это все серверу:
    IdUDPClient1.SendBuffer(IdUDPClient1.Host, IdUDPClient1.Port, RawToBytes(buffer, buffer.Length)); сервер запущен на Windows но не получается я слышу только пикание
     
    Вопрос:
    как мне передать этот поток серверу (среды Windows) и как его проигрывать на сервере, может у кого есть опыт работы с этом сфере или какой нибудь документация имеется или какой нибудь предложение есть как все это сделать все совете и предложении очень важен 
     
    Заранее спасибо согласитесь интересно использовать микрофон так и не дожидая пока он создаст файл
    всем удачи
×
×
  • Создать...