有時,當您將耳機與Android設備配合使用時,媒體音量可能會突然下降,并且無法將音量調高。為此,您必須解鎖設備并接受警告:
對話框出現的時間是無法預測的:當您開車或騎自行車,手臟或弄濕等時,可能會出現該對話框。當然,通過耳機聽大聲的音樂可能會損害聽力。但是設備無法識別所連接的設備:耳機或揚聲器。對于演講者來說,此消息毫無意義。
聽力系統有WHO-ETU標準。在歐盟和其他一些國家/地區,必須強制使用它們。這些標準根據音量和收聽時間來描述人們的聲音容限。
根據MCC(移動國家/地區代碼),可以啟用或禁用警告。它由資源定義R.bool.config_safe_media_volume_enabled。如果啟用了警告,則系統會計算“不安全的收聽”時間,并在達到20小時后顯示警告。
當音量大于85 dB且連接了耳機時,則認為收聽“不安全”。累積的“不安全收聽”時間存儲在其中,Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS并每分鐘更新一次。
安全監聽系統邏輯在AudioService.java中實現。
設置audio.safemedia.bypass=true在文件系統/ build.properties:
為什么它應該起作用?
讓我們看一下AudioService.java中的一些字段:
// mSafeMediaVolumeState indicates whether the media volume is limited over headphones. // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, // it can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume() // (when user opts out). private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0; private static final int SAFE_MEDIA_VOLUME_DISABLED = 1; private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2; // confirmed private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3; // unconfirmed private Integer mSafeMediaVolumeState;
該字段mSafeMediaVolumeState 保持當前的安全監聽狀態:
我們需要mSafeMediaVolumeState 分配給DISABLED。
初始值在這里分配:
private void onConfigureSafeVolume(boolean force, String caller) { ... boolean safeMediaVolumeEnabled = SystemProperties.getBoolean("audio.safemedia.force", false) || mContext.getResources().getBoolean( com.android.internal.R.bool.config_safe_media_volume_enabled); boolean safeMediaVolumeBypass = SystemProperties.getBoolean("audio.safemedia.bypass", false); int persistedState; if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) { persistedState = SAFE_MEDIA_VOLUME_ACTIVE; /* Omitted code. Here mSafeMediaVolumeState is assigned to ACTIVE, or INACTIVE */ ... } else { persistedState = SAFE_MEDIA_VOLUME_DISABLED; mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; }
DISABLED在兩種情況下,可以將其分配給:什么時候R.bool.config_safe_media_volume_enabled=true(我們不能更改)或什么時候audio.safemedia.bypass = true(我們可以使用root特權進行更改)。
解決方案是監視的值,Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS并且不允許其超過20小時。接近閾值時應重置該值。
int unsafeMs = Settings.Secure.getInt(contentResolver, "unsafe_volume_music_active_ms")
使用adb相同
adb shell settings get secure unsafe_volume_music_active_ms
首先,授予更改安全設置的權限:
adb shell pm grant com.example.app android.permission.WRITE_SECURE_SETTINGS
可以完成,因為此許可權具有“,”, 然后調用:protectionLevel="signature|privileged|development
Settings.Secure.putInt(contentResolver, "unsafe_volume_music_active_ms" , 1)
它必須為1,因為0值與ACTIVE狀態相關聯。
使用adb也是一樣:
adb shell settings put secure unsafe_volume_music_active_ms 1
值更新后,我們需要讓AudioService讀取并使用它。根據源代碼,唯一的方法是重新啟動它。音頻服務是一項系統服務,因此要重新啟動它,必須重新啟動設備(或者用戶可以重新登錄)。
為了使該解決方案更易于使用,我為一個小型應用程序編寫了代碼,該應用程序會定期檢查該Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS值并提醒重新啟動設備。
當然,重新啟動或重新登錄需要花費時間,但是此解決方案不需要root特權。
熱門源碼