Android 声音分贝控制锁屏demo实现

标题demo实现总体逻辑:

1. 声明权限
2. 声明,注册 receiver,接收注册设别管理器结果
3. 完成注册APP为设备管理器
4. 录音权限申请
5. 编写类文件,实现业务逻辑

OK,我们开始~~

  1. 声明权限如下
    <!--锁屏权限  需要注册为设备管理器-->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!--录音权限-->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!--设置锁屏密码-->
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
  1. 声明,注册 receiver,接收注册设别管理器结果
    广播接收器类文件如下:

/**
 * com.gerryrun.gerryandroiddemo.testdemo.lockscreen
 * create by GerryRun
 * email:[email protected]
 * 2020-03-14  21:20
 * Describe here: 广播接收器:receiver,接收注册设别管理器结果
 */
class MyAdminReceiver : DeviceAdminReceiver() {
    fun showToast(context: Context, msg: String) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    }

    override fun onEnabled(context: Context, intent: Intent) {

        showToast(
            context,
            "设备管理器激活成功"
        );
    }

    override fun onDisabled(context: Context, intent: Intent) {
        showToast(
            context,
            "设备管理器激活失败"
        );
    }
}

注册广播接收器:


        <receiver
            android:name=".testdemo.lockscreen.MyAdminReceiver"
            android:permission="android.permission.BIND_DEVICE_ADMIN">
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/lock_screen" />

            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>
  1. 完成注册APP为设备管理器

    /**
     * 检测并去激活设备管理器权限
     */
    fun CheckAdminPermission() {
        var mComponentName = ComponentName(this, MyAdminReceiver::class.java)

        var dmp: DevicePolicyManager =
            getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager

        var who = ComponentName(mActivity, MyAdminReceiver::class.java)
        if (dmp.isAdminActive(who)) {
            showToast("已拥有设备管理权限")
            runVoiceRecord()
        } else {
            var intent =
                Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mComponentName)
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "开启后就可以使用锁屏功能了...")
            startActivity(intent)
        }
    }
  1. 录音权限申请

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(
                    arrayOf(Manifest.permission.RECORD_AUDIO),
                    REQUEST_ASK_RECORD_AUDIO
                )
                return
            }
        }

权限回调:

override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        when (requestCode) {
            REQUEST_ASK_RECORD_AUDIO -> {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    showToast("权限申请成功")
                    //开始 获取声音分贝逻辑
                    runVoiceRecord()
                } else {
                    showToast("权限申请失败")
                }
            }
        }
    }

runVoiceRecord()方法:


    private fun runVoiceRecord() {

        var dmp: DevicePolicyManager =
            getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
        mHandler = Handler(Handler.Callback {

            if (it.what == 1) {
                var voice: Double = it.obj as Double
                if (voice > 30) {
                    var who = ComponentName(mActivity, MyAdminReceiver::class.java)
                    if (dmp.isAdminActive(who)) {
                        dmp.lockNow()
                        finish()
                    } else {
                        var intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
                        var mcomponentName = ComponentName(mActivity, MyAdminReceiver::class.java)
                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mcomponentName)
                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "请打开管理员权限")
                        mActivity.startActivity(intent)
                    }
                }
            }

            return@Callback false
        })

        mAudioRecordManager = AudioRecordManager(mHandler, 1)
        mAudioRecordManager?.getNoiseLevel(true)
    }
  1. 编写类文件,实现业务逻辑
    话筒管理类:AudioRecordManager

/**
 * com.gerryrun.gerryandroiddemo.testdemo.lockscreen
 * create by GerryRun
 * email:[email protected]
 * 2020-03-14  21:22
 * Describe here: 话筒管理类
 */
class AudioRecordManager {
    private var thread: Thread? = null

    /**
     * 是否 使用 handler发送音量消息
     */
    var mCanSendMsg: Boolean = true

    val TAG = "AudioRecordManager"

    //通道配置
    var SAMPLE_RATE_IN_SIZE = 44100
    var BUFFER_SIZE = AudioRecord.getMinBufferSize(
        SAMPLE_RATE_IN_SIZE,
        AudioFormat.CHANNEL_IN_DEFAULT,
        AudioFormat.ENCODING_PCM_16BIT
    )

    //话筒类
    var mAudioRecord: AudioRecord? = null

    //是否正在录音
    var isVoiceRun = false
    var mHandler: Handler? = null
    var mWhat = 0

    //锁对象
    lateinit var mLock: Object

    /**
     * 构造方法
     */
    constructor(handler: Handler, what: Int) {
        mHandler = handler
        mWhat = what
        mLock = Object()
    }

    //    获取声音分贝
    fun getNoiseLevel(canSendMsg: Boolean) {
        if (isVoiceRun) return
        mCanSendMsg = canSendMsg

        isVoiceRun = true
        thread = object : Thread() {
            override fun run() {
                //死循环
                while (isVoiceRun) {
                    if (mCanSendMsg) {
                        /**
                         * 初始化 话筒类
                         */
                        if (null == mAudioRecord)
                            mAudioRecord = AudioRecord(
                                MediaRecorder.AudioSource.MIC,
                                SAMPLE_RATE_IN_SIZE,
                                AudioFormat.CHANNEL_IN_DEFAULT,
                                AudioFormat.ENCODING_PCM_16BIT, BUFFER_SIZE
                            )
                        if (mAudioRecord == null) throw NullPointerException("话筒类初始化失败")

                        var buffer = ShortArray(BUFFER_SIZE)
                        /**
                         * 不少机型 调用此方法会报错,所以try catch捕获一下
                         */
                        try {
                            mAudioRecord?.startRecording()
                        } catch (e: IllegalStateException) {
                            e.printStackTrace()
                        }
                        var r = mAudioRecord?.read(buffer, 0, BUFFER_SIZE)
                        var v = 0
                        for (i in 0 until buffer.size) {
                            v += buffer[i] * buffer[i]
                        }
                        /**
                         * 平方和 除以数据总长度,得到音量的大小
                         */
                        if (r == null) {
                            return
                        }
                        var mean: Double = (v / (r!!.toDouble()))
                        var volume = 10 * log10(mean)

                        if (!this.isInterrupted)
                            synchronized(mLock) {
                                mLock.wait(500)
                                doSendMsg(volume)
                            }
                    }
                }
            }
        }
        thread?.start()
    }

