主要解决录音时候不能让当前app内音外放
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了主要解决录音时候不能让当前app内音外放相关的知识,希望对你有一定的参考价值。
参考技术A 选择一个CategoryAVAudioSessionCategoryAmbient或kAudioSessionCategory_AmbientSound——用于非以语音为主的应用,使用这个category的应用会随着静音键和屏幕关闭而静音。并且不会中止其它应用播放声音,可以和其它自带应用如iPod,safari等同时播放声音。
AVAudioSessionCategorySoloAmbient或kAudioSessionCategory_SoloAmbientSound——类似于AVAudioSessionCategoryAmbient不同之处在于它会中止其它应用播放声音。 这个category为默认category。
AVAudioSessionCategoryPlayback或kAudioSessionCategory_MediaPlayback——用于以语音为主的应用,使用这个category的应用不会随着静音键和屏幕关闭而静音。
AVAudioSessionCategoryRecord或kAudioSessionCategory_RecordAudio———用于需要录音的应用,设置该category后,除了来电铃声,闹钟或日历提醒之外的其它系统声音都不会被播放。
AVAudioSessionCategoryPlayAndRecord或kAudioSessionCategory_PlayAndRecord——用于既需要播放声音又需要录音的应用,语音聊天应用(如微信)应该使用这个category。
AVAudioSessionCategoryAudioProcessing或kAudioSessionCategory_AudioProcessing————当需要进行离线语音处理时使用这个category,这里我也不太明白离线语音处理是什么概念,希望有知道的可以解释下。
注意 :并不是一个应用只能使用一个category,程序应该根据实际需要来切换设置不同的category,举个例子,录音的时候,需要设置为AVAudioSessionCategoryRecord,当录音结束时,应根据程序需要更改category为AVAudioSessionCategoryAmbient,AVAudioSessionCategorySoloAmbient或AVAudioSessionCategoryPlayback中的一种。
设置Category
NSError *setCategoryError = nil;
BOOLsuccess = [[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: &setCategoryError];
if(!success) /* handle the error in setCategoryError */
NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: &setCategoryError];
if (!success) /* handle the error in setCategoryError */
切换到扬声器
按照苹果官方文档的说法,只有在category设置为AVAudioSessionCategoryPlayAndRecord时才能从扬声器播放声音,这一点我还未证实。
总之,按照官方文档的说法,先设置category为AVAudioSessionCategoryPlayAndRecord,然后通过重写audio route属性来重定向音频。
audio route属性有以下两个,一个是默认的听筒,另一个则是扬声器。
enum
kAudioSessionOverrideAudioRoute_None = 0,
kAudioSessionOverrideAudioRoute_Speaker ='spkr'
;
enum
kAudioSessionOverrideAudioRoute_None = 0,
kAudioSessionOverrideAudioRoute_Speaker = 'spkr'
;
Override audio route的方法有如下两种:
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (
kAudioSessionProperty_OverrideAudioRoute
sizeof(audioRouteOverride),
&audioRouteOverride
);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (
kAudioSessionProperty_OverrideAudioRoute
sizeof (audioRouteOverride),
&audioRouteOverride
);
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof(doChangeDefaultRoute),
&doChangeDefaultRoute
);
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof (doChangeDefaultRoute),
&doChangeDefaultRoute
);
这两种方法区别在于:
使用kAudioSessionProperty_OverrideAudioRoute时,当发生任何中断如插拔耳机时,audio route就会重置回听筒,你必须再设置一次。
使用kAudioSessionProperty_OverrideCategoryDefaultToSpeaker则除非你更改category,否则会一直生效。
转自 http://blog.csdn.net/xy5811/article/details/8563137
在获得一个AVAudioSession类的实例后,你就能通过调用 音频 会话对象的setCategory:error:实例方法,来从 IOS 应用可用的不同类别中作出选择。下面列出了可供使用的音频会话类别:
AVAudioSessionCategorySoloAmbient
这个类别非常像AVAudioSessionCategoryAmbient类别,除了会停止其他程序的音频回放,比如iPod程序。当设备被设置为静音模式,你的音频回放将会停止。
AVAudioSessionCategoryRecord
这会停止其他应用的声音(比如iPod)并让你的应用也不能初始化音频回放(比如AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个类别,调用AVAudioPlayer的prepareToPlay会返回YES,但是调用play方法将返回NO。主UI界面会照常工作。这时,即使你的设备屏幕被用户锁定了,应用的录音仍会继续。
AVAudioSessionCategoryPlayback
这个类别会静止其他应用的音频回放(比如iPod应用的音频回放)。你可以使用AVAudioPlayer的prepareToPlay和play方法,在你的应用中播放声音。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放都会继续。
AVAudioSessionCategoryPlayAndRecord
这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后,其他应用的声音播放将会停止。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放和录制都会继续。
AVAudioSessionCategoryAudioProcessing
这个类别用于应用中进行音频处理的情形,而不是音频回放或录制。设置了这种模式,你在应用中就不能播放和录制任何声音。调用AVAPlayer的prepareToPlay和play方法都将返回NO。其他应用的音频回放,比如iPod,也会在此模式下停止。
AVAudioSessionCategoryAmbient
这个类别不会停止其他应用的声音,相反,它允许你的音频播放于其他应用的声音之上,比如iPod。你的应用的主UI县城会工作正常。调用AVAPlayer的prepareToPlay和play方法都将返回YES。当用户锁屏时,你的应用将停止所有正在回放的音频。仅当你的应用是唯一播放该音频文件的应用时,静音模式将停止你程序的音频回放。如果正当iPod播放一手歌时,你开始播放音频,将设备设为静音模式并不能停止你的音频回放。
Android自制静音App,解决他人手机外放问题
契源
看到一个粉丝留言,吐槽舍友深夜手机外放,打扰别人休息,想设计一款软件阻止舍友行径。于是我就来简单设计一下。
需求实现分析
实际上,我之前有篇博文提到过一个类似的Android APP,主要功能是将手机声音强制开到最大,然后播放背景音乐。再之前的那个基础上,删除音乐文件,然后将手机声音调小就满足了此需求。
效果演示
这个软件很快就做出来了,效果演示如下:
轻轻一键,世界清净了
软件下载地址:https://www.pgyer.com/ikCz
软件源码:https://github.com/zstar1003/Mute
具体功能分析
软件本身比较简单,主要包含下面几个部分
音量调节
软件核心功能是设置音量为0,这在Android中,可以使用AudioManager
这个类中的相关API,核心代码:
am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
//启动线程循环设置音量
new Thread()
@TargetApi(Build.VERSION_CODES.P)
public void run()
//这儿是耗时操作,完成之后更新UI;
while(true)
final int m = am.getStreamMinVolume(AudioManager.STREAM_MUSIC); //设置静音
runOnUiThread(new Runnable()
@Override
public void run()
//更新UI
am.setStreamVolume(AudioManager.STREAM_MUSIC, m, AudioManager.FLAG_PLAY_SOUND);
);
try
sleep(500);
catch (InterruptedException e)
.start();
监听按钮
此次功能是监听返回主页,调节音量按钮,监听到之后弹出气泡框提示
核心代码:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
if(keyCode==KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_BACK || keyCode== KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
Toast toast = Toast.makeText(this,null,Toast.LENGTH_LONG);
toast.setText("别试了,没用的!");
toast.show();
return true;
return super.onKeyDown(keyCode, event);
按钮点击
在主页上加了个功能,点击按钮切换图片,并且达到指定次数后,退出软件
//按钮点击事件
final Button bt = findViewById(R.id.activitymainButton);
final ImageView kt = findViewById(R.id.kt);
bt.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View p1)
if(num != 0)
num--;
bt.setText("对不起,我错了\\n"+"再点"+num+"下就关闭程序");
else
finish();
if(num % 2 == 0)
kt.setImageResource(R.drawable.xu1);
else
kt.setImageResource(R.drawable.xu2);
);
隐藏标题栏/修改通知栏颜色
下面再做点小优化,让UI看起来更舒适
隐藏标题栏:
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
修改通知栏颜色:
Window window = this.getWindow();
window.setStatusBarColor(0xFFcfde29);
按钮美化
按钮美化,在drawable
中,新建一个按钮皮肤xml文件,为按钮点击和非点击状态设置不同颜色
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#64AFFA"/>
<corners android:radius="10dp"/>
<padding
android:bottom="2dp"
android:left="33dp"
android:right="33dp"
android:top="2dp">
</padding>
</shape>
</item>
<item android:state_pressed="false">
<shape>
<solid android:color="#99CCFF"/>
<corners android:radius="10dp"/>
<padding
android:bottom="2dp"
android:left="33dp"
android:right="33dp"
android:top="2dp">
</padding>
</shape>
</item>
</selector>
拓展思考
开发过程中,我发现部分手机已经做的相当“智能”,即便监听阻止返回按键,手机还是可以轻易调出清除进程等方式来退出软件。
我试图想把软件做的更“流氓”一些,想到了以下思路:
- 加入一个系统级服务,不停地设置音量静音
- 加入一个系统级服务,监听Activity是否被Kill,若被Kill则重启
- 加入一个系统级服务,监听开机广播,开机自启软件
- 在软件界面中增加更多手势的识别,以防止用户呼出软件管理界面
- …
不过经过一番调研,以上思路均无办法实现,很多能找到的方法基本都不适配Android10以后的版本,在手机厂商的不断迭代中,除非将软件加入到系统的白名单,否则还是会被用户所管理。
最后总结,此软件仅供娱乐,解决舍友手机外放问题靠软件手段无法从根源上解决,在此呼吁读者在非单人空间切勿手机外放,影响他人生活休息。
以上是关于主要解决录音时候不能让当前app内音外放的主要内容,如果未能解决你的问题,请参考以下文章