Android為撥號盤dialer定製聲音DTMF Tones

l_serein發表於2012-05-17

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);   //發出聲音
        }
    }
}

相關文章