• Android: VIVO手机setSpeakerphoneOn p无效,无法切换speaker的问题


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

    1.小米6X(9.02.Samsung s7e(7.03.Google piexl 2xl(10.04.诺基亚x7(9.05.华为nova3e(8.06.小米6(8.07.锤子T2(5.1.18.HTC M8(6.09.小米4(4.4.210.华硕zenfone3(8.011.Samsung note8(7.1.112.LG G6(7.013.HTC M10(8.014.LG G5(7.015.一加5T(7.1.116.华为荣耀v10(9.017.MEIZU Note2(5.1--》以上17款均pass
    18.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

  • 相关阅读:
    Rancher 2.1平台搭建及使用
    回归博客园
    CGI与FastCGI
    [转]1小时内打造你自己的PHP MVC框架
    MySQL学习随笔--通过实例理解merge ,temptable算法的差异
    MySQL学习随笔--视图
    使用onenote写博客园的方法
    手动配置wamp环境(1)--apache安装与基本操作
    文档兼容性定义,使ie按指定的版本解析
    JavaScript线程
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/11913133.html
Copyright © 2020-2023  润新知