Ses girişi paylaşılıyor

Ses girişi genellikle yerleşik mikrofondan, harici bir mikrofondan veya cihaza bağlı bir ses arayüzünden gelir. Ses girişi, telefon görüşmesinden de gelebilir.

Bazen iki veya daha fazla uygulama aynı ses girişini "yakalamak" isteyebilir. Farklı görevler gerçekleştiriyor olabilirler. Örneğin, ses alan bazı uygulamalar basit bir ses kaydedici gibi "kayıt yapıyor" olabilirken, diğer uygulamalar Google Asistan veya sesli komutlara yanıt veren bir erişilebilirlik hizmeti gibi "dinliyor" olabilir.

Her iki durumda da bu uygulamalar ses girişi almak ister. Bu sayfada, bir uygulamanın kayıt yapıp yapmadığına veya yalnızca dinleyip dinlemediğine bakılmaksızın "yakalama" terimi kullanılmaktadır.

İki veya daha fazla uygulama aynı anda ses yakalamak isterse ses sinyalini aynı kaynaktan hepsine iletme konusunda sorun yaşanabilir. Bu sayfada, Android sisteminin ses girişi yakalayan birden fazla uygulama arasında ses girişini nasıl paylaştığı açıklanmaktadır.

Android 10 öncesi davranış

Android 10'dan önce, giriş ses akışı aynı anda yalnızca bir uygulama tarafından yakalanabiliyordu. Başka bir uygulama ses kaydı yapıyorsa veya sesi dinliyorsa uygulamanız bir AudioRecord nesnesi oluşturabilir ancak AudioRecord.startRecording() yöntemini çağırdığınızda hata döndürülür ve kayıt başlatılmaz.

Ayrıcalıklı bir uygulamanın (ör. Google Asistan veya bir erişilebilirlik hizmeti) android.permission.CAPTURE_AUDIO_HOTWORD iznine sahip olması ve HOTWORD türünde bir ses kaynağı kullanması bu kuralın istisnasıydı. Bu durumda başka bir uygulama kayda başlayabilir. Bu durumda ayrıcalıklı uygulama sonlandırılır ve yeni uygulama girişi yakalar.

Android 9'da bir değişiklik daha yapıldı: Yalnızca ön planda çalışan uygulamalar (veya ön plan hizmeti) ses girişini yakalayabiliyordu. Ön plan hizmeti veya ön plan kullanıcı arayüzü bileşeni olmayan bir uygulama ses kaydetmeye başladığında, o sırada ses kaydeden tek uygulama olsa bile çalışmaya devam eder ancak sessiz ses kaydederdi.

Android 10 davranışı

Android 10'dan önceki davranış "ilk gelen ilk hizmet alır" şeklindedir. Bir uygulama ses kaydetmeye başladığında, ses kaydeden uygulama durana kadar başka hiçbir uygulama ses girişine erişemez.

Android 10, uygulamalar çalışırken giriş ses akışını uygulamalar arasında değiştirebilen bir öncelik şeması uygular. Çoğu durumda, yeni bir uygulama ses girişini alırsa daha önce ses kaydı yapan uygulama çalışmaya devam eder ancak sessizliği alır. Bazı durumlarda sistem, her iki uygulamaya da ses iletmeye devam edebilir. Çeşitli paylaşım senaryoları aşağıda açıklanmıştır.

Bu şema, ses odağının ses çıkışını kullanmak için yarışan birden fazla uygulamayı yönetme şekline benzer. Ancak ses odağı, odaklanma ve odaklanmayı bırakma ile ilgili programatik isteklerle yönetilir. Burada açıklanan giriş değiştirme şeması ise yeni bir uygulama ses yakalamaya başladığında otomatik olarak uygulanan bir önceliklendirme politikasına dayanır.

Android, ses yakalama amacıyla iki tür uygulama arasında ayrım yapar:

  • "Sıradan" uygulamalar kullanıcı tarafından yüklenir.
  • "Ayrıcalıklı" uygulamalar cihaza önceden yüklenmiş olarak gelir. Bunlar arasında Google Asistan ve tüm erişilebilirlik hizmetleri yer alır.

