Android将耳机音量链接到主音量

Android将耳机音量链接到主音量,android,android-audiomanager,android-tv,Android,Android Audiomanager,Android Tv,我有一台安卓电视(飞利浦49PUS6401) 我想连接一个环绕音响系统,它的质量比内置扬声器好得多,即使只用于立体声 然而,这台电视将主输出和耳机输出的音量控制分开,其结果是,即使电视内置扬声器关闭,遥控器上的音量键也不会调整耳机音量(我将其用作线路输出) 我正计划编写一个简单的应用程序,以便在mast音量发生变化时调整耳机音量,但我似乎不知道如何获取或设置耳机音量,因为音频管理器处理的是流而不是输出,因此我能从中获得的唯一值是主音量 如何找到获取/设置耳机音量的方法? 我已通过adb获得she

我有一台安卓电视(飞利浦49PUS6401) 我想连接一个环绕音响系统,它的质量比内置扬声器好得多,即使只用于立体声

然而,这台电视将主输出和耳机输出的音量控制分开,其结果是,即使电视内置扬声器关闭,遥控器上的音量键也不会调整耳机音量(我将其用作线路输出)

我正计划编写一个简单的应用程序,以便在mast音量发生变化时调整耳机音量,但我似乎不知道如何获取或设置耳机音量,因为音频管理器处理的是流而不是输出,因此我能从中获得的唯一值是主音量

如何找到获取/设置耳机音量的方法? 我已通过adb获得shell访问权限,但无法获得root


作为参考,电视正在运行最新的固件,即android 5.1.1,据我所知,这是飞利浦android电视用户的常见问题(例如,第22页在线程中,或讨论中)。 一般来说,您任务的模板是
服务
,它跟踪“系统/音乐”音频流(或媒体按钮按下)的插拔事件和音量,而不是在“有线耳机”音频流上进行相应的更改(“标准”安卓中没有此类流,但显然 类似的东西出现在)水平。问题是,仅使用Android SDK而不使用“飞利浦Android电视API”(可能不是公共的),似乎不可能改变“有线耳机”音频流级别的音量

“VolumeTrackingService”的模板源代码可能如下所示:

public class VolumeTrackingService extends Service {

    private static final String TAG = VolumeTrackingService.class.getSimpleName();

    public static final String ACTION_START = "VolumeTrackingService.ACTION_START";
    public static final String ACTION_STOP = "VolumeTrackingService.ACTION_STOP";

    HeadsetPlugIntentReceiver mHeadsetPlugReceiver;
    private static boolean mHeadsetPlugged = false;

    private SettingsContentObserver mSettingsContentObserver;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mHeadsetPlugReceiver = new HeadsetPlugIntentReceiver();
        registerReceiver(mHeadsetPlugReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
        mSettingsContentObserver = new SettingsContentObserver(new Handler());
        getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver);
    }

    @Override
    public void onDestroy() {
        getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
        unregisterReceiver(mHeadsetPlugReceiver);
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String actionRequested = intent.getAction();
            if (ACTION_START.equals(actionRequested)) {
            } else if (ACTION_STOP.equals(actionRequested)) {
                stopSelf();
            }
        }
        return START_STICKY;
    }

    private int getSystemVolumeInPercentage() {
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        final int streamVolumeMax = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        final int streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        return 100 * streamVolume / streamVolumeMax;
    }

    private void setHeadphonesVolume(int volumeInPercentage) {
        // there should be magic of wired headphones volume level changing
    }

    private void processVolumeChanges() {
        if (mHeadsetPlugged) {
            int systemVolumeInPercentage = getSystemVolumeInPercentage();
            setHeadphonesVolume(systemVolumeInPercentage);
        }
    }


    public class SettingsContentObserver extends ContentObserver {

        public SettingsContentObserver(Handler handler) {
            super(handler);
        }

        @Override
        public boolean deliverSelfNotifications() {
            return super.deliverSelfNotifications();
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            if (mHeadsetPlugged ) {
                processVolumeChanges();
            }
        }
    }

    public class HeadsetPlugIntentReceiver extends android.content.BroadcastReceiver {
        @Override
        public void onReceive(Context ctx, Intent intent) {
            if (intent.getAction().equals(android.media.AudioManager.ACTION_HEADSET_PLUG)) {
                mHeadsetPlugged = intent.getIntExtra("state", 0) == 1;
            }
        }
    }
}
不幸的是,它并没有解决主要问题:改变有线耳机的音量水平(如果没有“飞利浦Android电视API”,这可能是不可能的)


但是,如果您的环绕声音响系统有遥控器,您可以做一些变通:在上述
服务中模拟音响系统遥控命令,并通过连接到飞利浦49PUS6401安卓电视USB主机的IR加密狗发送。

安卓对主控器和耳机输出没有区别。你只能调整流,我知道通常不会,但不知何故,这台电视机的制造商设法使输出双工,使耳机始终处于活动状态,音量单独控制,这在支持论坛上得到广泛注意,一些索尼电视也有这个问题:我认为电视耳机输出仅用于HDMI输入的音频,对吗?不,电视播放的任何音频(无论是HDMI输入、电视输入、scart等)都同时通过电视扬声器和耳机播放,通过单独的音量控制,您的飞利浦49PUS6401环绕音响系统的哪个端口连接了“耳机”或“数字音频输出”或其他?虽然我非常感谢您抽出时间编写一个简单的框架来帮助我,这是
//有线耳机音量水平变化的神奇之处
我正在挣扎…我明白了)。事实上,我认为“但如果您的环绕声音响系统有遥控器,您可以做一些变通:在上述服务中模拟音响系统遥控命令,并通过连接到您的飞利浦49PUS6401安卓电视USB主机的IR加密狗发送。”-是答案的主要部分,服务模板-仅介绍。我认为只有普通的安卓SDK无法实现您想要的功能。通过模拟遥控信号对环绕声系统进行音量控制在任何情况下都是可行的。IR加密狗可能简单且便宜,就像它是100%的解决方案一样。因为问题出在飞利浦Android电视上(例如索尼BRAVIA上,一切都可以按您的意愿运行)。我的音响系统没有遥控器,所以这对我来说不起作用,对其他人来说可能也不起作用,但不幸的是,这并不能解决我的问题。好的。您也可以尝试模拟“按键”事件序列来更改耳机音量(如在应答中),但它将显示在电视屏幕上。但最好在电视和音响系统之间添加音量控制放大器。