Camera拍照声设定

Posted 蜗牛慢慢

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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。

 

以上是关于Camera拍照声设定的主要内容,如果未能解决你的问题,请参考以下文章

使用 IntentService 使用 Camera2 拍照

Android 11.0 Camera2 默认选择拍照尺寸修改及流程分析

玩转Android Camera开发:国内首发---使用GLSurfaceView预览Camera 基础拍照demo

使用Camera进行拍照

android 相机 怎么改变相机预览界面大小

android中用Camera来调用摄像头,只能用takePicture来拍照吗?