    /**
     * 向activity发送声音分贝信息
     */
    fun doSendMsg(volume: Double) {
        var msg: Message = Message.obtain()
        msg.what = mWhat
        msg.obj = volume
        Log.e(TAG, "volume==$volume")
        mHandler?.sendMessage(msg)
    }

    /**
     * 停止录音
     */
    fun stopRecord(canSendMsg: Boolean) {
        mCanSendMsg = canSendMsg

        Log.e(TAG, "null != thread==" + (null != thread))

        if (null != thread) {
            /**
             * 停止线程方法:
             * Thread.interrupt()方法
             *
             * Thread.stop()方法因为不安全,已被弃用,直接调用会boom,
             *
             */
            thread!!.interrupt()
        }
        thread = null

        /**
         * 释放 音频采集对象
         */
        if (null != mAudioRecord) {
            mAudioRecord?.release()
            mAudioRecord = null
        }
    }
}
  1. 实现业务逻辑
    private fun runVoiceRecord() {

        /**
         * 获取 DevicePolicyManager 对象
         */
        var dmp: DevicePolicyManager =
            getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
        mHandler = Handler(Handler.Callback {

            if (it.what == 1) {
                var voice: Double = it.obj as Double
                if (voice > 30) {
                    //判断当前app是否为设备管理器
                    var who = ComponentName(mActivity, MyAdminReceiver::class.java)
                    if (dmp.isAdminActive(who)) {
                        //锁屏
                        dmp.lockNow()
                        finish()
                    } else {
                        //跳转设备管理器注册页面
                        var intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
                        var mcomponentName = ComponentName(mActivity, MyAdminReceiver::class.java)
                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mcomponentName)
                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "请打开管理员权限")
                        mActivity.startActivity(intent)
                    }
                }
            }

            return@Callback false
        })
        //初始化  AudioRecordManager 对象
        mAudioRecordManager = AudioRecordManager(mHandler, 1)
        //开始获取声音分贝
        mAudioRecordManager?.getNoiseLevel(true)
    }

如此,所有逻辑已完成,下面奉上整个activity文件:

class LockScreenActivity : BaseActivity<ActivityLockScreenBinding>() {
    private var mAudioRecordManager: AudioRecordManager? = null
    private lateinit var mHandler: Handler

    var REQUEST_ASK_RECORD_AUDIO = 1001

    override fun getContentViewId(): Int {
        return R.layout.activity_lock_screen
    }

    override fun initTheView() {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(
                    arrayOf(Manifest.permission.RECORD_AUDIO),
                    REQUEST_ASK_RECORD_AUDIO
                )
                return
            }
        }

        CheckAdminPermission()
    }

    private fun runVoiceRecord() {

        /**
         * 获取 DevicePolicyManager 对象
         */
        var dmp: DevicePolicyManager =
            getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
        mHandler = Handler(Handler.Callback {

            if (it.what == 1) {
                var voice: Double = it.obj as Double
                if (voice > 30) {
                    //判断当前app是否为设备管理器
                    var who = ComponentName(mActivity, MyAdminReceiver::class.java)
                    if (dmp.isAdminActive(who)) {
                        //锁屏
                        dmp.lockNow()
                        finish()
                    } else {
                        //跳转设备管理器注册页面
                        var intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
                        var mcomponentName = ComponentName(mActivity, MyAdminReceiver::class.java)
                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mcomponentName)
                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "请打开管理员权限")
                        mActivity.startActivity(intent)
                    }
                }
            }

            return@Callback false
        })
        //初始化  AudioRecordManager 对象
        mAudioRecordManager = AudioRecordManager(mHandler, 1)
        //开始获取声音分贝
        mAudioRecordManager?.getNoiseLevel(true)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        when (requestCode) {
            REQUEST_ASK_RECORD_AUDIO -> {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    showToast("权限申请成功")
                    //开始 获取声音分贝逻辑
                    runVoiceRecord()
                } else {
                    showToast("权限申请失败")
                }
            }
        }
    }

    /**
     * 检测并去激活设备管理器权限
     */
    fun CheckAdminPermission() {
        var mComponentName = ComponentName(this, MyAdminReceiver::class.java)

        var dmp: DevicePolicyManager =
            getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager

        var who = ComponentName(mActivity, MyAdminReceiver::class.java)
        if (dmp.isAdminActive(who)) {
            showToast("已拥有设备管理权限")
            runVoiceRecord()
        } else {
            var intent =
                Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mComponentName)
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "开启后就可以使用锁屏功能了...")
            startActivity(intent)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mAudioRecordManager!!.stopRecord(false)
        mAudioRecordManager = null
    }
}

至此,demo实现完毕,务必轻喷哦~~~

你可能感兴趣的:(Android)