Android之旅

实现一键锁屏

2019-08-13  本文已影响1人  h2coder

实现一键锁屏

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

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);
    }
}
  1. AndroidManifest.xml清单文件,添加设备管理广播
android:permission="android.permission.BIND_DEVICE_ADMIN"
<meta-data
    android:name="android.app.device_admin"
    android:resource="@xml/fs_one_screen_lock" />
<?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的广播即可锁屏。

上一篇 下一篇

猜你喜欢

热点阅读