Ayrıca, "gizlilik açısından hassas" bir ses kaynağı (CAMCORDER veya VOICE_COMMUNICATION) kullanan uygulamalar farklı şekilde ele alınır.

Ses girişini kullanma ve paylaşmayla ilgili önceliklendirme kuralları aşağıdaki gibidir:

  • Ayrıcalıklı uygulamalar, normal uygulamalardan daha yüksek önceliğe sahiptir.
  • Ön planda görünür kullanıcı arayüzleri olan uygulamalar, arka plan uygulamalarından daha yüksek önceliğe sahiptir.
  • Gizlilik açısından hassas bir kaynaktan ses kaydeden uygulamalar, kaydetmeyen uygulamalara göre daha yüksek önceliğe sahiptir.
  • İki normal uygulama hiçbir zaman aynı anda ses kaydedemez.
  • Bazı durumlarda, ayrıcalıklı bir uygulama ses girişini başka bir uygulamayla paylaşabilir.
  • Aynı önceliğe sahip iki arka plan uygulaması ses kaydediyorsa en son başlatılan uygulama daha yüksek önceliğe sahiptir.

Paylaşım senaryoları

İki uygulama ses yakalamaya çalıştığında her ikisi de giriş sinyalini alabilir veya uygulamalardan biri sessiz kalabilir.

Dört ana senaryo vardır:

  • Asistan + sıradan uygulama
  • Erişilebilirlik hizmeti + sıradan uygulama
  • İki sıradan uygulama
  • Sesli arama + normal uygulama

Asistan + sıradan uygulama

Asistan, önceden yüklendiği ve RoleManager.ROLE_ASSISTANT rolüne sahip olduğu için ayrıcalıklı bir uygulamadır. Bu role sahip diğer önceden yüklenmiş uygulamalar da benzer şekilde değerlendirilir.

Android, giriş sesini şu kurallara göre paylaşır:

  • Asistan, gizliliğe duyarlı bir ses kaynağı kullanan başka bir uygulama tarafından ses yakalanmadığı sürece ses alabilir (ön planda veya arka planda olması fark etmez).

  • Asistan'ın ekranın üst kısmında görünür bir kullanıcı arayüzü bileşeni yoksa uygulama ses alır.

Her iki uygulamanın da yalnızca Asistan arka plandayken ve diğer uygulama gizlilik açısından hassas bir ses kaynağından kayıt yapmıyorken ses aldığını unutmayın.

Erişilebilirlik hizmeti + sıradan uygulama

AccessibilityService için katı bir beyan gerekir.

Android, giriş sesini şu kurallara göre paylaşır:

  • Hizmetin kullanıcı arayüzü üstteyse hem hizmet hem de uygulama ses girişi alır. Bu davranış, sesli aramayı veya video kaydını sesli komutlarla kontrol etme gibi işlevler sunar.

  • Hizmet en üstte değilse bu durum, aşağıdaki sıradan iki uygulama durumu gibi ele alınır.

İki sıradan uygulama

İki uygulama aynı anda ses kaydı yaparken yalnızca bir uygulama ses alır, diğeri ise sessiz kalır.

Android, giriş sesini şu kurallara göre paylaşır:

  • Uygulamalardan hiçbiri gizlilik açısından hassas değilse kullanıcı arayüzü üstte olan uygulama ses alır. Uygulamaların hiçbirinde kullanıcı arayüzü yoksa en son ses yakalamaya başlayan uygulama sesi alır.
  • Uygulamalardan biri gizlilik açısından hassassa ses bu uygulamaya iletilir. Diğer uygulama, üstte bir kullanıcı arayüzü olsa veya daha yakın zamanda ses yakalamaya başlamış olsa bile sessiz kalır.
  • Her iki uygulama da gizliliğe duyarlıysa en son ses kaydetmeye başlayan uygulama ses alır, diğeri ise sessiz kalır.

