import .ToneGenerator
 import android.provider.Settings//Tone 相关
 const val DTMF_DURATION_MS = 120 // 声音的播放时间,毫秒class ToneHelper() {
 // 监视器对象锁
 private val mToneGeneratorLock = Any()
// 声音产生器
private var mToneGenerator
        : ToneGenerator? = null

// 系统参数“按键操作音”标志位
private var mDTMFToneEnabled = false

fun initToneGenerator(context: Context) {
    runOnBackgroundThread(Runnable {
        //按键声音播放设置及初始化
        try {
            // 获取系统参数“按键操作音”是否开启
            mDTMFToneEnabled = Settings.System.getInt(
                context.contentResolver,
                Settings.System.DTMF_TONE_WHEN_DIALING, 1
            ) == 1
            synchronized(mToneGeneratorLock) {
                if (mDTMFToneEnabled && mToneGenerator == null) {
                    mToneGenerator = ToneGenerator(
                        AudioManager.STREAM_DTMF, 100
                    ) // 设置声音的大小
                    if (context is Activity) {
                        context.volumeControlStream = AudioManager.STREAM_DTMF
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            mDTMFToneEnabled = false
            mToneGenerator = null
        }
    })
}

fun playTone(context: Context, dtmf: Int) {
    if (dtmf < 0) {
        return
    }
    if (!mDTMFToneEnabled) {
        return
    }
    val audioManager =
        context.applicationContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    val ringerMode = audioManager.ringerMode
    if ((ringerMode == AudioManager.RINGER_MODE_SILENT
                || ringerMode == AudioManager.RINGER_MODE_VIBRATE)
    ) {
        // 静音或者震动时不发出声音
        return
    }
    synchronized(mToneGeneratorLock) {
        mToneGenerator?.startTone(dtmf, DTMF_DURATION_MS) //发出声音
    }
}

fun release() {
    try {
        mDTMFToneEnabled = false
        mToneGenerator?.stopTone()
        mToneGenerator?.release()
        mToneGenerator = null
    } catch (e: Exception) {
        e.printStackTrace()
    }
}


### 线程池工具
package com.xg.practise.util
import java.util.concurrent.Executors
 import java.util.concurrent.ScheduledExecutorService
 import java.util.concurrent.TimeUnitval executor: ScheduledExecutorService = Executors.newScheduledThreadPool(10)
fun runOnBackgroundThread(runnable: Runnable?) {
 executor.execute(runnable)
 }fun runOnBackgroundThread(runnable: Runnable?, delay: Long) {
 executor.schedule(runnable, delay, TimeUnit.MILLISECONDS)
 }
### 主页面简单实现
package com.xg.practise
import .ToneGenerator
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import .AppCompatActivity
 import androidx.databinding.DataBindingUtil
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import com.xg.practise.databinding.ActivityToneBinding
 import com.xg.practise.util.ToneHelperclass ToneActivity : AppCompatActivity() {
 private var mToneHelper
 : ToneHelper? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    var dataBinding =
        DataBindingUtil.setContentView<ActivityToneBinding>(this, R.layout.activity_tone);
    setContentView(dataBinding.root)

    mToneHelper = ToneHelper()
    mToneHelper?.initToneGenerator(this@ToneActivity)

    var array = arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#")
    dataBinding.recycler.layoutManager = GridLayoutManager(this@ToneActivity, 3)
    dataBinding.recycler.adapter = object : RecyclerView.Adapter<MyViewHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
            return MyViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(android.R.layout.simple_list_item_1, parent, false)
            )
        }

        override fun getItemCount(): Int {
            return array.size
        }