Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

4 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. hi sonya, if you look at the demo you can see that you can select and move objects one by one. Viewport3d Scene Large TRectangle3D FPS Test.rar
  2. okoca

    How to play sound via stream in android platform

    It's a test I made at the time, if you make it better please share it with us, like I did. is both client and server. unit Unit2; 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.ScrollBox, FMX.Memo, FMX.Edit, IdContext, IdTCPConnection, IdTCPClient, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, IdIOHandler, IdIOHandlerStream, IdIOHandlerSocket, IdIOHandlerStack, IdServerIOHandler, IdServerIOHandlerSocket, IdServerIOHandlerStack, FMX.ListBox; type TMain = class(TForm) Button_ServerListen: TButton; Panel1: TPanel; Label1: TLabel; Memo_Debug: TMemo; Label_RunControl: TLabel; Timer_RunControl: TTimer; IdTCPServer: TIdTCPServer; IdTCPClient: TIdTCPClient; cTimerRecorder: TTimer; Button_ClientConnect: TButton; Timer_Connect: TTimer; Edit_RemoteIP: TEdit; ComboBox_SelectIP: TComboBox; procedure FormCreate(Sender: TObject); procedure Timer_RunControlTimer(Sender: TObject); procedure IdTCPServerExecute(AContext: TIdContext); procedure IdTCPServerConnect(AContext: TIdContext); procedure IdTCPServerDisconnect(AContext: TIdContext); procedure IdTCPClientConnected(Sender: TObject); procedure cTimerRecorderTimer(Sender: TObject); procedure IdTCPClientDisconnected(Sender: TObject); procedure Timer_ConnectTimer(Sender: TObject); procedure Button_ClientConnectClick(Sender: TObject); procedure ComboBox_SelectIPChange(Sender: TObject); private { Private declarations } public { Public declarations } Procedure Debug(From, Msg:String); end; var Main: TMain; implementation Uses System.IOUtils, System.Diagnostics, // TickCount Androidapi.JNI, Androidapi.JNIBridge, Androidapi.JNI.JavaTypes, Androidapi.JNI.Media, Androidapi.JNI.Net, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText; // Wifi {$R *.fmx} Var // Server sAudioTrack: JAudioTrack; sMemory:TMemoryStream; sBuffer:TJavaArray<Byte>; Var // Client cMemory:TMemoryStream; cBuffer:TJavaArray<Byte>; cAudioRecord:JAudioRecord; cBufferSize:Integer; Var SampleRate:Integer; AudioFormat:Integer; tCountdown:Byte=2; InternalTimer:Integer=0; // ------------------------------ function GetWifiIpAddress: String; var WifiManagerObj: JObject; WifiManager: JWifiManager; WifiInfo: JWifiInfo; ip: Integer; begin WifiManagerObj := SharedActivityContext.getSystemService(TJContext.JavaClass.WIFI_SERVICE); WifiManager := TJWifiManager.Wrap((WifiManagerObj as ILocalObject).GetObjectID); WifiInfo := WifiManager.getConnectionInfo(); ip := WifiInfo.getIpAddress and $FFFFFFFF; result := Format('%d.%d.%d.%d', [(IP) and $FF, (IP shr 8) and $FF, (IP shr 16) and $FF, (IP shr 24) and $FF]); end; procedure TMain.Timer_RunControlTimer(Sender: TObject); begin Label_RunControl.Text:=IntToStr(Random(65535)); end; function MemoryStreamToString(M: TMemoryStream): string; begin SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char)); end; procedure TMain.ComboBox_SelectIPChange(Sender: TObject); begin Edit_RemoteIP.Text:=Trim(ComboBox_SelectIP.Items.Strings[ComboBox_SelectIP.ItemIndex]); end; Procedure TMain.Debug(From, Msg:String); Begin Msg:=From+'> '+Trim(Msg); Memo_Debug.Lines.Add(Msg); Memo_Debug.SelStart := Length(Memo_Debug.Text); Memo_Debug.SelLength := 0; Memo_Debug.ScrollBy(0, Memo_Debug.Lines.Count); Sleep(1); End; procedure TMain.Button_ClientConnectClick(Sender: TObject); begin IdTCPClient.Host:=Edit_RemoteIP.Text; IdTCPClient.Port:=5555; IdTCPClient.ConnectTimeout:=3000; IdTCPClient.Connect; end; procedure TMain.Timer_ConnectTimer(Sender: TObject); begin tCountdown:=tCountdown-1; Button_ClientConnect.Text:='Bağlan ('+tCountDown.ToString+')'; if tCountdown<1 then Begin Timer_Connect.Enabled:=False; // -------------------------- TThread.CreateAnonymousThread( procedure() begin TThread.Synchronize(TThread.CurrentThread, procedure begin Button_ClientConnectClick(Sender); end); end).Start; End; end; procedure TMain.FormCreate(Sender: TObject); begin Edit_RemoteIP.Text:=GetWifiIpAddress; //SAMPLE_RATE 16000 - 22050 - 44100 SampleRate:=44100; AudioFormat:=TJAudioFormat.JavaClass.ENCODING_PCM_16BIT; // 3764, 8192 cbufferSize:=TJAudioRecord.JavaClass.getMinBufferSize(SampleRate, TJAudioFormat.JavaClass.CHANNEL_IN_MONO, AudioFormat); Debug('*','cBufferSize = '+cBufferSize.ToString()); if (cbufferSize=TJAudioRecord.JavaClass.ERROR_BAD_VALUE) then Debug('*','cbufferSize = ERROR_BAD_VALUE'); cAudioRecord:=TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC, SampleRate, TJAudioFormat.JavaClass.CHANNEL_IN_MONO, AudioFormat, cBufferSize); sAudioTrack:=TJAudioTrack.JavaClass.init(TJAudioManager.JavaClass.STREAM_MUSIC, SampleRate, TJAudioFormat.JavaClass.CHANNEL_OUT_MONO, AudioFormat, cBufferSize, TJAudioTrack.JavaClass.MODE_STREAM); // MODE_STREAM - MODE_STATIC if (cAudioRecord.getState <> TJAudioRecord.JavaClass.STATE_INITIALIZED) then Debug('*','cAudioRecord.getState = '+cAudioRecord.getState.ToString()+'<>STATE_INITIALIZED'); cBuffer:=TJavaArray<Byte>.create(cBufferSize); sBuffer:=TJavaArray<Byte>.create(cBufferSize); sMemory:=TMemoryStream.Create; cMemory:=TMemoryStream.Create; Debug('*','# Server Start Event.'); IdTCPServer.DefaultPort:=5555; IdTCPServer.Bindings.Add.IP:=Edit_RemoteIP.Text; IdTCPServer.Active:=True; if IdTCPServer.Active then Begin Button_ServerListen.Enabled:=False; Button_ServerListen.Text:='Server Aktif'; Debug('*','Server ('+Edit_RemoteIP.Text+':'+IdTCPServer.DefaultPort.ToString+') Bekliyor.'); End; InternalTimer:=0; TThread.CreateAnonymousThread( procedure() begin Repeat Sleep(100); InternalTimer:=InternalTimer+1; Until (Application.Terminated); End).Start; // Timer_Connect.Enabled:=True; end; procedure TMain.IdTCPServerConnect(AContext: TIdContext); begin Debug('S', AContext.Connection.Socket.Binding.PeerIP+':'+AContext.Connection.Socket.Binding.PeerPort.ToString+' Bağlandı.'); Debug('S','sAudioTrack.Play'); sAudioTrack.Play; end; procedure TMain.IdTCPServerDisconnect(AContext: TIdContext); begin Debug('S', AContext.Connection.Socket.Binding.PeerIP+':'+AContext.Connection.Socket.Binding.PeerPort.ToString+' Koptu.'); Debug('S','sAudioTrack.Stop'); sAudioTrack.stop; end; procedure TMain.IdTCPServerExecute(AContext: TIdContext); Var rLen,x:Integer; begin if AContext.Connection.IOHandler.Readable then begin rLen:=0; Try rLen:=StrToIntdef(AContext.Connection.IOHandler.Readln,0); Except End; //Debug('S','rLen = '+rLen.ToString); if rLen>0 then Begin sMemory.Clear; Try AContext.Connection.IOHandler.ReadStream(sMemory, rLen, False); Except End; if sMemory.Size>0 then Begin // thread içinde yaz, bufferden sbuffer.size kadar okuyabilirsin, fazlası? sMemory.Position:=0; repeat x:=sMemory.Read(sBuffer.data^, sBuffer.Length); sAudioTrack.Write(sBuffer, 0, sBuffer.Length); until (x=0); End; End; End; End; procedure TMain.IdTCPClientConnected(Sender: TObject); begin Debug('C','TCPClient.Connected.'); Debug('C','cAudioRecord.Start'); cMemory.Clear; cAudioRecord.startRecording; cTimerRecorder.Enabled:=True; end; procedure TMain.IdTCPClientDisconnected(Sender: TObject); begin Debug('C','TCPClient.Disconnected.'); Debug('C','cAudioRecord.Stop'); cTimerRecorder.Enabled:=False; cAudioRecord.Stop; end; procedure TMain.cTimerRecorderTimer(Sender: TObject); Var rLen:Integer; begin cTimerRecorder.Enabled:=False; if IdTCPClient.Connected then Begin InternalTimer:=0; cMemory.Clear; Repeat Try rLen:=cAudioRecord.Read(cBuffer, 0, cBuffer.Length); cMemory.Write(cBuffer.Data^, rLen); Except End; Application.ProcessMessages; Until InternalTimer>9; rLen:=cMemory.Size; // buradan sonra thread ile yollasın. Debug('c',rLen.ToString()+'kb uploading.'); Try IdTCPClient.IOHandler.WriteLn(cMemory.Size.ToString); Except End; if rLen<>cMemory.Size then Debug('#','error on cmem size') else Begin cMemory.Position:=0; Try IdTCPClient.IOHandler.Write(cMemory, rLen, False); Except End; End; End; cTimerRecorder.Enabled:=True; end; // stream size 50kb dan büyükse upload et end. Sound Streamming - Remote Ses Buffering.rar
  3. okoca

    FMX 2D drawing

    Hi wuwuxin, the 3d scene environment, you can create a 2d environment by fixing the camera angle, I think this is the best resource you can find. https://www.youtube.com/user/QuarkCube/videos even if I were you, I would back up the videos of that channel, you may not find it tomorrow. I don't know exactly what you need but you can catch it yourself by browsing the videos. Thank you to.
  4. I agree with your opinion, the captain is cut out for this kind of work, https://sandboxie-plus.com/downloads/ I use. when i'm done i delete the repository Sandboxie folder, create it again, isolate the fully running application from the system. After examining what it has created in the sandboxie folder, I test its reliability.
  5. okoca

    Design time and run time styles different

    hello, if you make a sample demo that shows us a problem, we'll look into it.
  6. okoca

    Custom ListBox Layout in fmx

    for listbox or listview, every time you scroll, OnApplyItemStyleLookup is triggered, when this event is triggered, for example, does the item in the listbox appear (can user see this listbox item), You need to check the visible area, that is, the listbox will take its height, the listbox will take the position of the item and the listbox will update the number of items that fit inside the height the style information and other item information that will appear on the screen, for example update listboxitem.image or listboxitem.text/rectangle/button. Don't do this to all items, your app will start to freeze while scrolling, if you do this as i say, OnApplyItemStyleLookup It will not constantly update the same items that appear on the screen in every scroll, otherwise even if you slide the scroll by 1 pixel, it will always be triggered. Procedure TfCountrySelection.ListBox_CountryList_OnApplyItemStyleLookup(Sender: TObject); Var ListBoxItem:TListBoxItem; FlagStream:TMemoryStream; UlkeKodu:String; Flag:TObject; Begin Try ListBoxItem:=TListBoxItem(Sender); UlkeKodu:=ListBoxItem.StylesData['country_code'].AsString; if Length(UlkeKodu)>0 then Begin if (Flags.GetCountryFlagStream(Trim(UlkeKodu), FlagStream)=True) then Begin Try Flag:=ListBoxItem.FindStyleResource('Flag'); if (Flag<>Nil) And (Flag is TRectangle) then Begin TRectangle(Flag).Fill.Bitmap.Bitmap.LoadFromStream(FlagStream); End; Finally FlagStream.Free; End; End; End; Except On E:Exception Do Begin fDebug.AddExceptionLog('Exception! | '+Self.Name+'.ListBox_CountryList_OnApplyItemStyleLookup -> '+E.Message); End; End; End;
  7. okoca

    FMX Android Mouse pos X , Y and keyboard event

    hi, its usage is shown below, it would be better if you add a short pause between mouse down and up event (sleep(ms)). if your question is to click somewhere on the android screen rather than in the form (for example running as a background service) this will not work. http://git.kngstr.com/KngStr/delphi-fixes/src/b80b30a708f89ee5e1bbc457af248e69869a2ad4/10.3.1/Fixes/FMX.Presentation.Android.pas if EventAction = TJMotionEvent.JavaClass.ACTION_DOWN then begin Form.MouseMove([ssTouch], TouchPoint.X, TouchPoint.Y); Form.MouseMove([], TouchPoint.X, TouchPoint.Y); // Require for correct IsMouseOver handle Form.MouseDown(TMouseButton.mbLeft, [ssLeft, ssTouch], TouchPoint.x, TouchPoint.y); end else if EventAction = TJMotionEvent.JavaClass.ACTION_MOVE then begin ProcessMoveActiveGestures; Form.MouseMove([ssLeft, ssTouch], TouchPoint.x, TouchPoint.y) end else if EventAction = TJMotionEvent.JavaClass.ACTION_CANCEL then begin FinishActiveGestures; Form.MouseUp(TMouseButton.mbLeft, [ssLeft, ssTouch], TouchPoint.x, TouchPoint.y, False); // In MouseUp the form can unload presentation! if Form <> nil then Form.MouseLeave; end else if EventAction = TJMotionEvent.JavaClass.ACTION_UP then begin FinishActiveGestures; Form.MouseUp(TMouseButton.mbLeft, [ssLeft, ssTouch], TouchPoint.x, TouchPoint.y); // In MouseUp the form can unload presentation! if Form <> nil then Form.MouseLeave; end;
  8. okoca

    Fmx Android Service Segmentation Fault (11)

    hey dave, thank you for your long support and contribution to the delphi community, take care.
  9. okoca

    Fmx Android Service Segmentation Fault (11)

    I'm glad that the problem has been resolved. On the service side, we cannot use many fmx objects and units, so it is necessary to solve the problem with the native functions of the platform, many people don't know or ignore this situation, they think it's like development fmx gui app, and they're dealing with problems. for abount timer, you can check the here. https://github.com/grijjy/DelphiPlatformTimerQueue
  10. okoca

    Fmx Android Service Segmentation Fault (11)

    Hello, which Delphi version are you using? what is android device version, it can be tested more easily if you prepare and share a simple demo that shows the problem.