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

[Android]Входящий звонок


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 Где ошибка?

Спасибо.

 

 

Изменено пользователем Ingalime
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

И так не работает:

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 не происходит. :(

Изменено пользователем Ingalime
Ссылка на комментарий
  • 0

Вам не нужно этого делать, вам нужно обрабатывать потерю аудиофокуса. Код корявый лень в порядок приводить...

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;

 

Изменено пользователем OnePeople
Ссылка на комментарий
  • 0

Извините, не совсем понятно с потерей фокуса. Приложение имеет службу переднего фона. Приложение может быть свернуто, но музыка все равно будет играть. Так работают все плееры и мой также. При входящем звонке хочу остановить воспроизведение. Сейчас музыка продолжает играть при разговоре по телефону.

Ссылка на комментарий
  • 0
В 11.08.2021 в 15:46, Ingalime сказал:

Извините, не совсем понятно с потерей фокуса. Приложение имеет службу переднего фона. Приложение может быть свернуто, но музыка все равно будет играть. Так работают все плееры и мой также. При входящем звонке хочу остановить воспроизведение. Сейчас музыка продолжает играть при разговоре по телефону.

Думаю, что правильнее и проще всего будет добавить в приложение ресивер, и подписаться на событие входящего вызова, ну, и далее, скажем, в сервис интент отправить, или в приложение, или еще что сделать

Ссылка на комментарий
  • 0
В 11.08.2021 в 15:46, Ingalime сказал:

Извините, не совсем понятно с потерей фокуса. Приложение имеет службу переднего фона. Приложение может быть свернуто, но музыка все равно будет играть. Так работают все плееры и мой также. При входящем звонке хочу остановить воспроизведение. Сейчас музыка продолжает играть при разговоре по телефону.

Ну смотрите, вообще любой нормальный плеер когда начинает играть запрашивает фокус себе, чтобы другие приложения приостановили проигрывание, когда происходит звонок приложение телефон также забирает аудио фокус себе, ваше задача отловить этот момент, при внедрении этого кода, ваше приложение будет останавливать проигрывание когда потеряет фокус. Во первых это единственно правильный метод. Во вторых ваше приложение будет останавливать проигрывание и при запуске видео в Ютуб, или входящем звонке с мессенджеров.

Ссылка на комментарий
  • 0
15 часов назад, mazayhin сказал:

Думаю, что правильнее и проще всего будет добавить в приложение ресивер, и подписаться на событие входящего вызова, ну, и далее, скажем, в сервис интент отправить, или в приложение, или еще что сделать

Правильнее через аудио фокус!

Ссылка на комментарий
  • 0

Здравствуйте. После добавления кода было много чего красным подчеркнуто. Помогло добавление в uses Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, AndroidApi.JNI.Media

Однако по прежнему пишет что не определен тип JHandler / TJHandler Что надо добавить?

И такой вопрос: как реализовано  LogCAAdd и когда первый раз вызываем TForm1.GetAudioFocus;?

Спасибо.

Изменено пользователем Ingalime
Ссылка на комментарий
  • 0
6 часов назад, Ingalime сказал:

не определен тип JHandler / TJHandler

Androidapi.JNI.Os;

6 часов назад, Ingalime сказал:

LogCAAdd

Мой лог вам не нужно

 

6 часов назад, Ingalime сказал:

когда первый раз вызываем TForm1.GetAudioFocus;

Каждый раз когда запускаете проигрывание файла

Ссылка на комментарий
  • 0
23 минуты назад, OnePeople сказал:

Каждый раз когда запускаете проигрывание файла

Подскажите, пожалуйста, не будет ли утечки памяти, если пользователь несколько раз подряд нажмёт кнопку воспроизведения?

Ссылка на комментарий
  • 0

Подскажите, пожалуйста, как убрать ошибку Undeclared indentifier: 'FAudioManager' на строке:

res := FAudioManager.requestAudioFocus(AudioFocusRequest);

И тут хотелоcь бы уточнить, вопрос в коде:

if  (focusChange=TJaudioManager.JavaClass.AUDIOFOCUS_LOSS) then // фокус потерян
        begin    
           // music stop // действия если фокус потерян
           // тут будет обращение к визуальным компонетам. Это не безопасно?
           // или надо тут обернуть в TThread.Queue?
        end;

 

Изменено пользователем Ingalime
Ссылка на комментарий
  • 0

 в 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;

Ссылка на комментарий
  • 0
В 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;

 

Тут вы делаете что хотите, хоть обращаетесь к визуальным компонентам хоть нет, главное чтобы вы остановили воспроизведение!

Ссылка на комментарий
  • 0

Что-то никак не получается. При добавлении 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
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

А какие файлы скинуть? Проект большой. Содержит файлы SO, библиотеки BASS, картинки. Все работает, только осталось входящий звонок реализовать.

Изменено пользователем Ingalime
Ссылка на комментарий
  • 0

 

 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

Мне кажется, что у меня где-то неправильно расположены объявления, потому что подчеркивает бессмысленные вещи. Сейчас после полной вставки кода стал подчеркивать красным использование другого юнита 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
2 часа назад, Ingalime сказал:

Сейчас после полной вставки кода стал подчеркивать красным использование другого юнита uses UnitDonate;  в Structure пишет (E2029 Declaration expected but 'USES' found at line 188 (188:1)) и дальше по коду подчеркивает во всех функциях конструкцию со скобкой end);

перенесите

{$R *.fmx}

uses UnitDonate;

сразу после implementation

Ссылка на комментарий
  • 0

Спасибо, теперь все компилируется. Однако:

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

На андроид 8.1 все отлично. На андроид 7.1 приложение выпадает в черный экран с продолжением играет музыку и чтобы его закрыть надо идти в настроки стстемы и там его можно закрыть.

Видимо получение фокуса зависит от версии андроид.

Ссылка на комментарий
  • 0
    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;

 

Ссылка на комментарий

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...