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

Запись и сохранение голоса в течение 10 секунд после запуска Android сервиса (Пример)


Pax Beach

Вопрос

Я реализовал пример работы с микрофоном и таймером в Android сервисе, как указано в теме вопроса.

Каждый раз, когда вы отправляете в сервис StartCommand или сервис перезапускается, включается запись с микрофона, и сохраняется в каталог с музыков в файл "myrecord.3gp".

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

Для отладки своих программ на Android используйте запись в LOGI и чтение при помощи monitor.bat (PlatformSDKs\android-sdk-windows\tools).

 

uses
  ...
  AndroidApi.JNI.Media, // JMediaRecorder
  AndroidApi.Timer, // Timer
  ...;

Const
  TimerInterval = 1000;
  TimerCounterSecLimit = 10;

type
  TDM = class(TAndroidService)
    ...
  private
    FTimerHandle: Integer;
    FRecording: Boolean;

    procedure StartRecord;
    procedure StopRecord;

    procedure StartTimer;
    procedure StopTimer;
  public
    FAudioRec: JMediaRecorder;
  end;

procedure Log(const Fmt: string; const Params: array of const); overload;
var
  Msg: string;
  M: TMarshaller;
begin
  Msg := Format(Fmt, Params);
  LOGI(M.AsUtf8(Msg).ToPointer);
end;

procedure Log(const Source: string); overload;
var
  M: TMarshaller;
begin
  LOGI(M.AsUtf8(Source).ToPointer);
end;

procedure TDM.AndroidServiceCreate(Sender: TObject);
begin
  FTimerHandle := 0;
  FTimerCounter := 0;
  FRecording := false;
end;

procedure TDM.AndroidServiceDestroy(Sender: TObject);
begin
  StopTimer;
  StopRecord;
end;

function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then
  begin
    StopTimer;
    StopRecord;
    Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service
    Log('- service stoped', []);
  end
  else begin
    if not FRecording then
    begin
        Log('... sound record to be started', []);
        StartRecord;
        StartTimer;
    end;

    Result := TJService.JavaClass.START_STICKY; // rerun service if it stops
    Log('+ Service started', []);
  end;
end;

procedure TDM.StartRecord;
begin
  StopRecord;

  FAudioRec := TJMediaRecorder.Create;
  FAudioRec.setAudioSource(TJMediaRecorder_AudioSource.JavaClass.MIC);
  FAudioRec.setOutputFormat(TJMediaRecorder_OutputFormat.JavaClass.THREE_GPP);
  FAudioRec.setAudioEncoder(TJMediaRecorder_AudioEncoder.JavaClass.AMR_NB);
  FAudioRec.setOutputFile(StringToJString(TPath.Combine(TPath.GetSharedMusicPath, 'myrecord.3gp')));
  try
    FAudioRec.Prepare();
    FAudioRec.start;
    FRecording := True;
    Log('+ Start record to %s', [TPath.Combine(TPath.GetSharedMusicPath, 'myrecord.3gp')]);
  except
    on E: Exception do
      Log('- Error in mic recording: %s', [E.Message]);
  end;
end;

procedure TDM.StopRecord;
begin
  if Assigned(FAudioRec) then
  begin
    if FRecording then
    begin
      FRecording := false;
      try
        FAudioRec.stop();
        FAudioRec.release();
        Log('- Mic recording is stoped');
      except
        on E: Exception do
          Log('- Error in mic stop recording: %s', [E.Message]);
      end;
    end;
  end
  else
  begin
    FRecording := false;
  end;
end;

procedure TDM.WaitComplete(TimerId: Integer);
begin
  if FTimerCounter < TimerCounterSecLimit then
  begin
    Log('+++ Timer is triggered %d time.', [FTimerCounter]);
    inc(FTimerCounter);
  end
  else
    StopTimer;
end;

procedure TDM.StartTimer;
begin
  FTimerCounter := 0;
  if FTimerHandle = 0 then
  begin
    FTimerHandle := AndroidTimerCreate;
    AndroidTimerSetInterval(FTimerHandle, TimerInterval);
  end;
  AndroidTimerSetHandler(WaitComplete);

  Log('+ Timer started', []);
end;

procedure TDM.StopTimer;
begin
  if FTimerHandle > 0 then
  begin
    Log('... MIC recording to be stopped');
    StopRecord;

    AndroidTimerSetHandler(nil);
    Log('- Timer stoped', []);
  end;
end;

end.

 

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

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

  • 0

Большое спасибо за такой пример!

Попробовал реализовать у себя - не создается файл. Все действия орабатываются, лог пишется (дополнял логированием после каждого шага - все в порядке). Сервис тоже "не падает" - работает. Но файла на выходе нет :( Ни по имени файла (с полным путем), ни по поиску файла на устройстве :(

Разрешения присутствуют (и на запись/чтение файлового хранилища и на запись аудио).

В чем может быть проблема?

RAD Studio 10.1 upd.2 Win8.1

 

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

Сто пятьсот причин. Я бы плясал от версии андроид, наличие прав на сохранение файлов у приложения, куда приложение установлено, куда пишется файл.

Примерно в такой последовательности.

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

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

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

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

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

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

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

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

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

×
×
  • Создать...