Ingalime Опубликовано 10 августа, 2021 Поделиться Опубликовано 10 августа, 2021 (изменено) Здравствуйте. Мне надо при входящем звонке остановить музыку в плеере. Согласно документации получился такой код: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Mobile_Tutorial:_Using_the_Phone_Dialer_on_Mobile_Devices_(iOS_and_Android) unit Unitcall; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Platform, FMX.PhoneDialer; type TForm1 = class(TForm) private { Private declarations } PhoneDialerService: IFMXPhoneDialerService; procedure MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState); public { Public declarations } constructor Create(AOwner: TComponent); override; end; var Form1: TForm1; implementation {$R *.fmx} constructor TForm1.Create(AOwner: TComponent); begin inherited Create(AOwner); TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDialerService)); if Assigned(PhoneDialerService) then PhoneDialerService.OnCallStateChanged := MyOnCallStateChanged; end; procedure TForm1.MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState); var outText: String; Begin case ACallState of TCallState.Incoming: Button2Click(self);//стоп play не отрабатывает end; End; procedure TForm1.Button2Click(Sender: TObject); begin OverflowMenu.Visible := False; Text1.Text := ''; FloatAnimation1.Enabled := False; Viewport3D1.Visible := False; AniIndicator1.Enabled := FALSE; AniIndicator1.Visible := FALSE; BASS_ChannelStop(str); BASS_StreamFree(str); end; procedure TForm1.FormCreate(Sender: TObject); Begin if not BASS_Init(-1, 44100, 0, nil, nil) Then Begin ShowMessage('Failed to initialize audio!' + sLineBreak + 'Не удалось инициализировать audio!'); Exit; end; try if FService = Nil Then Begin FService := TLocalServiceConnection.Create; FService.StartService('serPublic'); end; except Exit; end; //******************************* Ничего не происходит при входящем звонке. Дебагер с моим телефоном не работает. Разрешение READ_PHONE_STATE установлено. RAD 10.4 Где ошибка? Спасибо. Изменено 10 августа, 2021 пользователем Ingalime Цитата Ссылка на комментарий
0 Ingalime Опубликовано 10 августа, 2021 Автор Поделиться Опубликовано 10 августа, 2021 (изменено) И так не работает: procedure TForm1.MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState); var outText: String; Begin case ACallState of TCallState.Incoming: Begin TThread.Queue(nil, procedure begin OverflowMenu.Visible := False; Text1.Text := 'Входящий звонок'; FloatAnimation1.Enabled := False; Viewport3D1.Visible := False; AniIndicator1.Enabled := FALSE; AniIndicator1.Visible := FALSE; BASS_ChannelStop(str); BASS_StreamFree(str); end ); End; end; End; Расставляя текстовые метки для проверки выяснилось что при входящем звонке событие MyOnCallStateChanged не происходит. Изменено 10 августа, 2021 пользователем Ingalime Цитата Ссылка на комментарий
0 OnePeople Опубликовано 11 августа, 2021 Поделиться Опубликовано 11 августа, 2021 (изменено) Вам не нужно этого делать, вам нужно обрабатывать потерю аудиофокуса. Код корявый лень в порядок приводить... type TMyAudioFocusChangeListener = class; // Создаем класс прослушивания фокуса аудио TForm1 = class(TForm) ... private { Private declarations } afChangeListener: TMyAudioFocusChangeListener; Создаем переменную прослушивания фокуса аудио ... public procedure GetAudioFocus; procedure onAudioFocusChange(focusChange: Integer); end; TAudioFocusChangeEvent = procedure(focusChange: Integer) of object; // описания события изменения фокуса TMyAudioFocusChangeListener = class(TJavaLocal, JAudioManager_OnAudioFocusChangeListener) // описание класса прослушивания фокуса аудио private [weak] FParent : TForm1; FOnAudioFocusChanged: TAudioFocusChangeEvent; public constructor Create(AParent : TForm1); property OnAudioFocusChanged: TAudioFocusChangeEvent read FOnAudioFocusChanged write FOnAudioFocusChanged; Destructor Destroy; Override; procedure onAudioFocusChange(focusChange: Integer); cdecl; end; var Form1: TForm1; AuFocus: JAudioManager_OnAudioFocusChangeListener; JAudioManagerListener: TMyAudioFocusChangeListener; implementation constructor TMyAudioFocusChangeListener.Create; // создание класса begin inherited Create; FParent := AParent; end; destructor TMyAudioFocusChangeListener.Destroy; // уничтожение класса begin inherited; end; procedure TMyAudioFocusChangeListener.onAudioFocusChange(focusChange: Integer); // событие изменения фокуса begin if Assigned(FOnAudioFocusChanged) then begin FOnAudioFocusChanged(focusChange); // передача события изменения фокуса end; FParent.onAudioFocusChange(focusChange); // вызов процедуры изменения фокуса формы end; procedure TForm1.onAudioFocusChange(focusChange: Integer); //процедура изменения фокуса формы begin if (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then // фокус потерян begin // music stop // действия если фокус потерян end; end; procedure TForm1.GetAudioFocus; // получаем фокус для своего приложения begin CallinUIThread(procedure var AudioFocusRequest: JAudioFocusRequest; playbackAttributes: JAudioAttributes; afHandler: JHandler; res: integer; begin afChangeListener := TMyAudioFocusChangeListener.Create(Self); // создаем класс прослушивания аудио фокуса для своего приложения afHandler := TJHandler.Create; // создаем указатель своего приложения playbackAttributes := TJAudioAttributes_Builder.Create // создаем параметры прослушивания аудио фокуса .setUsage(TJAudioAttributes.JavaClass.USAGE_MEDIA) .setContentType(TJAudioAttributes.JavaClass.CONTENT_TYPE_MUSIC) .build(); AudioFocusRequest := TJAudioFocusRequest_Builder(TJAudioManager.JavaClass.AUDIOFOCUS_GAIN).Create // создаем запрос с параметрами прослушивания аудио фокуса .setAudioAttributes(playbackAttributes) .setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(afChangeListener, afHandler) .build(); res := FAudioManager.requestAudioFocus(AudioFocusRequest); // непосредственно запрашиваем фокус if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_DELAYED then // отказано else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_GRANTED then begin //фокус получен LogCAAdd('AUDIOFOCUS_REQUEST_GRANTED'); end else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_FAILED then // отказано LogCAAdd('AUDIOFOCUS_REQUEST_FAILED'); end ); end; Изменено 6 сентября, 2021 пользователем OnePeople Semitako и Ingalime 2 Цитата Ссылка на комментарий
0 Ingalime Опубликовано 11 августа, 2021 Автор Поделиться Опубликовано 11 августа, 2021 Извините, не совсем понятно с потерей фокуса. Приложение имеет службу переднего фона. Приложение может быть свернуто, но музыка все равно будет играть. Так работают все плееры и мой также. При входящем звонке хочу остановить воспроизведение. Сейчас музыка продолжает играть при разговоре по телефону. Цитата Ссылка на комментарий
0 mazayhin Опубликовано 12 августа, 2021 Поделиться Опубликовано 12 августа, 2021 В 11.08.2021 в 15:46, Ingalime сказал: Извините, не совсем понятно с потерей фокуса. Приложение имеет службу переднего фона. Приложение может быть свернуто, но музыка все равно будет играть. Так работают все плееры и мой также. При входящем звонке хочу остановить воспроизведение. Сейчас музыка продолжает играть при разговоре по телефону. Думаю, что правильнее и проще всего будет добавить в приложение ресивер, и подписаться на событие входящего вызова, ну, и далее, скажем, в сервис интент отправить, или в приложение, или еще что сделать Ingalime 1 Цитата Ссылка на комментарий
0 OnePeople Опубликовано 13 августа, 2021 Поделиться Опубликовано 13 августа, 2021 В 11.08.2021 в 15:46, Ingalime сказал: Извините, не совсем понятно с потерей фокуса. Приложение имеет службу переднего фона. Приложение может быть свернуто, но музыка все равно будет играть. Так работают все плееры и мой также. При входящем звонке хочу остановить воспроизведение. Сейчас музыка продолжает играть при разговоре по телефону. Ну смотрите, вообще любой нормальный плеер когда начинает играть запрашивает фокус себе, чтобы другие приложения приостановили проигрывание, когда происходит звонок приложение телефон также забирает аудио фокус себе, ваше задача отловить этот момент, при внедрении этого кода, ваше приложение будет останавливать проигрывание когда потеряет фокус. Во первых это единственно правильный метод. Во вторых ваше приложение будет останавливать проигрывание и при запуске видео в Ютуб, или входящем звонке с мессенджеров. Ingalime, mazayhin и Semitako 2 1 Цитата Ссылка на комментарий
0 OnePeople Опубликовано 13 августа, 2021 Поделиться Опубликовано 13 августа, 2021 15 часов назад, mazayhin сказал: Думаю, что правильнее и проще всего будет добавить в приложение ресивер, и подписаться на событие входящего вызова, ну, и далее, скажем, в сервис интент отправить, или в приложение, или еще что сделать Правильнее через аудио фокус! mazayhin 1 Цитата Ссылка на комментарий
0 Ingalime Опубликовано 8 сентября, 2021 Автор Поделиться Опубликовано 8 сентября, 2021 (изменено) Здравствуйте. После добавления кода было много чего красным подчеркнуто. Помогло добавление в uses Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, AndroidApi.JNI.Media Однако по прежнему пишет что не определен тип JHandler / TJHandler Что надо добавить? И такой вопрос: как реализовано LogCAAdd и когда первый раз вызываем TForm1.GetAudioFocus;? Спасибо. Изменено 8 сентября, 2021 пользователем Ingalime Цитата Ссылка на комментарий
0 OnePeople Опубликовано 8 сентября, 2021 Поделиться Опубликовано 8 сентября, 2021 6 часов назад, Ingalime сказал: не определен тип JHandler / TJHandler Androidapi.JNI.Os; 6 часов назад, Ingalime сказал: LogCAAdd Мой лог вам не нужно 6 часов назад, Ingalime сказал: когда первый раз вызываем TForm1.GetAudioFocus; Каждый раз когда запускаете проигрывание файла Ingalime 1 Цитата Ссылка на комментарий
0 Ingalime Опубликовано 8 сентября, 2021 Автор Поделиться Опубликовано 8 сентября, 2021 23 минуты назад, OnePeople сказал: Каждый раз когда запускаете проигрывание файла Подскажите, пожалуйста, не будет ли утечки памяти, если пользователь несколько раз подряд нажмёт кнопку воспроизведения? Цитата Ссылка на комментарий
0 Ingalime Опубликовано 9 сентября, 2021 Автор Поделиться Опубликовано 9 сентября, 2021 (изменено) Подскажите, пожалуйста, как убрать ошибку Undeclared indentifier: 'FAudioManager' на строке: res := FAudioManager.requestAudioFocus(AudioFocusRequest); И тут хотелоcь бы уточнить, вопрос в коде: if (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then // фокус потерян begin // music stop // действия если фокус потерян // тут будет обращение к визуальным компонетам. Это не безопасно? // или надо тут обернуть в TThread.Queue? end; Изменено 9 сентября, 2021 пользователем Ingalime Цитата Ссылка на комментарий
0 OnePeople Опубликовано 10 сентября, 2021 Поделиться Опубликовано 10 сентября, 2021 в OnCreate {$IFDEF ANDROID} if FAudioService=nil then begin FAudioService:= TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.AUDIO_SERVICE); if FAudioService <> nil then begin FAudioManager := TJAudioManager.Wrap((FAudioService as ILocalObject).GetObjectID); end; end; {$ENDIF} Общая переменная var FAudioManager: JAudioManager; Ingalime 1 Цитата Ссылка на комментарий
0 OnePeople Опубликовано 10 сентября, 2021 Поделиться Опубликовано 10 сентября, 2021 В 09.09.2021 в 13:48, Ingalime сказал: Подскажите, пожалуйста, как убрать ошибку Undeclared indentifier: 'FAudioManager' на строке: res := FAudioManager.requestAudioFocus(AudioFocusRequest); И тут хотелоcь бы уточнить, вопрос в коде: if (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then // фокус потерян begin // music stop // действия если фокус потерян // тут будет обращение к визуальным компонетам. Это не безопасно? // или надо тут обернуть в TThread.Queue? end; Тут вы делаете что хотите, хоть обращаетесь к визуальным компонентам хоть нет, главное чтобы вы остановили воспроизведение! Ingalime 1 Цитата Ссылка на комментарий
0 Ingalime Опубликовано 11 сентября, 2021 Автор Поделиться Опубликовано 11 сентября, 2021 Что-то никак не получается. При добавлении FAudioManager: JAudioManager; получаю Declaration expected but 'USES' found at line unit UnitMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, bass, FMX.Objects, FMX.Layouts, FMX.Helpers.Android, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App, Androidapi.JNI.Net, System.Math.Vectors, FMX.Ani, FMX.MaterialSources, FMX.Controls3D, FMX.Objects3D, FMX.Viewport3D, System.Net.HttpClient.Android, System.Net.HttpClient, System.Actions, FMX.ActnList, FMX.StdActns, FMX.MediaLibrary.Actions, System.Threading, FMX.Effects, FMX.ListBox, System.Android.Service, FMX.Platform.Android, System.Notification, FMX.Platform, FMX.PhoneDialer, Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, AndroidApi.JNI.Media, Androidapi.JNI.Os; type TMyAudioFocusChangeListener = class; // Создаем класс прослушивания фокуса аудио TForm1 = class(TForm) StyleBook1: TStyleBook; ToolBar1: TToolBar; ToolBar2: TToolBar; Button1: TButton; Button2: TButton; Layout1: TLayout; TrackBar1: TTrackBar; Layout2: TLayout; Layout3: TLayout; Label1: TLabel; Image1: TImage; Rectangle1: TRectangle; Rectangle2: TRectangle; Label2: TLabel; Viewport3D1: TViewport3D; Sphere1: TSphere; TextureMaterialSource1: TTextureMaterialSource; FloatAnimation1: TFloatAnimation; Image2: TImage; Text1: TText; OverflowButton: TButton; ActionList1: TActionList; ShowShareSheetAction1: TShowShareSheetAction; Layout4: TLayout; ProgressBar1: TProgressBar; Label3: TLabel; OverflowMenu: TListBox; ListBoxItem1: TListBoxItem; ListBoxItem2: TListBoxItem; ListBoxItem3: TListBoxItem; ShadowEffect1: TShadowEffect; AniIndicator1: TAniIndicator; Button3: TButton; Image3: TImage; ListBoxItem4: TListBoxItem; NotificationCenter1: TNotificationCenter; Label4: TLabel; Layout5: TLayout; procedure Label1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ListBoxItem1Click(Sender: TObject); procedure ListBoxItem2Click(Sender: TObject); procedure ListBoxItem3Click(Sender: TObject); procedure OverflowButtonClick(Sender: TObject); procedure Image3Click(Sender: TObject); procedure ListBoxItem4Click(Sender: TObject); procedure Label4Click(Sender: TObject); private { Private declarations } FService: TLocalServiceConnection; afChangeListener: TMyAudioFocusChangeListener; //Создаем переменную прослушивания фокуса аудио public { Public declarations } procedure GetAudioFocus; procedure onAudioFocusChange(focusChange: Integer); end; TAudioFocusChangeEvent = procedure(focusChange: Integer) of object; // описания события изменения фокуса TMyAudioFocusChangeListener = class(TJavaLocal, JAudioManager_OnAudioFocusChangeListener) // описание класса прослушивания фокуса аудио private [weak] FParent : TForm1; FOnAudioFocusChanged: TAudioFocusChangeEvent; public constructor Create(AParent : TForm1); property OnAudioFocusChanged: TAudioFocusChangeEvent read FOnAudioFocusChanged write FOnAudioFocusChanged; Destructor Destroy; Override; procedure onAudioFocusChange(focusChange: Integer); cdecl; end; var Form1: TForm1; AuFocus: JAudioManager_OnAudioFocusChangeListener; JAudioManagerListener: TMyAudioFocusChangeListener; FAudioManager: JAudioManager; smp: HSAMPLE; str: HSTREAM; MyNotification: TNotification; implementation //***************** constructor TMyAudioFocusChangeListener.Create; // создание класса begin inherited Create; FParent := AParent; end; //и т.д. Где я ошибаюсь? Спасибо. Цитата Ссылка на комментарий
0 OnePeople Опубликовано 11 сентября, 2021 Поделиться Опубликовано 11 сентября, 2021 1 час назад, Ingalime сказал: Что-то никак не получается. При добавлении FAudioManager: JAudioManager; получаю Declaration expected but 'USES' found at line unit UnitMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, bass, FMX.Objects, FMX.Layouts, FMX.Helpers.Android, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App, Androidapi.JNI.Net, System.Math.Vectors, FMX.Ani, FMX.MaterialSources, FMX.Controls3D, FMX.Objects3D, FMX.Viewport3D, System.Net.HttpClient.Android, System.Net.HttpClient, System.Actions, FMX.ActnList, FMX.StdActns, FMX.MediaLibrary.Actions, System.Threading, FMX.Effects, FMX.ListBox, System.Android.Service, FMX.Platform.Android, System.Notification, FMX.Platform, FMX.PhoneDialer, Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, AndroidApi.JNI.Media, Androidapi.JNI.Os; type TMyAudioFocusChangeListener = class; // Создаем класс прослушивания фокуса аудио TForm1 = class(TForm) StyleBook1: TStyleBook; ToolBar1: TToolBar; ToolBar2: TToolBar; Button1: TButton; Button2: TButton; Layout1: TLayout; TrackBar1: TTrackBar; Layout2: TLayout; Layout3: TLayout; Label1: TLabel; Image1: TImage; Rectangle1: TRectangle; Rectangle2: TRectangle; Label2: TLabel; Viewport3D1: TViewport3D; Sphere1: TSphere; TextureMaterialSource1: TTextureMaterialSource; FloatAnimation1: TFloatAnimation; Image2: TImage; Text1: TText; OverflowButton: TButton; ActionList1: TActionList; ShowShareSheetAction1: TShowShareSheetAction; Layout4: TLayout; ProgressBar1: TProgressBar; Label3: TLabel; OverflowMenu: TListBox; ListBoxItem1: TListBoxItem; ListBoxItem2: TListBoxItem; ListBoxItem3: TListBoxItem; ShadowEffect1: TShadowEffect; AniIndicator1: TAniIndicator; Button3: TButton; Image3: TImage; ListBoxItem4: TListBoxItem; NotificationCenter1: TNotificationCenter; Label4: TLabel; Layout5: TLayout; procedure Label1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ListBoxItem1Click(Sender: TObject); procedure ListBoxItem2Click(Sender: TObject); procedure ListBoxItem3Click(Sender: TObject); procedure OverflowButtonClick(Sender: TObject); procedure Image3Click(Sender: TObject); procedure ListBoxItem4Click(Sender: TObject); procedure Label4Click(Sender: TObject); private { Private declarations } FService: TLocalServiceConnection; afChangeListener: TMyAudioFocusChangeListener; //Создаем переменную прослушивания фокуса аудио public { Public declarations } procedure GetAudioFocus; procedure onAudioFocusChange(focusChange: Integer); end; TAudioFocusChangeEvent = procedure(focusChange: Integer) of object; // описания события изменения фокуса TMyAudioFocusChangeListener = class(TJavaLocal, JAudioManager_OnAudioFocusChangeListener) // описание класса прослушивания фокуса аудио private [weak] FParent : TForm1; FOnAudioFocusChanged: TAudioFocusChangeEvent; public constructor Create(AParent : TForm1); property OnAudioFocusChanged: TAudioFocusChangeEvent read FOnAudioFocusChanged write FOnAudioFocusChanged; Destructor Destroy; Override; procedure onAudioFocusChange(focusChange: Integer); cdecl; end; var Form1: TForm1; AuFocus: JAudioManager_OnAudioFocusChangeListener; JAudioManagerListener: TMyAudioFocusChangeListener; FAudioManager: JAudioManager; smp: HSAMPLE; str: HSTREAM; MyNotification: TNotification; implementation //***************** constructor TMyAudioFocusChangeListener.Create; // создание класса begin inherited Create; FParent := AParent; end; //и т.д. Где я ошибаюсь? Спасибо. Скиньте проект посмотреть Цитата Ссылка на комментарий
0 Ingalime Опубликовано 11 сентября, 2021 Автор Поделиться Опубликовано 11 сентября, 2021 (изменено) А какие файлы скинуть? Проект большой. Содержит файлы SO, библиотеки BASS, картинки. Все работает, только осталось входящий звонок реализовать. Изменено 12 сентября, 2021 пользователем Ingalime Цитата Ссылка на комментарий
0 OnePeople Опубликовано 11 сентября, 2021 Поделиться Опубликовано 11 сентября, 2021 var FAudioService: JObject; FAudioManager: JAudioManager; в OnCreate {$IFDEF ANDROID} if FAudioService=nil then begin FAudioService:= TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.AUDIO_SERVICE); if FAudioService <> nil then begin FAudioManager := TJAudioManager.Wrap((FAudioService as ILocalObject).GetObjectID); end; end; {$ENDIF} Не знаю чем вам помочь, на какую строку ругается? Цитата Ссылка на комментарий
0 Ingalime Опубликовано 15 сентября, 2021 Автор Поделиться Опубликовано 15 сентября, 2021 Мне кажется, что у меня где-то неправильно расположены объявления, потому что подчеркивает бессмысленные вещи. Сейчас после полной вставки кода стал подчеркивать красным использование другого юнита uses UnitDonate; в Structure пишет (E2029 Declaration expected but 'USES' found at line 188 (188:1)) и дальше по коду подчеркивает во всех функциях конструкцию со скобкой end); Если вы не видите ошибку, то можно ваш pas файл выложить с кодом только аудиофокуса? Попробую сравнить что у меня не так. Спасибо. unit UnitMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, bass, FMX.Objects, FMX.Layouts, FMX.Helpers.Android, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App, Androidapi.JNI.Net, System.Math.Vectors, FMX.Ani, FMX.MaterialSources, FMX.Controls3D, FMX.Objects3D, FMX.Viewport3D, System.Net.HttpClient.Android, System.Net.HttpClient, System.Actions, FMX.ActnList, FMX.StdActns, FMX.MediaLibrary.Actions, System.Threading, FMX.Effects, FMX.ListBox, System.Android.Service, FMX.Platform.Android, System.Notification, FMX.Platform, FMX.PhoneDialer, Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, AndroidApi.JNI.Media, Androidapi.JNI.Os; type TMyAudioFocusChangeListener = class; // Создаем класс прослушивания фокуса аудио TForm1 = class(TForm) StyleBook1: TStyleBook; ToolBar1: TToolBar; ToolBar2: TToolBar; Button1: TButton; Button2: TButton; Layout1: TLayout; TrackBar1: TTrackBar; Layout2: TLayout; Layout3: TLayout; Label1: TLabel; Image1: TImage; Rectangle1: TRectangle; Rectangle2: TRectangle; Label2: TLabel; Viewport3D1: TViewport3D; Sphere1: TSphere; TextureMaterialSource1: TTextureMaterialSource; FloatAnimation1: TFloatAnimation; Image2: TImage; Text1: TText; OverflowButton: TButton; ActionList1: TActionList; ShowShareSheetAction1: TShowShareSheetAction; Layout4: TLayout; ProgressBar1: TProgressBar; Label3: TLabel; OverflowMenu: TListBox; ListBoxItem1: TListBoxItem; ListBoxItem2: TListBoxItem; ListBoxItem3: TListBoxItem; ShadowEffect1: TShadowEffect; AniIndicator1: TAniIndicator; Button3: TButton; Image3: TImage; ListBoxItem4: TListBoxItem; NotificationCenter1: TNotificationCenter; Label4: TLabel; Layout5: TLayout; procedure Label1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ListBoxItem1Click(Sender: TObject); procedure ListBoxItem2Click(Sender: TObject); procedure ListBoxItem3Click(Sender: TObject); procedure OverflowButtonClick(Sender: TObject); procedure Image3Click(Sender: TObject); procedure ListBoxItem4Click(Sender: TObject); procedure Label4Click(Sender: TObject); private { Private declarations } FService: TLocalServiceConnection; //PhoneDialerService: IFMXPhoneDialerService; //call //procedure MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState); afChangeListener: TMyAudioFocusChangeListener; //Создаем переменную прослушивания фокуса аудио public { Public declarations } //constructor Create(AOwner: TComponent); override; //call procedure GetAudioFocus; procedure onAudioFocusChange(focusChange: Integer); end; TAudioFocusChangeEvent = procedure(focusChange: Integer) of object; // описания события изменения фокуса TMyAudioFocusChangeListener = class(TJavaLocal, JAudioManager_OnAudioFocusChangeListener) // описание класса прослушивания фокуса аудио private [weak] FParent : TForm1; FOnAudioFocusChanged: TAudioFocusChangeEvent; public constructor Create(AParent : TForm1); property OnAudioFocusChanged: TAudioFocusChangeEvent read FOnAudioFocusChanged write FOnAudioFocusChanged; Destructor Destroy; Override; procedure onAudioFocusChange(focusChange: Integer); cdecl; end; var Form1: TForm1; AuFocus: JAudioManager_OnAudioFocusChangeListener; JAudioManagerListener: TMyAudioFocusChangeListener; FAudioService: JObject; FAudioManager: JAudioManager; smp: HSAMPLE; str: HSTREAM; MyNotification: TNotification; implementation //***************** constructor TMyAudioFocusChangeListener.Create; // создание класса begin inherited Create; FParent := AParent; end; destructor TMyAudioFocusChangeListener.Destroy; // уничтожение класса begin inherited; end; procedure TMyAudioFocusChangeListener.onAudioFocusChange(focusChange: Integer); // событие изменения фокуса begin if Assigned(FOnAudioFocusChanged) then begin FOnAudioFocusChanged(focusChange); // передача события изменения фокуса end; FParent.onAudioFocusChange(focusChange); // вызов процедуры изменения фокуса формы end; procedure TForm1.onAudioFocusChange(focusChange: Integer); //процедура изменения фокуса формы begin if (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then // фокус потерян begin // music stop // действия если фокус потерян end; end; procedure TForm1.GetAudioFocus; // получаем фокус для своего приложения begin CallinUIThread(procedure var AudioFocusRequest: JAudioFocusRequest; playbackAttributes: JAudioAttributes; afHandler: JHandler; res: integer; begin afChangeListener := TMyAudioFocusChangeListener.Create(Self); // создаем класс прослушивания аудио фокуса для своего приложения afHandler := TJHandler.Create; // создаем указатель своего приложения playbackAttributes := TJAudioAttributes_Builder.Create // создаем параметры прослушивания аудио фокуса .setUsage(TJAudioAttributes.JavaClass.USAGE_MEDIA) .setContentType(TJAudioAttributes.JavaClass.CONTENT_TYPE_MUSIC) .build(); AudioFocusRequest := TJAudioFocusRequest_Builder(TJAudioManager.JavaClass.AUDIOFOCUS_GAIN).Create // создаем запрос с параметрами прослушивания аудио фокуса .setAudioAttributes(playbackAttributes) .setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(afChangeListener, afHandler) .build(); res := FAudioManager.requestAudioFocus(AudioFocusRequest); // непосредственно запрашиваем фокус if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_DELAYED then // отказано else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_GRANTED then begin //фокус получен //LogCAAdd('AUDIOFOCUS_REQUEST_GRANTED'); end else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_FAILED then // отказано //LogCAAdd('AUDIOFOCUS_REQUEST_FAILED'); end ); end; //****************** {$R *.fmx} uses UnitDonate; //красным подчеркивает //******************************* procedure TForm1.FormCreate(Sender: TObject); Begin if not BASS_Init(-1, 44100, 0, nil, nil) Then Begin ShowMessage('Failed to initialize audio!' + sLineBreak + 'Не удалось инициализировать audio!'); Exit; end; try if FService = Nil Then Begin FService := TLocalServiceConnection.Create; FService.StartService('serPublic'); end; except Exit; begin {$IFDEF ANDROID} if FAudioService=nil then begin FAudioService:= TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.AUDIO_SERVICE); if FAudioService <> nil then begin FAudioManager := TJAudioManager.Wrap((FAudioService as ILocalObject).GetObjectID); end; end; {$ENDIF} end; end; Цитата Ссылка на комментарий
0 Tumaso Опубликовано 15 сентября, 2021 Поделиться Опубликовано 15 сентября, 2021 2 часа назад, Ingalime сказал: Сейчас после полной вставки кода стал подчеркивать красным использование другого юнита uses UnitDonate; в Structure пишет (E2029 Declaration expected but 'USES' found at line 188 (188:1)) и дальше по коду подчеркивает во всех функциях конструкцию со скобкой end); перенесите {$R *.fmx} uses UnitDonate; сразу после implementation Ingalime 1 Цитата Ссылка на комментарий
0 Ingalime Опубликовано 16 сентября, 2021 Автор Поделиться Опубликовано 16 сентября, 2021 Спасибо, теперь все компилируется. Однако: else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_GRANTED then begin //фокус получен //LogCAAdd('AUDIOFOCUS_REQUEST_GRANTED'); ShowMessage('AUDIOFOCUS_REQUEST_GRANTED'); end else if res = TJAudioManager.JavaClass.AUDIOFOCUS_REQUEST_FAILED then // отказано //LogCAAdd('AUDIOFOCUS_REQUEST_FAILED'); ShowMessage('AUDIOFOCUS_REQUEST_FAILED'); end Вижу при нажатии на кнопку проигрывания сообщение AUDIOFOCUS_REQUEST_GRANTED Все нормально. Делаю звонок и поднимаю трубку. Музыку все равно слышно. Что-то мною упущено... if (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then // фокус потерян begin // music stop // действия если фокус потерян //код кнопки STOP OverflowMenu.Visible := False; Text1.Text := ''; FloatAnimation1.Enabled := False; Viewport3D1.Visible := False; AniIndicator1.Enabled := FALSE; AniIndicator1.Visible := FALSE; BASS_ChannelStop(str); BASS_StreamFree(str); ShowMessage('STOP OK');//тест - не вижу когда возвращаюсь в приложение положив трубку end; Цитата Ссылка на комментарий
0 OnePeople Опубликовано 18 сентября, 2021 Поделиться Опубликовано 18 сентября, 2021 if (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) or (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS_TRANSIENT) Ingalime 1 Цитата Ссылка на комментарий
0 Ingalime Опубликовано 19 ноября, 2021 Автор Поделиться Опубликовано 19 ноября, 2021 Спасибо буду пробовать. p.s. Болезни закончились, снова за работу. :) Цитата Ссылка на комментарий
0 Ingalime Опубликовано 12 декабря, 2021 Автор Поделиться Опубликовано 12 декабря, 2021 Спасибо все работает Цитата Ссылка на комментарий
0 Ingalime Опубликовано 14 декабря, 2021 Автор Поделиться Опубликовано 14 декабря, 2021 На андроид 8.1 все отлично. На андроид 7.1 приложение выпадает в черный экран с продолжением играет музыку и чтобы его закрыть надо идти в настроки стстемы и там его можно закрыть. Видимо получение фокуса зависит от версии андроид. Цитата Ссылка на комментарий
0 OnePeople Опубликовано 14 декабря, 2021 Поделиться Опубликовано 14 декабря, 2021 Да зависит, вам скинуть код? Цитата Ссылка на комментарий
0 OnePeople Опубликовано 14 декабря, 2021 Поделиться Опубликовано 14 декабря, 2021 if TJBuild_VERSION.JavaClass.SDK_INT >= 26 then begin playbackAttributes := TJAudioAttributes_Builder.Create .setUsage(TJAudioAttributes.JavaClass.USAGE_MEDIA) .setContentType(TJAudioAttributes.JavaClass.CONTENT_TYPE_MUSIC) .build(); AudioFocusRequest:=TJAudioFocusRequest_Builder(TJAudioManager.JavaClass.AUDIOFOCUS_GAIN).Create .setAudioAttributes(playbackAttributes) .setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(afChangeListener, afHandler) .build(); res := FAudioManager.requestAudioFocus(AudioFocusRequest); end else begin res := FAudioManager.requestAudioFocus(afChangeListener, TJAudioManager.JavaClass.STREAM_MUSIC, TJAudioManager.JavaClass.AUDIOFOCUS_GAIN); end; Semitako и Ingalime 1 1 Цитата Ссылка на комментарий
Вопрос
Ingalime
Здравствуйте. Мне надо при входящем звонке остановить музыку в плеере. Согласно документации получился такой код:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Mobile_Tutorial:_Using_the_Phone_Dialer_on_Mobile_Devices_(iOS_and_Android)
unit Unitcall; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Platform, FMX.PhoneDialer; type TForm1 = class(TForm) private { Private declarations } PhoneDialerService: IFMXPhoneDialerService; procedure MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState); public { Public declarations } constructor Create(AOwner: TComponent); override; end; var Form1: TForm1; implementation {$R *.fmx} constructor TForm1.Create(AOwner: TComponent); begin inherited Create(AOwner); TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDialerService)); if Assigned(PhoneDialerService) then PhoneDialerService.OnCallStateChanged := MyOnCallStateChanged; end; procedure TForm1.MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState); var outText: String; Begin case ACallState of TCallState.Incoming: Button2Click(self);//стоп play не отрабатывает end; End; procedure TForm1.Button2Click(Sender: TObject); begin OverflowMenu.Visible := False; Text1.Text := ''; FloatAnimation1.Enabled := False; Viewport3D1.Visible := False; AniIndicator1.Enabled := FALSE; AniIndicator1.Visible := FALSE; BASS_ChannelStop(str); BASS_StreamFree(str); end; procedure TForm1.FormCreate(Sender: TObject); Begin if not BASS_Init(-1, 44100, 0, nil, nil) Then Begin ShowMessage('Failed to initialize audio!' + sLineBreak + 'Не удалось инициализировать audio!'); Exit; end; try if FService = Nil Then Begin FService := TLocalServiceConnection.Create; FService.StartService('serPublic'); end; except Exit; end; //*******************************
Ничего не происходит при входящем звонке. Дебагер с моим телефоном не работает. Разрешение READ_PHONE_STATE установлено. RAD 10.4 Где ошибка?
Спасибо.
Ссылка на комментарий
25 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.