实现一键锁屏

作者: h2coder | 来源:发表于2019-08-13 14:54 被阅读1次

    实现一键锁屏

    一键锁屏的文章网上一抓一大把,不过之前找出来自己写了一遍,那么就记录一下吧~

    Api设计

    1. 封装一个代理类,提供lock锁屏方法进行锁屏。
    2. 设置锁屏回调:
      • 1)取消授权
      • 2)锁屏成功
      • 3)锁屏失败
    3. 代理onActivityResult,将结果代理给代理类处理

    实现步骤

    一键锁屏实际就是启动一个透明的Activity,获取设备权限,调用锁屏API后关闭页面,这样就完成了。

    配置

    1. 新建一个设备管理的广播接收器,继承DeviceAdminReceiver
    public class OneScreenLockAdminReceiver extends DeviceAdminReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            super.onReceive(context, intent);
        }
    }
    
    • 在res文件夹下,新建一个xml文件夹,新建一个xml文件fs_one_screen_lock,并在resource属性配置管理的区域
    1. AndroidManifest.xml清单文件,添加设备管理广播
    • 配置权限
    android:permission="android.permission.BIND_DEVICE_ADMIN"
    
    • meta-data属性配置
    <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/fs_one_screen_lock" />
    
    • intent-filter配置android.app.action.DEVICE_ADMIN_ENABLED
    <?xml version="1.0" encoding="utf-8"?>
    <device-admin>
        xmlns:android="http://schemas.android.com/apk/res/android"
        <uses-policies>
            <!-- 强行锁定  在里仅这个是需要的 -->
            <force-lock/>
    
            <!-- 清除所有数据(恢复出厂设置) -->
            <!--<wipe-data />-->
            <!-- 重置密码 -->
            <!--<reset-password />-->
            <!-- 限制密码选择 -->
            <!--<limit-password />-->
            <!-- 监控登录尝试 -->
            <!--<watch-login />-->
        </uses-policies>
    </device-admin>
    
    • 完整清单配置
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.zh.lock">
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/icon"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
    
            //...省略其他配置
    
            <!-- 一键锁屏,设备管理 -->
            <receiver
                android:name=".OneScreenLockAdminReceiver"
                android:permission="android.permission.BIND_DEVICE_ADMIN">
                <meta-data
                    android:name="android.app.device_admin"
                    android:resource="@xml/fs_one_screen_lock" />
                <intent-filter>
                    <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
                </intent-filter>
            </receiver>
        </application>
    </manifest>
    

    Java代码

    1. 回调接口
    //锁屏回调
    public interface OnLockListener {
        /**
         * 锁屏成功回调
         */
        void onLockSuccess();
    
        /**
         * 锁屏失败回调
         *
         * @param error 异常对象
         */
        void onLockFail(Throwable error);
    
        /**
         * 权限取消
         */
        void onLockPermissionCancel();
    }
    
    //回调空实现
    public static class SimpleOnLockListener implements OnLockListener {
    
        @Override
        public void onLockSuccess() {
        }
    
        @Override
        public void onLockFail(Throwable error) {
        }
    
        @Override
        public void onLockPermissionCancel() {
        }
    }
    
    //设置回调对象
    public void setOnLockListener(OnLockListener listener) {
        this.mListener = listener;
    }
    
    1. 判断是否获取了设备管理权限,有则调用锁屏,无则先申请设备管理权限再调用锁屏。
    public class LockAgent {
        private static final int LOCK_REQUEST_CODE = 9999;
        private Activity mActivity;
    
        private DevicePolicyManager mPolicyManager;
        private ComponentName mComponentName;
        private OnLockListener mListener;
    
        public LockAgent(Activity activity) {
            this.mActivity = activity;
        }
    
        private Activity getActivity() {
            return this.mActivity;
        }
    
        //锁屏
        public void lock() {
            Activity activity = getActivity();
            mPolicyManager = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
            mComponentName = new ComponentName(activity, OneScreenLockAdminReceiver.class);
            boolean isActive = mPolicyManager.isAdminActive(mComponentName);
            //没有授权
            if (!isActive) {
                activeManage();
            } else {
                //授权了,直接锁屏
                mPolicyManager.lockNow();
                if (mListener != null) {
                    mListener.onLockSuccess();
                }
            }
        }
    }
    
    1. 申请授权
    /**
     * 申请授权
     */
    private void activeManage() {
        //启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器
        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        //权限列表
        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mComponentName);
        //描述(additional explanation)
        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "激活后才可以使用锁屏功能");
        getActivity().startActivityForResult(intent, LOCK_REQUEST_CODE);
    }
    
    1. 处理授权结果
    /**
     * 代理Activity的onActivityResult
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == LOCK_REQUEST_CODE && resultCode == Activity.RESULT_CANCELED) {
            //直接返回界面
            if (mListener != null) {
                mListener.onLockPermissionCancel();
            }
        } else if (requestCode == LOCK_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            try {
                if (!mPolicyManager.isAdminActive(mComponentName)) {
                    //没有授予权限
                    if (mListener != null) {
                        mListener.onLockPermissionCancel();
                    }
                } else {
                    //授予了权限,锁屏
                    mPolicyManager.lockNow();
                    if (mListener != null) {
                        mListener.onLockSuccess();
                    }
                }
            } catch (Exception error) {
                error.printStackTrace();
                if (mListener != null) {
                    mListener.onLockFail(error);
                }
            }
        }
    }
    
    1. 使用
    public class MainActivity extends Activity {
        private static final String TAG = MainActivity.class.getSimpleName();
        private LockAgent mAgent;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //构建代理,配置回调
            mAgent = new LockAgent(this);
            mAgent.setOnLockListener(new LockAgent.SimpleOnLockListener() {
                @Override
                public void onLockSuccess() {
                    super.onLockSuccess();
                    //锁屏成功
                    finish();
                }
    
                @Override
                public void onLockFail(Throwable error) {
                    super.onLockFail(error);
                    //锁屏异常,一般不会,主要是避免第三方厂商各种骚操作
                    Log.d(TAG, "Lock Fail: " + error.getMessage());
                    finish();
                }
    
                @Override
                public void onLockPermissionCancel() {
                    super.onLockPermissionCancel();
                    //用户取消授权
                    Log.d(TAG, "Lock Permission Cancel");
                    toast(getString(R.string.request_lock_permission_fail));
                    finish();
                }
            });
            //锁屏
            mAgent.lock();
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            //代理结果
            if (mAgent != null) {
                mAgent.onActivityResult(requestCode, resultCode, data);
            }
        }
    
        private void toast(String msg) {
            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
        }
    }
    

    总结

    一键锁屏经过系统的封装后,使用还是挺简单的,当然第三方厂商会内置一个,避免申请权限需要用户授权,例如vivo会内置一个锁屏广播接收器,发送一个指定action的广播即可锁屏。

    相关文章

      网友评论

        本文标题:实现一键锁屏

        本文链接:https://www.haomeiwen.com/subject/tqxbjctx.html