zoukankan      html  css  js  c++  java
  • Camera拍照声设定

        在某些国家(比如Japan),为了防止偷拍,强制拍照声是需要从Speaker出来的(即使插入耳机的情况下)。

        实现该功能比较简单的方法就是将拍照声类型设置为Ringtone 或 Alarm 或 Notification类型,这样在AudioPolicyManager.cpp中device选择时就会将Speaker设为output device。

        还有一种方式就是设置拍照声为ENFORCED_AUDIBLE,该类型音频流的类型解释:

        ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker

        该解释应该就是说这类型的声音不能被静音,而且必须从speaker出来。

        但是仅仅将音频流类型设置为ENFORCED_AUDIBLE,并不能保证声音从speaker出来,从AudioPolicyManager.cpp里逻辑里看:

        case STRATEGY_ENFORCED_AUDIBLE:
            // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
            // except:
            //   - when in call where it doesn't default to STRATEGY_PHONE behavior
            //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
    
            if ((strategy == STRATEGY_SONIFICATION) ||
                    (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) {
                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
                if (device == AUDIO_DEVICE_NONE) {
                    ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
                }
            }
            // The second device used for sonification is the same as the device used by media strategy
            // FALL THROUGH
    
        case STRATEGY_MEDIA: {
            uint32_t device2 = AUDIO_DEVICE_NONE;
            if (strategy != STRATEGY_SONIFICATION) {
                // no sonification on remote submix (e.g. WFD)
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
            }
            if ((device2 == AUDIO_DEVICE_NONE) &&
                    mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
                if (device2 == AUDIO_DEVICE_NONE) {
                    device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
                }
                if (device2 == AUDIO_DEVICE_NONE) {
                    device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                }
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
            }
            if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
                // no sonification on aux digital (e.g. HDMI)
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
            }
            if ((device2 == AUDIO_DEVICE_NONE) &&
                    (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
            }
    
            // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
            // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
            device |= device2;
            if (device) break;
            device = mDefaultOutputDevice;
            if (device == AUDIO_DEVICE_NONE) {
                ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
            }
            } break;

        在case STRATEGY_ENFORCED_AUDIBLE中,因为目前(strategy != STRATEGY_SONIFICATION) 所以想要在音频流类型是ENFORCED_AUDIBLE的情况下Speaker还能出声的话,就需要满足:(mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED),否则就会follow case STRATEGY_MEDIA的device。

        而(mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)是在哪边设定的呢?

        全局搜索了代码,原来在AudioService初始化时:

        boolean cameraSoundForced = mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_camera_sound_forced);
        mCameraSoundForced = new Boolean(cameraSoundForced);
        sendMsg(mAudioHandler,
                MSG_SET_FORCE_USE,
                SENDMSG_QUEUE,
                AudioSystem.FOR_SYSTEM,
                cameraSoundForced ?
                          AudioSystem.FORCE_SYSTEM_ENFORCED :AudioSystem.FORCE_NONE,
                null,
                0);

        所以当cameraSoundForced的值为true时,就会setforceuse(FOR_SYSTEMFORCE_SYSTEM_ENFORCED);而com.android.internal.R.bool.config_camera_sound_forced是在config.xml中设定的,所以还需要在config.xml档里将config_camera_sound_forced变量设置为true。

  • 相关阅读:
    tensorflow结果可视化-【老鱼学tensorflow】
    tensorflow建造神经网络-【老鱼学tensorflow】
    tensorflow添加层-【老鱼学tensorflow】
    tensorflow激励函数-【老鱼学tensorflow】
    tensorflow 传入值-【老鱼学tensorflow】
    tensorflow变量-【老鱼学tensorflow】
    tensorflow会话控制-【老鱼学tensorflow】
    Android 代码判断是否有网络
    Android Toast 工具类
    Android 菊花加载工具类
  • 原文地址:https://www.cnblogs.com/Peter-Chen/p/5361427.html
Copyright © 2011-2022 走看看