# PatternLock **Repository Path**: archermind-ti/pattern-lock ## Basic Information - **Project Name**: PatternLock - **Description**: 具有认证流程实现的Material Design Pattern Lock库 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-05-20 - **Last Updated**: 2021-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PatternLock 具有认证流程实现的Material Design Pattern Lock库。 ## 为什么选择PatterLock? - 经过实战测试的框架实现,并进行了必要的修改。 - 支持XML属性进行自定义。 - 支持可变的MxN模式大小。 - 提供样板创建和确认/验证流程的直接实现,与框架“设置”应用程序相同。 - 提供了在示例应用程序源中进行集成的详细示例,例如,实现受保护的UI,主题切换。 ## 功能缺失 由于鸿蒙没有对应的更换主题api接口,所以主题切换功能无法完成。 ## 设计 该库旨在提供用于在Ohos应用中实现模式锁定机制的基本但可扩展的构建块。因此,常见用法将是扩展提供的基本Ability类并根据您的需要覆盖方法。 这个图书馆的目的也是要优雅。取自AOSP的代码经过了稍微的重构,并进行了重命名,以使其更加清晰,`PatternView`现在它利用Ohos资源系统进行自定义。 该库增加了对可变图案大小的支持,因此您可以通过设置`app:pl_rowCount`和来使用除框架的硬编码3x3设置以外的其他图案大小`app:pl_columnCount`。 ## 用法 ### 安装教程 方式一: 1. 下载模块代码添加到自己的工程 2. 关联使用 ``` dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) implementation project(":library") testImplementation 'junit:junit:4.13' …… } ``` 3. gradle sync 方式二: ``` groovy allprojects { repositories { mavenCentral() } } ... dependencies { ... implementation 'com.gitee.archermind-ti:patternlock:1.0.0-beta' ... } ``` ### 效果展示 ### 代码设置 创建一个PatternLockUtil类,帮助跳转,以及一些判断 ```java public class PatternLockUtils { public static final int REQUEST_CODE_CONFIRM_PATTERN = 1214; private PatternLockUtils() {} public static void setPattern(List pattern, Context context) { PreferenceUtils.putString(PreferenceContract.KEY_PATTERN_SHA1, PatternUtils.patternToSha1String(pattern), context); } private static String getPatternSha1(Context context) { return PreferenceUtils.getString(PreferenceContract.KEY_PATTERN_SHA1, PreferenceContract.DEFAULT_PATTERN_SHA1, context); } public static boolean hasPattern(Context context) { return !TextTool.isNullOrEmpty(getPatternSha1(context)); } public static boolean isPatternCorrect(List pattern, Context context) { return TextTool.isEqual(PatternUtils.patternToSha1String(pattern), getPatternSha1(context)); } public static void clearPattern(Context context) { PreferenceUtils.remove(PreferenceContract.KEY_PATTERN_SHA1, context); } public static void setPatternByUser(Ability context) { //// context.startAbility(new Intent(context, SetPatternViewAbilitySlice.class)); // Intent intent = new Intent(); // Operation operation = new Intent.OperationBuilder() // .withDeviceId("") // .withBundleName(context.getBundleName()) // .withAbilityName(SetPatternViewAbility.class) // .build(); // //// 把operation设置到intent中 // intent.setOperation(operation); // context.startAbility(intent,2); jumpAbilityForResult(context, "SetPatternAbility"); } public static void confirmPattern(Ability activity, int requestCode) { // activity.startAbilityForResult(new Intent(activity, ConfirmPatternViewAbility.class), // requestCode); Intent intent=new Intent(); Operation operation = new Intent.OperationBuilder() .withDeviceId("") .withBundleName(activity.getBundleName()) .withAbilityName(ConfirmPatternAbility.class) .build(); // 把operation设置到intent中 intent.setOperation(operation); activity.startAbilityForResult(intent,requestCode); } public static void confirmPattern(Ability ability) { confirmPattern(ability, REQUEST_CODE_CONFIRM_PATTERN); } public static void confirmPatternIfHas(Ability ability) { if (hasPattern(ability.getContext())) { confirmPattern(ability); } } public static boolean checkConfirmPatternResult(ActivityType activity, int requestCode, int resultCode) { if (requestCode == REQUEST_CODE_CONFIRM_PATTERN) { activity.onConfirmPatternResult(resultCode == -1); return true; } else { return false; } } public interface OnConfirmPatternResultListener { void onConfirmPatternResult(boolean successful); } public static void jumpAbility(Context context, String target,String bundleName) { Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withDeviceId("") .withBundleName(bundleName) .withAbilityName(target) .build(); intent.setOperation(operation); context.startAbility(intent, 1); } public static void jumpAbilityForResult(Ability context, String target,String bundleName) { Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withDeviceId("") .withBundleName(bundleName) .withAbilityName(target) .build(); intent.setOperation(operation); context.startAbilityForResult(intent, 1); } } ``` 继承仓库的设定解锁图案对象 ```java public class SetPatternAbilitySlice extends SetPatternAbilitySlice { @Override protected void onSetPattern(List pattern) { PatternLockUtils.setPattern(pattern, this); } } ``` 继承仓库的确认解锁图案对象 public class ConfirmPatternAbilitySlice extends ConfirmPatternAbilitySlice { @Override protected boolean isStealthModeEnabled() { return !PreferenceUtils.getBoolean("KEY_LOCK_SWITCH_CHECKED", true, this); // return !PreferenceUtils.getBoolean(PreferenceContract.KEY_PATTERN_VISIBLE, // PreferenceContract.DEFAULT_PATTERN_VISIBLE, this); } @Override protected boolean isPatternCorrect(List pattern) { return PatternLockUtils.isPatternCorrect(pattern, this); } @Override protected void onForgotPassword() { PatternLockUtils.jumpAbility(getContext(),"ResetPatternAbility"); super.onForgotPassword(); } } 创建ResetPatternAbility对象 public class ResetPatternAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_reset); Button mCancelButton = (Button) findComponentById(ResourceTable.Id_cancel_button); Button mOkButton= (Button) findComponentById(ResourceTable.Id_ok_button); mOkButton.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { String msg = ""; try { msg = getResourceManager().getElement(ResourceTable.String_pattern_reset).getString(); } catch (Exception e) { e.printStackTrace(); } PatternLockUtils.clearPattern(ResetPatternAbilitySlice.this); new ToastDialog(getContext()) .setText(msg) .setAlignment(LayoutAlignment.CENTER) .show(); terminateAbility(); } }); mCancelButton.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { terminateAbility(); } }); } } ### 版本迭代 * v1.0.1 ## License Copyright 2015 Zhang Hai Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.