Android为拨号盘dialer定制声音DTMF Tones

简介:

DTMF :双音多频,电话系统中电话机与交换机之间的一种用户信令,通常用于发送被叫号码。

双音多频的拨号键盘是4*4的矩阵,每一行代表一个低频,每一列代表一个高频,每按一个键就发送一个高频和低频的正弦信号组合。比如'1'相当于697和1209赫兹(Hz)。交换机可以解码这些频率组合并确定所对应的按键。

现在我就想给自己的拨号键盘加上双音多频的声音,类似于固定电话拨号的声音。

页面就不贴出来了,类似于系统的拨号盘。

public class DialActivity extends Activity implements OnClickListener{
 
    private static String TAG = "【DialApp】";
    private static final int PLAY_TONE = 0x01;
    private static final int DTMF_DURATION_MS = 120; // 声音的播放时间
    private Object mToneGeneratorLock = new Object(); // 监视器对象锁
    private ToneGenerator mToneGenerator;             // 声音产生器
    private static boolean mDTMFToneEnabled;         // 系统参数“按键操作音”标志位
    // 存储DTMF Tones
    private static final HashMap mToneMap = new HashMap();
 
    static {
        mToneMap.put('1', ToneGenerator.TONE_DTMF_1);
        mToneMap.put('2', ToneGenerator.TONE_DTMF_2);
        mToneMap.put('3', ToneGenerator.TONE_DTMF_3);
        mToneMap.put('4', ToneGenerator.TONE_DTMF_4);
        mToneMap.put('5', ToneGenerator.TONE_DTMF_5);
        mToneMap.put('6', ToneGenerator.TONE_DTMF_6);
        mToneMap.put('7', ToneGenerator.TONE_DTMF_7);
        mToneMap.put('8', ToneGenerator.TONE_DTMF_8);
        mToneMap.put('9', ToneGenerator.TONE_DTMF_9);
        mToneMap.put('0', ToneGenerator.TONE_DTMF_0);
        mToneMap.put('#', ToneGenerator.TONE_DTMF_P);
        mToneMap.put('*', ToneGenerator.TONE_DTMF_S);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //按键声音播放设置及初始化
        try {
            // 获取系统参数“按键操作音”是否开启
            mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
                    Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
            synchronized (mToneGeneratorLock) {
                if (mDTMFToneEnabled && mToneGenerator == null) {
                    mToneGenerator = new ToneGenerator(
                            AudioManager.STREAM_DTMF, 80); // 设置声音的大小
                    setVolumeControlStream(AudioManager.STREAM_DTMF);
                }
            }
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
            mDTMFToneEnabled = false;
            mToneGenerator = null;
        }
        /*
         * 拨号按钮注册监听事件
         * 
         */
    }
    @Override
    public void onClick(View view) {
        int id = view.getId();   //点击按钮的id
        Integer currentTone;     //获得当前的Tone
        switch(id){
        case R.id.digit1:
            mToneMap.get("1");
            break;
        case R.id.digit2:
            mToneMap.get("2");
            break;
            .
            .
            .        
        }
        if (null != currentTone) {
            //第一种方式,采用Handler消息机制进行发声
            Message msg = mHandler.obtainMessage(PLAY_TONE, currentTone);
            mHandler.sendMessage(msg);
            //第二种方式,直接调用playTone(int tone)方法,不知道二者有何区别?希望大家给点意见。
//            playTone(currentTone);
        }
    }
    /**
     * 处理按键响应事件的消息
     */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            try {
                switch (msg.what) {
                case PLAY_TONE:
                    Integer tone_id = (Integer) msg.obj;
                    if (tone_id != null) {
                        playTone(tone_id.intValue());
                    }
                    break;
                }
            } catch (Exception ex) {
                Log.d(TAG, ex.getMessage());
            }
        }
    };
 
    /**
     * 播放按键声音
     */
    private void playTone(int tone) {
        if (!mDTMFToneEnabled) {
            return;
        }
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int ringerMode = audioManager.getRingerMode();
        if (ringerMode == AudioManager.RINGER_MODE_SILENT
                || ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
            // 静音或者震动时不发出声音
            return;
        }
        synchronized (mToneGeneratorLock) {
            if (mToneGenerator == null) {
                Log.w(TAG, "playTone: mToneGenerator == null, tone: " + tone);
                return;
            }
            mToneGenerator.startTone(tone, DTMF_DURATION_MS);   //发出声音
        }
    }
}
  

,如需转载请自行联系原作者


相关文章
|
4月前
|
XML Java 调度
Android开发音效增强中铃声播放Ringtone及声音池调度SoundPool的讲解及实战(超详细 附源码)
Android开发音效增强中铃声播放Ringtone及声音池调度SoundPool的讲解及实战(超详细 附源码)
48 0
|
Android开发
Android隐藏虚拟按键,关闭开机动画、开机声音
/*********************************************************************** * Android隐藏虚拟按键,关闭开机动画、开机声音 * 声明: * 有时候,我们可能会希望隐藏掉android中的虚拟按键,当然,那个 * Android的开机动画,有时候也是挺讨人厌的,也是可以隐藏的。
882 0
|
Android开发
android各种声音类型级数设定及默认值
android各种声音类型级数设定及默认值            在audioservice.java文件中: /** @hide Maximum volume index values for audio streams */ ...
836 0
|
Android开发 语音技术 Java
|
大数据 Android开发
我的Android进阶之旅------>android视频播放只有声音无画面的解决办法
            今天调试公司用VideoView实现的播放器来播放视频的时候,只有声音输出而无画面输出。一开始以为是自己程序有问题,调试了半天无果。怀疑是真机本身的问题,于是下了几个第三方的播放器来进行视频播放,例如:快播、暴风影音、百度视频和MoboPlayer,都是无疾而终。
1917 0
|
Android开发
Android系统移植与调试之------->如何修改Android启动动画和开机声音
附:本文转载于  http://www.cnblogs.com/jqyp/archive/2012/03/07/2383973.html 1. Linux 系统启动,出现Linux小企鹅画面(reboot)(Android 1.5及以上版本已经取消加载图片); 2. Android平台启动初始化,出现"A N D R I O D"文字字样画面; 3. Android平台图形系统启动,出现含闪动的ANDROID字样的动画图片(start)。
1583 0
|
20天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
94 0