求助,耳机和外放都有声音插入手机后播放音乐还是外放

你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
这个问题一直都困扰我很久了,手机外放音乐是不是比用耳机听歌更费电?我一直认为外发,可能要多启动一个扩音的功能,所以可能手机外放要比耳机听歌要更加费电。但是朋友又说用耳机相当于接入了一个外部设备,也会持续消耗手机的电量。请问到底哪个更费电?为什么呢?有什么原理?
采用不同的外放形式,耗电量自然是不一样的。
首先我们要确定一点,那就是手机公放音乐是利用手机内部的扬声器实现的,不管扬声器的功率有多小,扬声器内部铁磁性物质的环流耗电量也要比驱动耳机所需的要大。
原理上来说,耳机调音量就是改变电阻,一般手机扬声器的额定功率都在0.5W~0.8W,耳塞的功率则一般不高于40mW (0.04W),所以,插耳机听音乐自然会更省电一些。
要回复问题请先或
浏览: 5067
关注: 2 人经验210 米
在线时间1 小时
版本V8.2.1.0.MBCCNDL
积分 212, 距离下一级还需 288 积分
积分 212, 距离下一级还需 288 积分
机型小米Max 标准版
签到次数15
MIUI版本V8.2.1.0.MBCCNDL
小米Max 标准版
V7.5.2.0.MBCCNDE
小米max,买了一个月,最近发现插入耳机后,在拔出就没有声音了,只是不间断的出现爆破声,只有重启后才能恢复正常。现象偶尔出现。
分享到微信朋友圈
打开微信,点击底部的“发现”,使用 “扫一扫” 即可将网页分享到我的朋友圈。
经验3919 米
在线时间260 小时
机型小米手机3/4 WCDMA版
MIUI版本7.1.3
恩,好的,感谢您的反馈。
经验2152 米
在线时间200 小时
版本7.9.21
积分 2637, 距离下一级还需 2363 积分
积分 2637, 距离下一级还需 2363 积分
机型小米手机5
签到次数44
MIUI版本7.9.21
我也有!!!!!
在线时间2 小时
版本V9.0.3.0.NCACNEI
积分 59, 距离下一级还需 141 积分
积分 59, 距离下一级还需 141 积分
机型小米手机6
MIUI版本V9.0.3.0.NCACNEI
Copyright (C) 2017 MIUI
京ICP备号 | 京公网安备34号 | 京ICP证110507号再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
威锋网7月10日消锋网7月10日消息,《植物大战僵尸2》 如今...
威锋网7月10日消息,《植物大...
近日,开发商 Esquilax Games ..
说到方块游戏,相信有很多朋友应该还会记得 Gavina Games 早...
威锋网7月10日消息,《植物大...
近日,开发商 Esquilax Games ..
说到方块游戏,相信有很多朋友应该还会记得 Gavina Games 早...
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
您需要通过验证再能继续浏览 3秒后开始验证
威锋旗下产品
Hi~我是威威!
 粤公网安备 11号
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!&nbsp&#8250&nbsp&nbsp&#8250&nbsp
Android音乐播放模式切换-外放、听筒、耳机
原文出处:&最近比较忙,好久都没有更新博客!最近由于项目需求要做音乐播放模式的切换,经过好多次尝试,发现这里面满满的都是坑啊,所以就写一篇日志记录下来,也给大家分享下遇到的坑及解决办法.场景需求在聊天场景中,收到对方语音时,用户可以选择外放播放,也可以选择插入耳机收听.更人性化一点当用户把手机靠近耳朵时屏幕关闭自动切换到听筒中播放,播放完毕后拿开手机屏幕自动点亮.比如微信就是如此.需求分析从上面场景中我们可以得出我们需要的要点:播放模式切换:外放&―-&耳机播放模式切换:外放&―-&听筒屏幕操作:亮屏&―-&息屏&―-&亮屏解决问题从需求分析我们可以得出需要代码进行控制的有:音乐播放控制外放,耳机,听筒之间的切换屏幕的息屏与亮屏音乐播放控制音乐播放控制最简单,直接使用MediaPlayer即可,为了更好地与界面代码分离以及更好控制音乐,这里写了一个控制类:PlayerManager,如下:/**
&*&音乐播放管理类
&*&Created&by&DevWiki&on&&0027.
public&class&PlayerManager&{
&&&&private&static&PlayerManager&playerM
&&&&private&MediaPlayer&mediaP
&&&&private&PlayCallback&
&&&&private&Context&
&&&&private&String&fileP
&&&&public&static&PlayerManager&getManager(){
&&&&&&&&if&(playerManager&==&null){
&&&&&&&&&&&&synchronized&(PlayerManager.class){
&&&&&&&&&&&&&&&&playerManager&=&new&PlayerManager();
&&&&&&&&&&&&}
&&&&&&&&return&playerM
&&&&private&PlayerManager(){
&&&&&&&&this.context&=&MyApplication.getContext();
&&&&&&&&mediaPlayer&=&new&MediaPlayer();
&&&&&*&播放回调接口
&&&&public&interface&PlayCallback{
&&&&&&&&/**&音乐准备完毕&*/
&&&&&&&&void&onPrepared();
&&&&&&&&/**&音乐播放完成&*/
&&&&&&&&void&onComplete();
&&&&&&&&/**&音乐停止播放&*/
&&&&&&&&void&onStop();
&&&&&*&播放音乐
&&&&&*&@param&path&音乐文件路径
&&&&&*&@param&callback&播放回调函数
&&&&public&void&play(String&path,&final&PlayCallback&callback){
&&&&&&&&this.filePath&=&
&&&&&&&&this.callback&=&
&&&&&&&&try&{
&&&&&&&&&&&&mediaPlayer.reset();
&&&&&&&&&&&&mediaPlayer.setDataSource(context,&Uri.parse(path));
&&&&&&&&&&&&mediaPlayer.prepare();
&&&&&&&&&&&&mediaPlayer.setOnPreparedListener(new&MediaPlayer.OnPreparedListener()&{
&&&&&&&&&&&&&&&&@Override
&&&&&&&&&&&&&&&&public&void&onPrepared(MediaPlayer&mp)&{
&&&&&&&&&&&&&&&&&&&&callback.onPrepared();
&&&&&&&&&&&&&&&&&&&&mediaPlayer.start();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&});
&&&&&&&&}&catch&(IOException&e)&{
&&&&&&&&&&&&e.printStackTrace();
&&&&&*&停止播放
&&&&public&void&stop(){
&&&&&&&&if&(isPlaying()){
&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&mediaPlayer.stop();
&&&&&&&&&&&&&&&&callback.onStop();
&&&&&&&&&&&&}&catch&(IllegalStateException&e)&{
&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&}
&&&&&*&是否正在播放
&&&&&*&@return&正在播放返回true,否则返回false
&&&&public&boolean&isPlaying()&{
&&&&&&&&return&mediaPlayer&!=&null&&&&mediaPlayer.isPlaying();
}为了方便获取Context,覆写了Application类如下:/**
&*&APP的Application
&*&Created&by&DevWiki&on&&0016.
public&class&MyApplication&extends&Application&{
&&&&private&static&Context&
&&&&@Override
&&&&public&void&onCreate()&{
&&&&&&&&super.onCreate();
&&&&&&&&context&=&
&&&&&*&获取APP的Context方便其他地方调用
&&&&&*&@return
&&&&public&static&Context&getContext(){
&&&&&&&&return&
}外放,耳机,听筒之间的切换在Android系统中是用AudioManager来管理播放模式的,通过AudioManager.setMode()方法来实现.在setMode()方法中有以下几种对应不同的播放模式:MODE_NORMAL: 普通模式,既不是铃声模式也不是通话模式MODE_RINGTONE:铃声模式MODE_IN_CALL:通话模式MODE_IN_COMMUNICATION:通信模式,包括音/视频,VoIP通话.(3.0加入的,与通话模式类似)其中:播放音乐的对应的就是MODE_NORMAL, 如果使用外放播则调用audioManager.setSpeakerphoneOn(true)即可.若使用耳机和听筒,则需要先设置模式为MODE_IN_CALL(3.0以前)或MODE_IN_COMMUNICATION(3.0以后).注意:需要权限android.permission.MODIFY_AUDIO_SETTINGS为什么在3.0以后设置模式为MODE_IN_COMMUNICATION,而不设置为MODE_IN_CALL?经验证在华为的某些机型中,设置MODE_IN_CALL根本不起作用.故在PlayerManager类中持有一个AudioManager变量,并添加如下几个方法:audioManager&=&(AudioManager)&context.getSystemService(Context.AUDIO_SERVICE);
&*&切换到外放
public&void&changeToSpeaker(){
&&&&audioManager.setMode(AudioManager.MODE_NORMAL);
&&&&audioManager.setSpeakerphoneOn(true);
&*&切换到耳机模式
public&void&changeToHeadset(){
&&&&audioManager.setSpeakerphoneOn(false);
&*&切换到听筒
public&void&changeToReceiver(){
&&&&audioManager.setSpeakerphoneOn(false);
&&&&if&(Build.VERSION.SDK_INT&&=&Build.VERSION_CODES.HONEYCOMB){
&&&&&&&&audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
&&&&}&else&{
&&&&&&&&audioManager.setMode(AudioManager.MODE_IN_CALL);
}如何判断用户是否插入耳机呢?在插入或者拔出耳机时系统会发出Action为Intent.ACTION_HEADSET_PLUG的广播,并且该广播不能使用静态接收器处理,故写一个广播接收器处理耳机事件即可.class&HeadsetReceiver&extends&BroadcastReceiver{
&&&&@Override
&&&&public&void&onReceive(Context&context,&Intent&intent)&{
&&&&&&&&String&action&=&intent.getAction();
&&&&&&&&switch&(action){
&&&&&&&&&&&&//插入和拔出耳机会触发此广播
&&&&&&&&&&&&case&Intent.ACTION_HEADSET_PLUG:
&&&&&&&&&&&&&&&&int&state&=&intent.getIntExtra(&state&,&0);
&&&&&&&&&&&&&&&&if&(state&==&1){
&&&&&&&&&&&&&&&&&&&&playerManager.changeToHeadset();
&&&&&&&&&&&&&&&&}&else&if&(state&==&0){
&&&&&&&&&&&&&&&&&&&&playerManager.changeToSpeaker();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&default:
&&&&&&&&&&&&&&&&
}屏幕的息屏与亮屏屏幕息屏与亮屏有个前提是正确判断用户是否靠近听筒,如何判断?现在几乎每个手机都有距离感应器,通过举例感应器可获得距离.距离感应器由SensorManager管理:sensorManager&=&(SensorManager)&getSystemService(SENSOR_SERVICE);
sensor&=&sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
sensorManager.registerListener(this,&sensor,&SensorManager.SENSOR_DELAY_NORMAL);注册监听的方法的最后一个参数是敏感度,敏感度越高越费电,此处选择一般敏感度即可.此外Activity还需实现SensorEventListener接口,覆写其方法:@Override
public&void&onSensorChanged(SensorEvent&event)&{
&&&&float&value&=&event.values[0];
&&&&if&(playerManager.isPlaying()){
&&&&&&&&if&(value&==&sensor.getMaximumRange())&{
&&&&&&&&&&&&playerManager.changeToSpeaker();
&&&&&&&&&&&&setScreenOn();
&&&&&&&&}&else&{
&&&&&&&&&&&&playerManager.changeToReceiver();
&&&&&&&&&&&&setScreenOff();
&&&&}&else&{
&&&&&&&&if(value&==&sensor.getMaximumRange()){
&&&&&&&&&&&&playerManager.changeToSpeaker();
&&&&&&&&&&&&setScreenOn();
}在Android系统中硬件的工作状态的控制由PowerManager与WakeLock掌管.PowerManager通过不同的WakeLock来控制CPU,屏幕,键盘等硬件的工作状态.powerManager&=&(PowerManager)&getSystemService(POWER_SERVICE);
wakeLock&=&powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,&TAG);注意:需要权限android.Manifest.permission.DEVICE_POWER和android.permission.WAKE_LOCK其中第一个参数代表控制级别,可选值有:PARTIAL_WAKE_LOCK : CPU运行,屏幕和键盘可能关闭SCREEN_DIM_WAKE_LOCK : 屏幕亮,键盘灯可能关闭SCREEN_BRIGHT_WAKE_LOCK : 屏幕全亮,键盘灯可能关闭FULL_WAKE_LOCK : 屏幕和键盘灯全亮PROXIMITY_SCREEN_OFF_WAKE_LOCK : 屏幕关闭,键盘灯关闭,CPU运行DOZE_WAKE_LOCK : 屏幕灰显,CPU延缓工作此处我们选取PROXIMITY_SCREEN_OFF_WAKE_LOCK.WakeLock通过acquire()和release()方法上锁和解锁.private&void&setScreenOff(){
&&&&if&(wakeLock&==&null){
&&&&&&&&wakeLock&=&powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,&TAG);
&&&&wakeLock.acquire();
private&void&setScreenOn(){
&&&&if&(wakeLock&!=&null){
&&&&&&&&wakeLock.setReferenceCounted(false);
&&&&&&&&wakeLock.release();
&&&&&&&&wakeLock&=&
}开始验证通过以上三个解决方案,然后运行程序可知基本满足功能需求.但是有以下几个问题:耳机模式下用手遮挡距离感应器会切换到听筒三星Note,华为P,华为Mate系列会出现外放切换到听筒,听筒切换到外放出现卡顿现象耳机切换到外放会出现丢失语音三星,华为手机在熄灭屏幕是会调用Activity的onPause(),onStop()方法!!解决新问题耳机模式用手遮挡距离感应器问题此问题只需在耳机模式下对距离感应器不做响应即可,在PlayerManager中添加:/**
&*&耳机是否插入
&*&@return&插入耳机返回true,否则返回false
@SuppressWarnings(&deprecation&)
public&boolean&isWiredHeadsetOn(){
&&&&return&audioManager.isWiredHeadsetOn();
}然后修改距离感应器回调方法为:@Override
public&void&onSensorChanged(SensorEvent&event)&{
&&&&float&value&=&event.values[0];
&&&&if&(playerManager.isWiredHeadsetOn()){
&&&&if&(playerManager.isPlaying()){
&&&&&&&&if&(value&==&sensor.getMaximumRange())&{
&&&&&&&&&&&&playerManager.changeToSpeaker();
&&&&&&&&&&&&setScreenOn();
&&&&&&&&}&else&{
&&&&&&&&&&&&playerManager.changeToReceiver();
&&&&&&&&&&&&setScreenOff();
&&&&}&else&{
&&&&&&&&if(value&==&sensor.getMaximumRange()){
&&&&&&&&&&&&playerManager.changeToSpeaker();
&&&&&&&&&&&&setScreenOn();
}三星,华为听筒外放切换卡顿这个问题只能采用折中的办法:重新播放为何采用此方法?短的语音本来就短,切换重播几乎不受影响长得音乐一般不会用听筒听不是所有的手机都会出现卡顿故在PlayerManager中修改方法:/**
&*&切换到听筒
public&void&changeToReceiver(){
&&&&if&(isPlaying()){
&&&&&&&&stop();
&&&&&&&&changeToReceiverNoStop();
&&&&&&&&play(filePath,&callback);
&&&&}&else&{
&&&&&&&&changeToReceiverNoStop();
&*&切换到外放
public&void&changeToSpeaker(){
&&&&if&(PhoneModelUtil.isSamsungPhone()&||&PhoneModelUtil.isHuaweiPhone()){
&&&&&&&&stop();
&&&&&&&&changeToSpeakerNoStop();
&&&&&&&&play(filePath,&callback);
&&&&}&else&{
&&&&&&&&changeToSpeakerNoStop();
public&void&changeToSpeakerNoStop(){
&&&&audioManager.setMode(AudioManager.MODE_NORMAL);
&&&&audioManager.setSpeakerphoneOn(true);
}耳机切换到外放会出现丢失语音此问题由于耳机切换到外放需要一段时间导致,故解决此问题的方法是先暂停再续播.那么什么时候暂停什么时候续播呢?查资料得知,在耳机拔出时系统还会发出Action为AudioManager.ACTION_AUDIO_BECOMING_NOISY的广播,且此广播比Intent.ACTION_HEADSET_PLUG要早,所以解决方案也出来了:收到AudioManager.ACTION_AUDIO_BECOMING_NOISY时暂停播放,收到Intent.ACTION_HEADSET_PLUG并且附带的state=1时续播三星,华为手机在熄灭屏幕是会调用Activity的onPause(),onStop()方法这个问题嘛,其实也不算问题,但是值得注意.如果你在onStop()中做了某些释放资源的操作,那么在onStart()中就要重新获取,防止出现其他问题.后记项目代码请点击此处:我的更多信息:
上一篇: 背景 为了优化用户体验,我们往往会在让用户输入手机号码时添加空格,比如:133 .那么在Android中如何实现呢? 实现方法 Android中的输入框EditText有个方法addTextChangedListener(),该方法实现输入框文字变动时的监听.该方法需要传入一个TextWatcher
下一篇: 原文出处: http://blog.csdn.net/harvic880925/article/details/ 一、概述 1、SpannableString、SpannableStringBuilder与String的关系 首先SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在

我要回帖

更多关于 耳机和外放都有声音 的文章

 

随机推荐