setSpeakerphoneOn 方法可以使语音和通话能够强制从手机的扬声器输出,不过在测试了众多手机在调用了这个API之后都可以,唯独有一款VIVO手机不可以:

.小米6X(9.0)
.Samsung s7e(7.0)
.Google piexl 2xl(10.0)
.诺基亚x7(9.0)
.华为nova3e(8.0)
.小米6(8.0)
.锤子T2(5.1.)
.HTC M8(6.0)
.小米4(4.4.)
.华硕zenfone3(8.0)
.Samsung note8(7.1.)
.LG G6(7.0)
.HTC M10(8.0)
.LG G5(7.0)
.一加5T(7.1.)
.华为荣耀v10(9.0)
.MEIZU Note2(5.1)
--》以上17款均pass
.vivo x20p(8.0)--》Fail

解决方法:

 final static int FOR_MEDIA = 1;
final static int FORCE_NONE = 0;
final static int FORCE_SPEAKER = 1;
final static int FORCE_HEADPHONES = 2; public void switchSpeaker() {
if (RomUtil.isVivo()) {
Log.i(TAG, "switchSpeaker: This is vivo phone");
try {
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "switchSpeaker: others"); mAudioManager.setMicrophoneMute(false);
mAudioManager.setSpeakerphoneOn(true);//使用扬声器外放,即使已经插入耳机
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
}
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
} public void switchHeadset() {
if (RomUtil.isVivo()) {
Log.i(TAG, "switchSpeaker: This is vivo phone");
try {
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_HEADPHONES);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "switchSpeaker: others");
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(false);
}
}

RomUtil.java

package com.hxzk.som.base.utils;

import android.os.Build;
import android.text.TextUtils;
import android.util.Log; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; /**
* Created by HaiyuKing
* Used 判断手机ROM,检测ROM是MIUI、EMUI还是Flyme
* 参考资料:https://www.jianshu.com/p/ba9347a5a05a
*/
public class RomUtil {
private static final String TAG = "Rom"; public static final String ROM_MIUI = "MIUI";
public static final String ROM_EMUI = "EMUI";
public static final String ROM_FLYME = "FLYME";
public static final String ROM_OPPO = "OPPO";
public static final String ROM_SMARTISAN = "SMARTISAN";
public static final String ROM_VIVO = "VIVO";
public static final String ROM_QIKU = "QIKU"; private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";
private static final String KEY_VERSION_EMUI = "ro.build.version.emui";
private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";
private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version";
private static final String KEY_VERSION_VIVO = "ro.vivo.os.version"; private static String sName;
private static String sVersion; //华为
public static boolean isEmui() {
return check(ROM_EMUI);
}
//小米
public static boolean isMiui() {
return check(ROM_MIUI);
}
//vivo
public static boolean isVivo() {
return check(ROM_VIVO);
}
//oppo
public static boolean isOppo() {
return check(ROM_OPPO);
}
//魅族
public static boolean isFlyme() {
return check(ROM_FLYME);
}
//360手机
public static boolean is360() {
return check(ROM_QIKU) || check("360");
} public static boolean isSmartisan() {
return check(ROM_SMARTISAN);
} public static String getName() {
if (sName == null) {
check("");
}
return sName;
} public static String getVersion() {
if (sVersion == null) {
check("");
}
return sVersion;
} public static boolean check(String rom) {
if (sName != null) {
return sName.equals(rom);
} if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) {
sName = ROM_MIUI;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) {
sName = ROM_EMUI;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) {
sName = ROM_OPPO;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) {
sName = ROM_VIVO;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) {
sName = ROM_SMARTISAN;
} else {
sVersion = Build.DISPLAY;
if (sVersion.toUpperCase().contains(ROM_FLYME)) {
sName = ROM_FLYME;
} else {
sVersion = Build.UNKNOWN;
sName = Build.MANUFACTURER.toUpperCase();
}
}
return sName.equals(rom);
} public static String getProp(String name) {
String line = null;
BufferedReader input = null;
try {
Process p = Runtime.getRuntime().exec("getprop " + name);
input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
line = input.readLine();
input.close();
} catch (IOException ex) {
Log.e(TAG, "Unable to read prop " + name, ex);
return null;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return line;
}
}

参考链接:

1. VIVO官网:音频类AudioManager接口使用规范

2. Android 4.3之系统setSpeakPhoneOn 实现Audio ouput path 切换

3. how to turn speaker on/off programmatically in android 4.0

