Ses girişi genellikle yerleşik mikrofondan, harici mikrofondan veya cihaza bağlı bir ses arayüzünden gelir. Ses girişi, telefon görüşmesinden de alınabilir.
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 "kayıt" yapıyor olabilir (ör. basit bir ses kaydedici), bazı uygulamalar ise "dinliyor" olabilir (ör. Google Asistan veya sesli komutlara yanıt veren bir erişilebilirlik hizmeti).
Her iki durumda da bu uygulamalar ses girişi almak ister. Bu sayfada, bir uygulama kayıt yapıyor veya yalnızca dinliyor olmasına bakılmaksızın "yakalama" terimini kullanırız.
İki veya daha fazla uygulama aynı anda ses yakalamak isterse aynı kaynaktan gelen ses sinyalini hepsine iletmede sorun yaşanabilir. Bu sayfada, Android sisteminin ses girişini, ses yakalayan birden fazla uygulama arasında 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 zaten ses kaydı yapıyorsa veya ses dinliyorsa uygulamanız AudioRecord nesnesi oluşturabilir ancak AudioRecord.startRecording() çağrıldığında hata döndürülür ve kayıt başlatılmaz.
Bu kuralın tek istisnası, ayrıcalıklı bir uygulamanın (ör. Google Asistan veya bir erişilebilirlik hizmeti) android.permission.CAPTURE_AUDIO_HOTWORD iznine sahip olduğu ve HOTWORD türünde bir ses kaynağı kullandığı durumlardı. Bu durumda başka bir uygulama kayda başlayabilir. Bu durumda, ayrıcalıklı uygulama sonlandırıldı ve yeni uygulama girişi yakaladı.
Android 9'da bir değişiklik daha yapıldı: Yalnızca ön planda çalışan uygulamalar (veya ön plan hizmetleri) ses girişini yakalayabiliyordu. Ön plan hizmeti veya ön plan kullanıcı arayüzü bileşeni olmayan bir uygulama ses yakalamaya başladığında, o sırada ses yakalayan tek uygulama olsa bile uygulama çalışmaya devam ediyor ancak sessiz kalıyordu.
Android 10 davranışı
Android 10'dan önceki davranış "önce gelen alır" şeklindedir. Bir uygulama ses yakalamaya başladığında, ses yakalayan 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 yakalayan uygulama çalışmaya devam eder ancak sessiz kalır. Bazı durumlarda sistem, her iki uygulamaya da ses iletmeye devam edebilir. Çeşitli paylaşım senaryoları aşağıda açıklanmaktadır.
Bu şema, ses çıkışının kullanımı için yarışan birden fazla uygulamayı ses odağının ele alma şekline benzer. Ancak ses odağı, odak kazanma ve bırakma için programatik isteklerle yönetilirken burada açıklanan giriş değiştirme şeması, 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:
- "Normal" 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, "gizliliğe duyarlı" bir ses kaynağı CAMCORDER veya VOICE_COMMUNICATION kullanan uygulamalar farklı şekilde değerlendirilir.
Ses girişini kullanma ve paylaşmaya ilişkin önceliklendirme kuralları şunlardır:
- Ayrıcalıklı uygulamalar, normal uygulamalara göre daha yüksek önceliğe sahiptir.
- Görünür ön plan kullanıcı arayüzlerine sahip uygulamalar, arka plan uygulamalarına göre daha yüksek önceliğe sahiptir.
- Gizliliğe duyarlı bir kaynaktan ses yakalayan uygulamalar, bu tür uygulamalara göre daha yüksek önceliğe sahiptir.
- İki normal uygulama aynı anda ses yakalayamaz.
- 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 yakalıyorsa 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 birinde sessizlik oluşabilir.
Dört ana senaryo vardır:
- Asistan + normal uygulama
- Erişilebilirlik hizmeti + normal uygulama
- İki normal uygulama
- Sesli arama + normal uygulama
Asistan + normal uygulama
Asistan, önceden yüklenmiş olduğu ve RoleManager.ROLE_ASSISTANT rolünü üstlendiği için ayrıcalıklı bir uygulamadır. Bu role sahip diğer tüm önceden yüklenmiş uygulamalar da benzer şekilde ele alınır.
Android, giriş sesini şu kurallara göre paylaşır:
Gizliliğe duyarlı bir ses kaynağı kullanan başka bir uygulama zaten kayıt yapmıyorsa Asistan, 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 gizliliğe duyarlı bir ses kaynağından kayıt yapmıyorken ses aldığını unutmayın.
Erişilebilirlik hizmeti + normal 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 arama veya video kaydı gibi işlevleri sesli komutlarla kontrol etmenizi sağlar.
Hizmet en üstte değilse bu durum, aşağıdaki normal iki uygulamalı durum gibi ele alınır.
İki normal uygulama
İki uygulama aynı anda kayıt yaparken yalnızca bir uygulama ses alır, diğer uygulama ise sessiz kalır.
Android, giriş sesini şu kurallara göre paylaşır:
- Her iki uygulama da gizliliğe duyarlı değilse ses, üstte kullanıcı arayüzü olan uygulamaya gönderilir. Her iki uygulamanın da kullanıcı arayüzü yoksa en son kayda başlayan uygulama ses alır.
- Uygulamalardan biri gizliliğe duyarlıysa ses alır, diğer uygulama ise en üstte bir kullanıcı arayüzü olsa veya daha yakın zamanda yakalamaya başlamış olsa bile sessiz kalır.
- Her iki uygulama da gizlilik açısından hassassa en son ses yakalamaya başlayan uygulama sesi 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:
- Aramada her zaman ses alınır.
- Uygulama, erişilebilirlik hizmeti ise ses yakalayabilir.
Uygulama,
CAPTURE_AUDIO_OUTPUTizniyle ayrıcalıklı (önceden yüklenmiş) bir uygulama ise sesli aramayı kaydedebilir.Uygulamanın, sesli görüşmenin uplink (TX), downlink (RX) veya her ikisini de kaydetmek için
MediaRecorder.AudioSource.VOICE_UPLINKveyaMediaRecorder.AudioSource.VOICE_DOWNLINKses kaynaklarını ve/veyaAudioDeviceInfo.TYPE_TELEPHONYcihazını belirtmesi gerekir.
Android 11 davranışı
Android 11 (API düzeyi 30), yukarıda açıklanan Android 10 öncelik şemasını kullanır. Ayrıca, seçilen kullanım alanından bağımsız olarak sesi eşzamanlı kaydetme özelliğini etkinleştiren ve devre dışı bırakan AudioRecord, MediaRecorder ve AAudioStream'de yeni yöntemler sunar.
Yeni yöntemler:
AudioRecord.Builder.setPrivacySensitive()AudioRecord.isPrivacySensitive()MediaRecorder.setPrivacySensitive()MediaRecorder.isPrivacySensitive()AAudioStreamBuilder_setPrivacySensitive()AAudioStream_isPrivacySensitive()
setPrivacySensitive() true olduğunda yakalama kullanım alanı özeldir 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 kaydettiğinde yalnızca bir veya ikisi "etkin" (ses alıyor) olur, diğerleri ise sessize alınır (sessizlik alıyor). Etkin uygulamalar değiştiğinde ses çerçevesi, ses yollarını şu kurallara göre yeniden yapılandırabilir:
- Her etkin uygulama için ses giriş cihazı değişebilir (örneğin, yerleşik mikrofondan bağlı bir Bluetooth kulaklığa geçilebilir).
- En yüksek önceliğe sahip etkin uygulamayla ilişkili ön işleme etkinleştirilir. Diğer tüm ön işleme adımları yoksayılır.
Etkin bir uygulama, daha yüksek öncelikli bir uygulama etkinleştiğinde sessize alınabileceğinden,
yapılandırma değiştiğinde bildirim almak için AudioManager.AudioRecordingCallback öğesini AudioRecord veya MediaRecorder nesnesine kaydedebilirsiniz. Olası değişiklikler şunlar olabilir:
- Yakalamanın sesi kapatılmış veya kapatılmamış
- Cihaz değiştirildi
- Ön işleme değişti
- Akış özellikleri değişti (örnekleme hızı, kanal maskesi, örnek biçimi)
Kayda başlamadan önce AudioRecord.registerAudioRecordingCallback() numarasını aramanız gerekir. Geri çağırma yalnızca uygulama ses alırken ve 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. Bu ç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() numarasını arayarak cihazdaki tüm etkin kayıtların genel görünümünü elde edebilirsiniz.