QQLOCKppi是什么意思么

键盘上的指示灯Scroll Lock是什么意思?_百度知道
键盘上的指示灯Scroll Lock是什么意思?
我知道Num Lock是切换数字,CapsLock是切换大小写供鼎垛刮艹钙讹水番惊,那Scroll Lock是什么意思?
提问者采纳
滚动锁定键! 附网络转载: Scroll Lock键的作用就是在阅读较长的文档时进行翻滚,就像现在有好多网页为了方便访问者而通过双击鼠标进行滚动阅读一样。但到了windows年代,Scroll Lock键基本是退出了历史的舞台,显得英雄无用武之地。不过,既然能在键盘这一亩三分地之上占有一席之地,我们总该把它派点儿用场吧!到天空或者华军下载名为“xCAT-Keyboard Network Leds”(键盘灯显示网络流量)的免费绿色小程序(你可以到百度上输入搜索到),双击就可运行。 其他用途 在魔兽中有供鼎垛刮艹钙讹水番惊用,冒险岛OL的截图按钮,在QQ截屏时有用,烧录有用! 此外.这个按键还是部分键盘的特殊功能开关. 比如小袋鼠DS-9868发光键盘.很多网友买了该键盘后反应这款键盘不能如网上所显示的那样按键发光. 此时只要按一下Scroll Lock键.键盘的灯光就会亮起来了.再按一下就是关闭.
其他类似问题
为您推荐:
lock的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁qq密码栏写大写锁定已打开是什么意思_百度知道
qq密码栏写大写锁定已打开是什么意思
提问者采纳
按住caps lock键就能恢复的小写字母。这个键一般在键盘的左中间的位置
其他类似问题
为您推荐:
大写锁定的相关知识
其他1条回答
就是你的输入法打拼音的时候是大写字母!
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁1666人阅读
访问博主的淘宝店,支持博主 :
本文源码(utf-8编码):
ps:请不要再问我,为什么导入之后会乱码了。
其实,代码基本上都是从原生系统中提取的:LockPatternView、加密工具类,以及解锁逻辑等,我只是稍作修改,大家都知道,原生系统界面比较丑陋,因此,我特意把QQ的apk解压了,从中拿了几张图案解锁的图片,一个简单的例子就这样诞生了。
好了,废话不多说,我们来看看效果(最后两张是最新4.4系统,炫一下,呵呵):
1.最关健的就是那个自定义九宫格View,代码来自framework下:LockPatternView,原生系统用的图片资源比较多,好像有7、8张吧,而且绘制的比较复杂,我找寻半天,眼睛都找瞎了,发现解压的QQ里面就3张图片,一个圈圈,两个点,没办法,只能修改代码了,在修改的过程中,才发现,其实可以把原生的LockPatternView给简化,绘制更少的图片,达到更好的效果。总共优化有:①去掉了连线的箭头,②原生的连线只有白色一种,改成根据不同状态显示黄色和红色两张色,③.原生view是先画点再画线,使得线覆盖在点的上面,影响美观,改成先画连线再画点。
关健部分代码onDraw函数:
@Override&&protected&void&onDraw(Canvas&canvas)&{&&&&&&final&ArrayList&Cell&&pattern&=&mP&&&&&&final&int&count&=&pattern.size();&&&&&&final&boolean[][]&drawLookup&=&mPatternDrawL&&&&&&&&if&(mPatternDisplayMode&==&DisplayMode.Animate)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&final&int&oneCycle&=&(count&+&1)&*&MILLIS_PER_CIRCLE_ANIMATING;&&&&&&&&&&final&int&spotInCycle&=&(int)&(SystemClock.elapsedRealtime()&-&mAnimatingPeriodStart)&&&&&&&&&&&&&&&&&&%&oneC&&&&&&&&&&final&int&numCircles&=&spotInCycle&/&MILLIS_PER_CIRCLE_ANIMATING;&&&&&&&&&&&&clearPatternDrawLookup();&&&&&&&&&&for&(int&i&=&0;&i&&&numC&i++)&{&&&&&&&&&&&&&&final&Cell&cell&=&pattern.get(i);&&&&&&&&&&&&&&drawLookup[cell.getRow()][cell.getColumn()]&=&true;&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&final&boolean&needToUpdateInProgressPoint&=&numCircles&&&0&&&&&&&&&&&&&&&&&&&&&numCircles&&&&&&&&&&&&&&&if&(needToUpdateInProgressPoint)&{&&&&&&&&&&&&&&final&float&percentageOfNextCircle&=&((float)&(spotInCycle&%&MILLIS_PER_CIRCLE_ANIMATING))&&&&&&&&&&&&&&&&&&&&&&/&MILLIS_PER_CIRCLE_ANIMATING;&&&&&&&&&&&&&&&&final&Cell&currentCell&=&pattern.get(numCircles&-&1);&&&&&&&&&&&&&&final&float&centerX&=&getCenterXForColumn(currentCell.column);&&&&&&&&&&&&&&final&float&centerY&=&getCenterYForRow(currentCell.row);&&&&&&&&&&&&&&&&final&Cell&nextCell&=&pattern.get(numCircles);&&&&&&&&&&&&&&final&float&dx&=&percentageOfNextCircle&&&&&&&&&&&&&&&&&&&&&&*&(getCenterXForColumn(nextCell.column)&-&centerX);&&&&&&&&&&&&&&final&float&dy&=&percentageOfNextCircle&&&&&&&&&&&&&&&&&&&&&&*&(getCenterYForRow(nextCell.row)&-&centerY);&&&&&&&&&&&&&&mInProgressX&=&centerX&+&&&&&&&&&&&&&&&mInProgressY&=&centerY&+&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&invalidate();&&&&&&}&&&&&&&&final&float&squareWidth&=&mSquareW&&&&&&final&float&squareHeight&=&mSquareH&&&&&&&&float&radius&=&(squareWidth&*&mDiameterFactor&*&0.5f);&&&&&&mPathPaint.setStrokeWidth(radius);&&&&&&&&final&Path&currentPath&=&mCurrentP&&&&&&currentPath.rewind();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&final&boolean&drawPath&=&(!mInStealthMode&||&mPatternDisplayMode&==&DisplayMode.Wrong);&&&&&&&&&&&&&&&&&&&&&&&&&&boolean&oldFlag&=&(mPaint.getFlags()&&&Paint.FILTER_BITMAP_FLAG)&!=&0;&&&&&&mPaint.setFilterBitmap(true);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(drawPath)&{&&&&&&&&&&boolean&anyCircles&=&false;&&&&&&&&&&for&(int&i&=&0;&i&&&&i++)&{&&&&&&&&&&&&&&Cell&cell&=&pattern.get(i);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(!drawLookup[cell.row][cell.column])&{&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&}&&&&&&&&&&&&&&anyCircles&=&true;&&&&&&&&&&&&&&&&float&centerX&=&getCenterXForColumn(cell.column);&&&&&&&&&&&&&&float&centerY&=&getCenterYForRow(cell.row);&&&&&&&&&&&&&&if&(i&==&0)&{&&&&&&&&&&&&&&&&&&currentPath.moveTo(centerX,&centerY);&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&currentPath.lineTo(centerX,&centerY);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&&&
&&&&&&&&&&if&((mPatternInProgress&||&mPatternDisplayMode&==&DisplayMode.Animate)&&&&&&&&&&&&&&&&&&&&&anyCircles)&{&&&&&&&&&&&&&&currentPath.lineTo(mInProgressX,&mInProgressY);&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&if&(mPatternDisplayMode&==&DisplayMode.Wrong)&&&&&&&&&&&&&&mPathPaint.setColor(Color.RED);&&&&&&&&&&else&&&&&&&&&&&&&&mPathPaint.setColor(Color.YELLOW);&&&&&&&&&&canvas.drawPath(currentPath,&mPathPaint);&&&&&&}&&&&&&&&&&&&&&final&int&paddingTop&=&getPaddingTop();&&&&&&final&int&paddingLeft&=&getPaddingLeft();&&&&&&&&for&(int&i&=&0;&i&&&3;&i++)&{&&&&&&&&&&float&topY&=&paddingTop&+&i&*&squareH&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&for&(int&j&=&0;&j&&&3;&j++)&{&&&&&&&&&&&&&&float&leftX&=&paddingLeft&+&j&*&squareW&&&&&&&&&&&&&&drawCircle(canvas,&(int)&leftX,&(int)&topY,&drawLookup[i][j]);&&&&&&&&&&}&&&&&&}&&&&&&&&mPaint.setFilterBitmap(oldFlag);&&&}&&
protected void onDraw(Canvas canvas) {
final ArrayList&Cell& pattern = mP
final int count = pattern.size();
final boolean[][] drawLookup = mPatternDrawL
if (mPatternDisplayMode == DisplayMode.Animate) {
// figure out which circles to draw
// + 1 so we pause on complete pattern
final int oneCycle = (count + 1) * MILLIS_PER_CIRCLE_ANIMATING;
final int spotInCycle = (int) (SystemClock.elapsedRealtime() - mAnimatingPeriodStart)
final int numCircles = spotInCycle / MILLIS_PER_CIRCLE_ANIMATING;
clearPatternDrawLookup();
for (int i = 0; i & numC i++) {
final Cell cell = pattern.get(i);
drawLookup[cell.getRow()][cell.getColumn()] =
// figure out in progress portion of ghosting line
final boolean needToUpdateInProgressPoint = numCircles & 0
&& numCircles &
if (needToUpdateInProgressPoint) {
final float percentageOfNextCircle = ((float) (spotInCycle % MILLIS_PER_CIRCLE_ANIMATING))
/ MILLIS_PER_CIRCLE_ANIMATING;
final Cell currentCell = pattern.get(numCircles - 1);
final float centerX = getCenterXForColumn(currentCell.column);
final float centerY = getCenterYForRow(currentCell.row);
final Cell nextCell = pattern.get(numCircles);
final float dx = percentageOfNextCircle
* (getCenterXForColumn(nextCell.column) - centerX);
final float dy = percentageOfNextCircle
* (getCenterYForRow(nextCell.row) - centerY);
mInProgressX = centerX +
mInProgressY = centerY +
// TODO: Infinite loop here...
invalidate();
final float squareWidth = mSquareW
final float squareHeight = mSquareH
float radius = (squareWidth * mDiameterFactor * 0.5f);
mPathPaint.setStrokeWidth(radius);
final Path currentPath = mCurrentP
currentPath.rewind();
// TODO: the path should be created and cached every time we hit-detect
// only the last segment of the path should be computed here
// draw the path of the pattern (unless the user is in progress, and
// we are in stealth mode)
final boolean drawPath = (!mInStealthMode || mPatternDisplayMode == DisplayMode.Wrong);
// draw the arrows associated with the path (unless the user is in
// progress, and
// we are in stealth mode)
boolean oldFlag = (mPaint.getFlags() & Paint.FILTER_BITMAP_FLAG) != 0;
mPaint.setFilterBitmap(true); // draw with higher quality since we
// render with transforms
// draw the lines
if (drawPath) {
boolean anyCircles =
for (int i = 0; i & i++) {
Cell cell = pattern.get(i);
// only draw the part of the pattern stored in
// the lookup table (this is only different in the case
// of animation).
if (!drawLookup[cell.row][cell.column]) {
anyCircles =
float centerX = getCenterXForColumn(cell.column);
float centerY = getCenterYForRow(cell.row);
if (i == 0) {
currentPath.moveTo(centerX, centerY);
currentPath.lineTo(centerX, centerY);
// add last in progress section
if ((mPatternInProgress || mPatternDisplayMode == DisplayMode.Animate)
&& anyCircles) {
currentPath.lineTo(mInProgressX, mInProgressY);
// chang the line color in different DisplayMode
if (mPatternDisplayMode == DisplayMode.Wrong)
mPathPaint.setColor(Color.RED);
mPathPaint.setColor(Color.YELLOW);
canvas.drawPath(currentPath, mPathPaint);
// draw the circles
final int paddingTop = getPaddingTop();
final int paddingLeft = getPaddingLeft();
for (int i = 0; i & 3; i++) {
float topY = paddingTop + i * squareH
// float centerY = mPaddingTop + i * mSquareHeight + (mSquareHeight
for (int j = 0; j & 3; j++) {
float leftX = paddingLeft + j * squareW
drawCircle(canvas, (int) leftX, (int) topY, drawLookup[i][j]);
mPaint.setFilterBitmap(oldFlag); // restore default flag
2.第二个值得学习的地方是(代码来自设置应用中):在创建解锁图案时的枚举使用,原生代码中使用了很多枚举,将绘制图案时的状态、底部两个按钮状态、顶部一个TextView显示的提示文字都紧密的联系起来。因此,只用监听LockPatternView动态变化,对应改变底部Button和顶部TextView的状态即可实现联动,简单的方法可以实现很多代码才能实现的逻辑,个人很喜欢。
①全局的状态:
&&&&&&&&protected&enum&Stage&{&&&&&&&&&&&&&&&&&&&&Introduction(R.string.lockpattern_recording_intro_header,&&&&&&&&&&&&&&&&&&LeftButtonMode.Cancel,&RightButtonMode.ContinueDisabled,&&&&&&&&&&&&&&&&&&ID_EMPTY_MESSAGE,&true),&&&&&&&&&&&&&&&&&&&&HelpScreen(R.string.lockpattern_settings_help_how_to_record,&&&&&&&&&&&&&&&&&&LeftButtonMode.Gone,&RightButtonMode.Ok,&ID_EMPTY_MESSAGE,&&&&&&&&&&&&&&&&&&false),&&&&&&&&&&&&&&&&&&&&ChoiceTooShort(R.string.lockpattern_recording_incorrect_too_short,&&&&&&&&&&&&&&&&&&LeftButtonMode.Retry,&RightButtonMode.ContinueDisabled,&&&&&&&&&&&&&&&&&&ID_EMPTY_MESSAGE,&true),&&&&&&&&&&&&&&&&&&&&FirstChoiceValid(R.string.lockpattern_pattern_entered_header,&&&&&&&&&&&&&&&&&&LeftButtonMode.Retry,&RightButtonMode.Continue,&&&&&&&&&&&&&&&&&&ID_EMPTY_MESSAGE,&false),&&&&&&&&&&&&&&&&&&&&NeedToConfirm(R.string.lockpattern_need_to_confirm,&&&&&&&&&&&&&&&&&&LeftButtonMode.Cancel,&RightButtonMode.ConfirmDisabled,&&&&&&&&&&&&&&&&&&ID_EMPTY_MESSAGE,&true),&&&&&&&&&&&&&&&&&&&&ConfirmWrong(R.string.lockpattern_need_to_unlock_wrong,&&&&&&&&&&&&&&&&&&LeftButtonMode.Cancel,&RightButtonMode.ConfirmDisabled,&&&&&&&&&&&&&&&&&&ID_EMPTY_MESSAGE,&true),&&&&&&&&&&&&&&&&&&&&ChoiceConfirmed(R.string.lockpattern_pattern_confirmed_header,&&&&&&&&&&&&&&&&&&LeftButtonMode.Cancel,&RightButtonMode.Confirm,&&&&&&&&&&&&&&&&&&ID_EMPTY_MESSAGE,&false);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Stage(int&headerMessage,&LeftButtonMode&leftMode,&&&&&&&&&&&&&&&&&&RightButtonMode&rightMode,&int&footerMessage,&&&&&&&&&&&&&&&&&&boolean&patternEnabled)&{&&&&&&&&&&&&&&this.headerMessage&=&headerM&&&&&&&&&&&&&&this.leftMode&=&leftM&&&&&&&&&&&&&&this.rightMode&=&rightM&&&&&&&&&&&&&&this.footerMessage&=&footerM&&&&&&&&&&&&&&this.patternEnabled&=&patternE&&&&&&&&&&}&&&&&&&&&&&&final&int&headerM&&&&&&&&&&final&LeftButtonMode&leftM&&&&&&&&&&final&RightButtonMode&rightM&&&&&&&&&&final&int&footerM&&&&&&&&&&final&boolean&patternE&&&&&&}&&
* Keep track internally of where the user is in choosing a pattern.
protected enum Stage {
// 初始状态
Introduction(R.string.lockpattern_recording_intro_header,
LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
ID_EMPTY_MESSAGE, true),
// 帮助状态
HelpScreen(R.string.lockpattern_settings_help_how_to_record,
LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE,
// 绘制过短
ChoiceTooShort(R.string.lockpattern_recording_incorrect_too_short,
LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
ID_EMPTY_MESSAGE, true),
// 第一次绘制图案
FirstChoiceValid(R.string.lockpattern_pattern_entered_header,
LeftButtonMode.Retry, RightButtonMode.Continue,
ID_EMPTY_MESSAGE, false),
// 需要再次绘制确认
NeedToConfirm(R.string.lockpattern_need_to_confirm,
LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
ID_EMPTY_MESSAGE, true),
// 确认出错
ConfirmWrong(R.string.lockpattern_need_to_unlock_wrong,
LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
ID_EMPTY_MESSAGE, true),
// 选择确认
ChoiceConfirmed(R.string.lockpattern_pattern_confirmed_header,
LeftButtonMode.Cancel, RightButtonMode.Confirm,
ID_EMPTY_MESSAGE, false);
* @param headerMessage
The message displayed at the top.
* @param leftMode
The mode of the left button.
* @param rightMode
The mode of the right button.
* @param footerMessage
The footer message.
* @param patternEnabled
Whether the pattern widget is enabled.
Stage(int headerMessage, LeftButtonMode leftMode,
RightButtonMode rightMode, int footerMessage,
boolean patternEnabled) {
this.headerMessage = headerM
this.leftMode = leftM
this.rightMode = rightM
this.footerMessage = footerM
this.patternEnabled = patternE
final int headerM
final LeftButtonMode leftM
final RightButtonMode rightM
final int footerM
final boolean patternE
②.底部两个按钮的状态枚举:
&&&&&&&&enum&LeftButtonMode&{&&&&&&&&&&&&&&&&&&&&Cancel(android.R.string.cancel,&true),&&&&&&&&&&&&&&&&&&&&CancelDisabled(android.R.string.cancel,&false),&&&&&&&&&&&&&&&&&&&&Retry(R.string.lockpattern_retry_button_text,&true),&&&&&&&&&&&&&&&&&&&&RetryDisabled(R.string.lockpattern_retry_button_text,&false),&&&&&&&&&&&&&&&&&&&&Gone(ID_EMPTY_MESSAGE,&false);&&&&&&&&&&&&&&&&&&&&&&&&&&&LeftButtonMode(int&text,&boolean&enabled)&{&&&&&&&&&&&&&&this.text&=&&&&&&&&&&&&&&&this.enabled&=&&&&&&&&&&&}&&&&&&&&&&&&final&int&&&&&&&&&&&final&boolean&&&&&&&}&&&&&&&&&&&&&&&&enum&RightButtonMode&{&&&&&&&&&&&&&&&&&&&&Continue(R.string.lockpattern_continue_button_text,&true),&&&&&&&&&&&&&&&&&&&&ContinueDisabled(R.string.lockpattern_continue_button_text,&false),&&&&&&&&&&&&&&&&&&&&Confirm(R.string.lockpattern_confirm_button_text,&true),&&&&&&&&&&&&&&&&&&&&ConfirmDisabled(R.string.lockpattern_confirm_button_text,&false),&&&&&&&&&&&&&&&&&&&&Ok(android.R.string.ok,&true);&&&&&&&&&&&&&&&&&&&&&&&&&&&RightButtonMode(int&text,&boolean&enabled)&{&&&&&&&&&&&&&&this.text&=&&&&&&&&&&&&&&&this.enabled&=&&&&&&&&&&&}&&&&&&&&&&&&final&int&&&&&&&&&&&final&boolean&&&&&&&}&&
* The states of the left footer button.
enum LeftButtonMode {
Cancel(android.R.string.cancel, true),
// 取消时禁用
CancelDisabled(android.R.string.cancel, false),
Retry(R.string.lockpattern_retry_button_text, true),
// 重试时禁用
RetryDisabled(R.string.lockpattern_retry_button_text, false),
Gone(ID_EMPTY_MESSAGE, false);
* @param text
The displayed text for this mode.
* @param enabled
Whether the button should be enabled.
LeftButtonMode(int text, boolean enabled) {
this.text =
this.enabled =
* The states of the right button.
enum RightButtonMode {
Continue(R.string.lockpattern_continue_button_text, true),
//继续时禁用
ContinueDisabled(R.string.lockpattern_continue_button_text, false),
Confirm(R.string.lockpattern_confirm_button_text, true),
//确认是禁用
ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
Ok(android.R.string.ok, true);
* @param text
The displayed text for this mode.
* @param enabled
Whether the button should be enabled.
RightButtonMode(int text, boolean enabled) {
this.text =
this.enabled =
就这样,只要LockPatternView的状态一发生改变,就会动态改变底部两个Button的文字和状态。很简洁,逻辑性很强。
3.第三个个人觉得比较有用的就是加密这一块了,为了以后方便使用,我把图案加密和字符加密分成两个工具类:LockPatternUtils和LockPasswordUtils两个文件,本文使用到的是LockPatternUtils。其实所谓的图案加密也是将其通过SHA-1加密转化成二进制数再保存到文件中(原生系统保存在/system/目录下,我这里没有权限,就保存到本应用目录下),解密时,也是将获取到用户的输入通过同样的方法加密,再与保存到文件中的对比,相同则密码正确,不同则密码错误。关健代码就是以下4个函数:
&&&&&&&&public&static&String&patternToString(List&LockPatternView.Cell&&pattern)&{&&&&&&if&(pattern&==&null)&{&&&&&&&&&&return&&&;&&&&&&}&&&&&&final&int&patternSize&=&pattern.size();&&&&&&&&byte[]&res&=&new&byte[patternSize];&&&&&&for&(int&i&=&0;&i&&&patternS&i++)&{&&&&&&&&&&LockPatternView.Cell&cell&=&pattern.get(i);&&&&&&&&&&res[i]&=&(byte)&(cell.getRow()&*&3&+&cell.getColumn());&&&&&&}&&&&&&return&new&String(res);&&}&&&&&&&&&&&&&public&void&saveLockPattern(List&LockPatternView.Cell&&pattern)&{&&&&&&&&&&&&final&byte[]&hash&=&LockPatternUtils.patternToHash(pattern);&&&&&&try&{&&&&&&&&&&&&&&&&&&&&RandomAccessFile&raf&=&new&RandomAccessFile(sLockPatternFilename,&&&&&&&&&&&&&&&&&&&rwd&);&&&&&&&&&&&&&&&&&&&&if&(pattern&==&null)&{&&&&&&&&&&&&&&raf.setLength(0);&&&&&&&&&&}&else&{&&&&&&&&&&&&&&raf.write(hash,&0,&hash.length);&&&&&&&&&&}&&&&&&&&&&raf.close();&&&&&&}&catch&(FileNotFoundException&fnfe)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Log.e(TAG,&&Unable&to&save&lock&pattern&to&&&+&sLockPatternFilename);&&&&&&}&catch&(IOException&ioe)&{&&&&&&&&&&&&&&&&&&&&Log.e(TAG,&&Unable&to&save&lock&pattern&to&&&+&sLockPatternFilename);&&&&&&}&&}&&&&&&&&&&&&&&private&static&byte[]&patternToHash(List&LockPatternView.Cell&&pattern)&{&&&&&&if&(pattern&==&null)&{&&&&&&&&&&return&null;&&&&&&}&&&&&&&&final&int&patternSize&=&pattern.size();&&&&&&byte[]&res&=&new&byte[patternSize];&&&&&&for&(int&i&=&0;&i&&&patternS&i++)&{&&&&&&&&&&LockPatternView.Cell&cell&=&pattern.get(i);&&&&&&&&&&res[i]&=&(byte)&(cell.getRow()&*&3&+&cell.getColumn());&&&&&&}&&&&&&try&{&&&&&&&&&&MessageDigest&md&=&MessageDigest.getInstance(&SHA-1&);&&&&&&&&&&byte[]&hash&=&md.digest(res);&&&&&&&&&&return&&&&&&&}&catch&(NoSuchAlgorithmException&nsa)&{&&&&&&&&&&return&&&&&&&}&&}&&&&&&&&&&&&&public&boolean&checkPattern(List&LockPatternView.Cell&&pattern)&{&&&&&&try&{&&&&&&&&&&&&&&&&&&&&RandomAccessFile&raf&=&new&RandomAccessFile(sLockPatternFilename,&&&&&&&&&&&&&&&&&&&r&);&&&&&&&&&&final&byte[]&stored&=&new&byte[(int)&raf.length()];&&&&&&&&&&int&got&=&raf.read(stored,&0,&stored.length);&&&&&&&&&&raf.close();&&&&&&&&&&if&(got&&=&0)&{&&&&&&&&&&&&&&return&true;&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&return&Arrays.equals(stored,&&&&&&&&&&&&&&&&&&LockPatternUtils.patternToHash(pattern));&&&&&&}&catch&(FileNotFoundException&fnfe)&{&&&&&&&&&&return&true;&&&&&&}&catch&(IOException&ioe)&{&&&&&&&&&&return&true;&&&&&&}&&}&&
* Serialize a pattern. 加密
* @param pattern
The pattern.
* @return The pattern in string form.
public static String patternToString(List&LockPatternView.Cell& pattern) {
if (pattern == null) {
return &&;
final int patternSize = pattern.size();
byte[] res = new byte[patternSize];
for (int i = 0; i & patternS i++) {
LockPatternView.Cell cell = pattern.get(i);
res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
return new String(res);
* Save a lock pattern.
* @param pattern
The new pattern to save.
* @param isFallback
Specifies if this is a fallback to biometric weak
public void saveLockPattern(List&LockPatternView.Cell& pattern) {
// Compute the hash
final byte[] hash = LockPatternUtils.patternToHash(pattern);
// Write the hash to file
RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename,
// Truncate the file if pattern is null, to clear the lock
if (pattern == null) {
raf.setLength(0);
raf.write(hash, 0, hash.length);
raf.close();
} catch (FileNotFoundException fnfe) {
// Cant do much, unless we want to fail over to using the settings
// provider
Log.e(TAG, &Unable to save lock pattern to & + sLockPatternFilename);
} catch (IOException ioe) {
// Cant do much
Log.e(TAG, &Unable to save lock pattern to & + sLockPatternFilename);
* Generate an SHA-1 hash for the pattern. Not the most secure, but it is at
* least a second level of protection. First level is that the file is in a
* location only readable by the system process.
* @param pattern the gesture pattern.
* @return the hash of the pattern in a byte array.
private static byte[] patternToHash(List&LockPatternView.Cell& pattern) {
if (pattern == null) {
final int patternSize = pattern.size();
byte[] res = new byte[patternSize];
for (int i = 0; i & patternS i++) {
LockPatternView.Cell cell = pattern.get(i);
res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
MessageDigest md = MessageDigest.getInstance(&SHA-1&);
byte[] hash = md.digest(res);
} catch (NoSuchAlgorithmException nsa) {
* Check to see if a pattern matches the saved pattern. If no pattern
* exists, always returns true.
* @param pattern
The pattern to check.
* @return Whether the pattern matches the stored one.
public boolean checkPattern(List&LockPatternView.Cell& pattern) {
// Read all the bytes from the file
RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename,
final byte[] stored = new byte[(int) raf.length()];
int got = raf.read(stored, 0, stored.length);
raf.close();
if (got &= 0) {
// Compare the hash from the file with the entered pattern's hash
return Arrays.equals(stored,
LockPatternUtils.patternToHash(pattern));
} catch (FileNotFoundException fnfe) {
} catch (IOException ioe) {
好了,代码就分析到这里,非常感谢你看到了文章末尾,很晚了,睡觉去,如果大家有什么问题或建议,欢迎留言,一起讨论,谢谢!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1079792次
积分:13432
积分:13432
排名:第378名
原创:138篇
转载:628篇
评论:316条
(6)(3)(3)(16)(14)(13)(4)(12)(1)(3)(14)(8)(2)(1)(8)(5)(17)(1)(1)(3)(1)(1)(3)(2)(1)(3)(1)(5)(2)(1)(5)(1)(15)(4)(8)(3)(6)(2)(21)(14)(56)(17)(13)(10)(6)(15)(7)(1)(8)(10)(6)(14)(16)(10)(9)(1)(7)(4)(1)(6)(5)(27)(66)(25)(18)(50)(7)(9)(7)(4)(3)(20)(1)(5)(11)(3)(2)(4)(4)(2)(2)(2)(1)(2)(5)(4)(5)(1)(3)(4)(12)(1)(1)(2)(1)(2)

我要回帖

更多关于 ppi是什么意思 的文章

 

随机推荐