Sesli arama + normal uygulama

AudioManager.getMode() tarafından döndürülen ses modu MODE_IN_CALL veya MODE_IN_COMMUNICATION ise sesli arama etkindir.

Android, giriş sesini şu kurallara göre paylaşır:

Android 11 davranışı

Android 11 (API düzeyi 30), yukarıda açıklanan Android 10 öncelik şemasını kullanır. Ayrıca AudioRecord, MediaRecorder ve AAudioStream sınıflarında, seçilen kullanım alanından bağımsız olarak aynı anda ses kaydetme özelliğini etkinleştiren ve devre dışı bırakan yeni yöntemler sunar.

Yeni yöntemler şunlardır:

setPrivacySensitive(), true olduğunda yakalama kullanım alanı gizlidir ve ayrıcalıklı bir asistan bile aynı anda yakalama yapamaz. Bu ayar, ses kaynağına bağlı olan varsayılan davranışı geçersiz kılar. Örneğin, VOICE_COMMUNICATION varsayılan olarak gizlidir ancak UNPROCESSED gizli değildir.

Yapılandırma değişiklikleri

Birden fazla uygulama aynı anda ses yakalarken bunlardan yalnızca bir veya ikisi "etkin" (ses alıyor) olur, diğerlerinin sesi kapatılır (sessizlik alır). Etkin uygulamalar değiştiğinde ses çerçevesi, ses yollarını şu kurallara göre yeniden yapılandırabilir:

  • Her etkin uygulamanın ses giriş cihazı değişebilir (örneğin, yerleşik mikrofondan takılı bir Bluetooth mikrofonlu kulaklığa).
  • En yüksek öncelikli etkin uygulamayla ilişkili ön işleme etkinleştirilir. Diğer tüm ön işleme adımları yoksayılır.

Daha yüksek öncelikli bir uygulama etkin hale geldiğinde etkin bir uygulama sessize alınabileceğinden, yapılandırma değiştiğinde bildirim almak için AudioRecord veya MediaRecorder nesnesine bir AudioManager.AudioRecordingCallback kaydedebilirsiniz. Olası değişiklikler şunlar olabilir:

  • Sessize alınmış veya alınmamış yakalama
  • Cihaz değiştirildi
  • Ön işleme değiştirildi
  • Akış özellikleri değişti (örnekleme hızı, kanal maskesi, örnek biçimi)

Yakalama işlemi başlatılmadan önce AudioRecord.registerAudioRecordingCallback() yöntemini çağırmanız gerekir. Geri çağırma yalnızca uygulama ses alırken ve bir değişiklik olduğunda yürütülür.

onRecordingConfigChanged() yöntemi, mevcut ses yakalama durumunu içeren bir AudioRecordingConfiguration döndürür. Değişiklik hakkında bilgi edinmek için aşağıdaki yöntemleri kullanın:

isClientSilenced()
İstemciye döndürülen ses, yakalama politikası nedeniyle şu anda sessize alınmışsa doğru değerini döndürür.
getAudioDevice()
Etkin ses sistemini döndürür.
getEffects()
Etkin ön işleme efektini döndürür. İstemci, en yüksek öncelikli etkin uygulama değilse etkin efektin getClientEffects() tarafından döndürülenlerle aynı olmayabileceğini unutmayın.
getFormat()
Akış özelliklerini döndürür. İstemci tarafından alınan gerçek ses verilerinin her zaman getClientFormat() tarafından döndürülen gerekli biçime uygun olduğunu unutmayın. Çerçeve, donanım arayüzünde kullanılan biçimden istemci tarafından belirtilen biçime gerekli yeniden örnekleme, kanal ve biçim dönüştürme işlemlerini otomatik olarak gerçekleştirir.
AudioRecord.getActiveRecordingConfiguration()
Etkin kayıt yapılandırmasını döndürür.

AudioManager.getActiveRecordingConfigurations() yöntemini çağırarak cihazdaki tüm etkin kayıtların genel görünümünü elde edebilirsiniz.