android广播实现PIN码设置

摘要:本文通过广播的方式调用系统设置PIN码的流程实现类似锁机的功能,可供开发人员在联网状态下后台推送消息进行锁机/解锁。有需要的同学可以参考PIN码的流程改为密码等其他形式。

1 定义一个广播接收器

广播action:android.intent.action.LOCKDEVICE

boolean extra: lock (true:锁机/false:解锁)

String extra: password (6位数字密码,后续代码会进行合法性检测)

java 复制代码
        <receiver android:name=".LockDeviceReceiver"
                  android:exported="true">
            <intent-filter>    
                <action android:name="android.intent.action.LOCKDEVICE"/>
            </intent-filter>
        </receiver>

2 功能实现

代码部分注释为 android 9之前的实现方式。

java 复制代码
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;

import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.PasswordValidationError.RECENTLY_USED;

import android.app.admin.PasswordMetrics;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.util.Log;

import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.PasswordValidationError;

import java.util.Collections;
import java.util.List;

/**
 * Boot completed receiver. used to reset the app install state every time the
 * device boots.
 *
 */
public class LockDeviceReceiver extends BroadcastReceiver {
    private static String TAG ="LockDeviceReceiver";

    private byte[] mPasswordHistoryHashFactor;
    private LockPatternUtils mLockPatternUtils;
    private LockscreenCredential mChosenPassword;
    private LockscreenCredential mCurrentCredential;

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if ("android.intent.action.LOCKDEVICE".equals(action)) {
            boolean isLock = intent.getBooleanExtra("lock", false);
            String password = intent.getStringExtra("password");
            mLockPatternUtils = new LockPatternUtils(context);
            if (isLock) {
                lockDevice(context, password);
            } else {
                unlockDevice(context, password);
            }
            return;
        }
    }

    private void lockDevice(Context context, String password) {
        mChosenPassword = LockscreenCredential.createPin(password);
        //int mRequestedQuality = mLockPatternUtils.computePasswordQuality(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
        if (password.length() == 6 && validatePassword(mChosenPassword)) {
            //mLockPatternUtils.setCredentialRequiredToDecrypt(false);
            //mLockPatternUtils.saveLockPassword(password, null, mRequestedQuality, UserHandle.myUserId());
            final boolean success = mLockPatternUtils.setLockCredential(
                    mChosenPassword, LockscreenCredential.createNone(), UserHandle.myUserId());
            Log.d(TAG, "lockDevice " + (success ? "success" : "unsuccess"));
        } else {
            Log.d(TAG, "invalid password!");
        }
    }

    private void unlockDevice(Context context, String password) {
        LockscreenCredential credential = LockscreenCredential.createPin(password);
        LockPatternChecker.checkCredential(
            mLockPatternUtils,
            credential,
            UserHandle.myUserId(),
            new LockPatternChecker.OnCheckCallback() {
                @Override
                public void onChecked(boolean matched, int timeoutMs) {
                    if (matched) {
                        //mLockPatternUtils.setSeparateProfileChallengeEnabled(UserHandle.myUserId(), true, credential);
                        //mLockPatternUtils.clearLock(password, UserHandle.myUserId());
                        //mLockPatternUtils.setLockScreenDisabled(true, UserHandle.myUserId());
                        final boolean success = mLockPatternUtils.setLockCredential(
                                LockscreenCredential.createNone(), LockscreenCredential.createPinOrNone(password), UserHandle.myUserId());
                        mLockPatternUtils.setLockScreenDisabled(true, UserHandle.myUserId());
                        Log.d(TAG, "unlockDevice " + (success ? "success" : "unsuccess"));
                    } else {
                        Log.d(TAG, "Password do not match");
                    }
                }
            });
    }

    boolean validatePassword(LockscreenCredential credential) {
        final byte[] password = credential.getCredential();
        List<PasswordValidationError> mValidationErrors = PasswordMetrics.validatePassword(
                new PasswordMetrics(CREDENTIAL_TYPE_NONE), PASSWORD_COMPLEXITY_NONE, true, password);
        if (mValidationErrors.isEmpty() &&  mLockPatternUtils.checkPasswordHistory(
                    password, getPasswordHistoryHashFactor(), UserHandle.myUserId())) {
            mValidationErrors =
                    Collections.singletonList(new PasswordValidationError(RECENTLY_USED));
        }
        return mValidationErrors.isEmpty();
    }

    private byte[] getPasswordHistoryHashFactor() {
        if (mPasswordHistoryHashFactor == null) {
            mPasswordHistoryHashFactor = mLockPatternUtils.getPasswordHistoryHashFactor(
                    mCurrentCredential != null ? mCurrentCredential
                            : LockscreenCredential.createNone(), UserHandle.myUserId());
        }
        return mPasswordHistoryHashFactor;
    }
}

3 其他注意

广播需要在系统管理中添加,避免被拦截。

相关推荐
感谢地心引力6 小时前
安卓、苹果手机无线投屏到Windows
android·windows·ios·智能手机·安卓·苹果·投屏
惊讶的猫6 小时前
探究StringBuilder和StringBuffer的线程安全问题
java·开发语言
jmxwzy6 小时前
Spring全家桶
java·spring·rpc
Halo_tjn6 小时前
基于封装的专项 知识点
java·前端·python·算法
Fleshy数模7 小时前
从数据获取到突破限制:Python爬虫进阶实战全攻略
java·开发语言
像少年啦飞驰点、7 小时前
零基础入门 Spring Boot:从“Hello World”到可上线的 Web 应用全闭环指南
java·spring boot·web开发·编程入门·后端开发
苍煜7 小时前
万字详解Maven打包策略:从基础插件到多模块实战
java·maven
有来技术7 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
GJGCY7 小时前
技术解析|中国智能体4类路径深度拆解,这类底座架构优势凸显
人工智能·经验分享·ai·agent·智能体·数字员工
东东5167 小时前
xxx医患档案管理系统
java·spring boot·vue·毕业设计·智慧城市