Android: VIVO手机setSpeakerphoneOn p无效,无法切换speaker的问题的更多相关文章

  1. android 控制手机的体积的大小 切换音效模式

    (1)项目介绍 于android API的AudioManager于,它提供了一种方法来调整电话音量. audioMa.adjustVolume(AudioManager.ADJUST_LOWER, ...

  2. RomUtil【Android判断手机ROM,用于判断手机机型】

    参考资料 Android判断手机ROM 正文 有时候需要判断手机系统的ROM,检测ROM是MIUI.EMUI还是Flyme,可以使用getprop命令,去系统build.prop文件查找是否有对应属性 ...

  3. EasyRTMP Android安卓手机直播推流摄像头偏暗的问题解决

    在我们测试EasyRTMP Android安卓手机推流的过程中发现有些设备预览时,明显偏暗!在稍微暗点的环境中几乎很难看清东西-额,这是怎么回事呢?又是安卓设备的兼容性问题,头疼! !!!好吧,停止抱 ...

  4. Android之手机向导以及设置中心模块的开发

    当我们使用的新的软件的时候,我们首先需要教用户如何使用我们的软件,当用户学习完使用教程,下次再登录的时候,我们应该直接跳到我们的功能界面,下面我来展示一下我学习视频做的效果图:手机防盗这个功能模块就是 ...

  5. Android:使用ViewPager实现左右滑动切换图片(图上有点点)

    在以下实例的基础上加上点点 Android:使用ViewPager实现左右滑动切换图片 (简单版) 效果预览: 因为要把点点放图片上,所以修改布局为相对布局: <?xml version=&qu ...

  6. Android:使用ViewPager实现左右滑动切换图片 (简单版)

    ViewPager,它是google SDk中自带的一个附加包的一个类, 可以使视图滑动. 步骤: 1.引入android-support-v4.jar包,在主布局里加入 <android.su ...

  7. 高仿优酷Android客户端图片左右滑动(自动切换)

    本例是用ViewPager去做的实现,支持自动滑动和手动滑动,不仅优酷网,实际上有很多商城和门户网站都有类似的实现: 具体思路: 1. 工程中需要添加android-support-v4.jar,才能 ...

  8. Android使得手机拍照功能的发展(源共享)

    Android系统调用手机拍照功能有两种方法来直接调用手机自带摄像头还有一个就是要当心自己的节拍. 例Camera360 强大的一个在每个操作系统都有一个手机摄影软件:您可以捕捉不同风格,不同特效的照 ...

  9. Android Studio 代码自动提示无效

    Android Studio代码自动提示无效(not available in Power Save mode)的解决办法 问题描述: 今天用Android studio敲代码,突然间就没有代码提示了 ...

随机推荐

  1. [LeetCode] 78. 子集 ☆☆☆(回溯)

    描述 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3],  [1],  [2] ...

  2. 《我是一只IT小小鸟》读书笔记——第七周

    我是一只IT小小鸟,每一个程序员都是从这样的阶段成长起来的,问题是是否能一开始就找到正确的路径,少走弯路.本书收集了许多年轻程序员从大学开始到就业的成长之路,十分有指导价值也很让人深思. 切忌急功近利 ...

  3. day 07 预科

    目录 异常处理 字符串内置方法 1.索引取值 2.切片 3.成员运算 4.for循环 5.len() 6.strip(): 默认去掉两端空格 7.lsteip()/rstrip(): 去左端/右端 空 ...

  4. Vue+Django项目部署

    本地项目配置 1 复制 luffy/settings/dev.py为prop.py 修改luffy/settings/prop.py中以下几项 (1) allow_hosts ALLOWED_HOST ...

  5. CentOS7安装MySQL5.7及Tomcat8.5

    在CentOS7服务器上部署FR项目应用 一.安装CentOS-7_x86_64 1.CentOS7:带GUI的服务器(FTP服务器.JAVA平台.兼容性程序库.开发工具.安全性工具.系统管理工具): ...

  6. KMP算法的时间复杂度与next数组分析

    一.什么是 KMP 算法 KMP 算法是一种改进的字符串匹配算法,用于判断一个字符串是否是另一个字符串的子串 二.KMP 算法的时间复杂度 O(m+n) 三.Next 数组 - KMP 算法的核心 K ...

  7. scrapy框架爬取智联招聘网站上深圳地区python岗位信息。

    爬取字段,公司名称,职位名称,公司详情的链接,薪资待遇,要求的工作经验年限 1,items中定义爬取字段 import scrapy class ZhilianzhaopinItem(scrapy.I ...

  8. P1856 [USACO5.5]矩形周长Picture[扫描线]

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  9. test20190925 老L

    100+0+0=100.概率题套路见的太少了,做题策略不是最优的. 排列 给出 n 个二元组,第 i 个二元组为(ai,bi). 将 n 个二元组按照一定顺序排成一列,可以得到一个排列.显然,这样的排 ...

  10. kvm创建windows2008虚拟机

    virt-install -n win2008-fushi001 -r 16384 --vcpus=4 --os-type=windows --accelerate -c /data/kvm/imag ...