android系统如何在静音模式下关闭camera拍照声音

本文介绍了如何在Android应用中,通过设置系统属性和利用AudioManager,实现在静音模式下禁止相机拍照时发出声音的功能。通过修改Android.mk文件和在AndroidManifest.xml中设置权限,应用能够以系统权限运行并读取系统属性,进而根据当前的静音状态决定是否播放拍照声音。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         话说为了防止偷拍,业内有不成文规定,手机公司在做camera时,点击拍照和录像键的时候,必须要有提示音。因此,google也就非常人性化的将播放拍照声音的函数,放到了cameraService中,防止开发者能开发出不响的camera,从而只要调用拍照函数,一定会响,这是写死在framework中的。

        话说这个规定在当今有点不合时宜,这不,今天我收到测试提的一个BUG,说是公司的新需求,要求在静音模式下拍照声音也得取消。这么无耻的需求,也许就在我们中国最大的山寨手机公司才会提到。废话不多说,看看是怎么改的。

       刚开始想到的是调用audiomanager的service,但是这会涉及到进程间通信,比较繁琐。所以用到了SystemProperity。想在APP监听点击事件时增加一个property,将当时的aduio状态写进去,如果为静音模式,则写入1,然后cameraservice再调用playsound时也取这个property,来判断是否playsound。

     关于在app中写入systemprperty,我想引用一下大神的博客,博客地址http://www.cnblogs.com/eustoma/archive/2011/05/28/2415859.html

     以下为引用的博文:

---------------------------------------------------------------------------------------------------------------------------------------start

   使应用程序具有AID_SYSTEM的UID

    那如何使应用程序的uid变为1000呢?

    由于我可以在Android系统源码的环境下用make来编译,所以需要做如下几步:

l  在应用程序的AndroidManifest.xml文件中的manifest节点中加入属性:

android:sharedUserId="android.uid.system";

通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来设置前缀为hw.的属性了。

l  修改Android.mk文件,加入LOCAL_CERTIFICATE := platform;

加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform. key,就是platform.pk8和platform.x509.pem两个文件。通过这样的设置,系统才可以拿到platform.pk8和platform.x509.pem两个文件。使用这两个key签名后apk才真正可以放入系统进程中。

然后使用mm命令来编译,生成的apk的uid就会成为1000。在去调用property_set("hw.jpeg.path", "/data/test.jpg");就不会有问题了。

---------------------------------------------------------------------------------------------------------------------------------------------end

忙活半天发现其实在AudioManager.java文件中,已经将一个KEY-VALUE值写入到了SystemProperity中:


然后在CameraService.cpp文件中,关于调用playsound()函数的地方加入如下判断:


注意:property_get()函数需要引入头文件,<cutils/properties.h>

希望能对有同样需求的朋友有所帮助。

### Android 系统拍照时快门声音的设置或实现方法 在 Android 系统中,处理拍照时的快门声音涉及多个方面,包括不同版本系统的差异、硬件支持情况以及软件层面的具体实现逻辑。以下是关于如何设置或实现拍照时快门声音的相关说明。 #### 1. **通过 `MediaActionSound` 类控制快门声音** Android 提供了一个名为 `MediaActionSound` 的类,用于播放标准的声音效果,其中包括快门声音。默认情况下,当用户按下拍照按钮时,系统会自动调用此 API 来播放快门声音。如果希望禁用该声音,可以通过注释掉相关代码或者条件判断来实现[^5]。 ```java // 如果需要关闭快门声音,则可以注释掉以下代码 // mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK); ``` #### 2. **静音模式下的快门声音行为** 从 Android 10 开始,Google 对于静音模式下是否允许播放快门声音有了更严格的规定。通常情况下,在设备处于静音模式时,不应再播放任何提示音,包括快门声音。然而,某些厂商可能未完全遵循这一规范,因此需要手动调整源码中的逻辑以确保符合预期[^3]。 例如,在 `CaptureModule` 中重写 `onQuickExpose()` 方法: ```java @Override public void onQuickExpose() { mMainThread.execute(() -> { // 启动闪光灯动画 mAppController.startFlashAnimation(true); // 判断当前是否为静音状态 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); if (!(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) { mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK); } }); } ``` 此处增加了对音频管理器 (`AudioManager`) 的检查,仅在非静音状态下才播放快门声音。 #### 3. **自定义快门声音文件** 除了使用内置的标准快门声音外,还可以加载外部资源作为新的快门声音。这适用于那些想要提供个性化体验的应用程序开发者[^4]。 步骤如下: - 将所需的声音文件放入项目的 `res/raw` 文件夹中; - 使用 MediaPlayer 加载并播放指定路径下的音频文件; 示例代码片段: ```java MediaPlayer mediaPlayer = new MediaPlayer(); try { AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.custom_shutter_sound); mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); afd.close(); mediaPlayer.prepare(); // 准备播放 mediaPlayer.setOnCompletionListener(mp -> mp.release()); // 播放完成后释放资源 } catch (IOException e) { Log.e("CustomShutter", "Failed to load custom shutter sound.", e); } mediaPlayer.start(); // 开始播放 ``` #### 4. **Camera2 API 下的实现细节** 对于采用 Camera2 API 进行开发的情况,由于其灵活性更高,因此也需要更加细致地考虑各种场景下的需求。比如在某些特定模块(如 `PictureTakerImpl`, `PictureCallbackAdapter` 和 `CaptureModule`)中都需要单独配置是否启用快门声音[^1]。 典型做法是在捕获图片之前先暂停所有潜在的异步操作,并确认环境参数后再决定下一步动作: ```java private void takePicture(boolean isSilent) { final CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); if (!isSilent && !isInSilentMode()) { mediaActionSound.play(MediaActionSound.SHUTTER_CLICK); } SessionConfiguration sessionConfig = new SessionConfiguration(SessionConfiguration.SESSION_REGULAR, Collections.singletonList(new Surface(imageReader.getSurface())), ContextCompat.getMainExecutor(context), captureSessionStateCallback); try { cameraDevice.createCaptureSession(sessionConfig, captureSessionStateCallback); } catch (CameraAccessException cae) { Log.e(TAG, "Error creating capture session!", cae); } } ``` --- ###
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值