Android 간단 한 제스처 암호 오픈 소스 라 이브 러 리 상세 설명

간단 한 소개
본 고 는 안 드 로 이 드 제스처 암호 오픈 소스 라 이브 러 리 의 사용 과 실현 에 대한 상세 한 과정 을 소개 한다.이 오픈 소스 라 이브 러 리 는 주로 다음 과 같은 몇 가지 기능 을 실현 한다.
4.567917.제스처 암호 의 그리 기 를 지원 하고 암호 저장 기능 을 지원 합 니 다.잠 금 을 풀 때 자동 으로 암호 에 대한 결 과 를 제공 합 니 다4.567917.비밀 번 호 를 그 리 는 방법 을 봉 인 했 습 니 다.두 번 의 비밀번호 가 일치 하 는 지 보다 제스처 비밀 번 호 를 빠르게 설정 할 수 있 습 니 다
  • 비밀번호 입력 오류 후의 재 시도 횟수 상한 선 을 설정 할 수 있 습 니 다
  • 서로 다른 상태 에서 제스처 암호 도안 의 색 을 사용자 정의 할 수 있 습 니 다
  • 제스처 암 호 를 사용자 정의 할 수 있 는 터치 포인트 수(n*n)
  • 최근 에는 제스처 암호 로 잠 금 해제 기능 을 사용 해 야 하기 때문에 demo 를 찾 아 사용 하기 가 좀 번 거 로 운 것 같 아서 일부 글 을 참고 하여 스스로 바퀴 를 만들어 관련 방법 을 밀봉 하여 사용 하기에 비교적 편리 하 다.
    github 링크 는 다음 과 같 습 니 다.스타 의 지원 을 받 을 수 있 을 것 같 습 니 다~
    github 링크    개인 블 로그
    사용 효과
    우선 사용 효과 보기:

    사용 방법
    XML 레이아웃 파일 에서 이 컨트롤 을 사용 합 니 다.
    
    <com.syd.oden.gesturelock.view.GestureLockViewGroup
      android:id="@+id/gesturelock"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:preference_id="1"
      android:layout_marginTop="30dp"
      app:count="3" />
    설정 할 수 있 는 매개 변 수 는 다음 과 같 습 니 다.
  • color_no_finger:만 지지 않 았 을 때 둥 근 색
  • color_finger_on:터치 할 때 동 그 란 색
  • color_finger_up_correct:정확 한 입력 시 원형 색상
  • color_finger_up_error:오류 발생 시 원형 색상
  • count:비밀 번 호 를 정리 하 는 원형 수량,n*n
  • preference_id:제스처 암호 로 저 장 된 id 번 호 는 입력 하지 않 거나 입력 하지 않 습 니 다.-1 은 기본 id 를 사용 합 니 다.
  • 초기 화
    
    private void initGesture() {
      mGestureLockViewGroup = (GestureLockViewGroup) findViewById(R.id.gesturelock);
      gestureEventListener();
      gesturePasswordSettingListener();
      gestureRetryLimitListener();
     }
    제스처 암호 감청 이벤트 설정
    
    private void gestureEventListener() {
      mGestureLockViewGroup.setGestureEventListener(new GestureEventListener() {
       @Override
       public void onGestureEvent(boolean matched) {
        mylog.d("onGestureEvent matched: " + matched);
        if (!matched) {
         tv_state.setTextColor(Color.RED);
         tv_state.setText("      ");
        } else {
         if (isReset) {
          isReset = false;
          Toast.makeText(MainActivity.this, "    !", Toast.LENGTH_SHORT).show();
          resetGesturePattern();
         } else {
          tv_state.setTextColor(Color.WHITE);
          tv_state.setText("      ");
         }
        }
       }
      });
     }
    
    비밀번호 가 설정 되 어 있 으 면 이 반전 에 들 어가 결 과 를 처리 합 니 다.위의 예 에 비밀 번 호 를 재 설정 하 는 처리 가 추가 되 었 습 니 다.
    제스처 암호 설정
    
    private void gesturePasswordSettingListener() {
      mGestureLockViewGroup.setGesturePasswordSettingListener(new GesturePasswordSettingListener() {
       @Override
       public boolean onFirstInputComplete(int len) {
        if (len > 3) {
         tv_state.setTextColor(Color.WHITE);
         tv_state.setText("        ");
         return true;
        } else {
         tv_state.setTextColor(Color.RED);
         tv_state.setText("    4  ,     !");
         return false;
        }
       }
    
       @Override
       public void onSuccess() {
        tv_state.setTextColor(Color.WHITE);
        Toast.makeText(MainActivity.this, "      !", Toast.LENGTH_SHORT).show();
        tv_state.setText("         !");
       }
    
       @Override
       public void onFail() {
        tv_state.setTextColor(Color.RED);
        tv_state.setText("         ,     ");
       }
      });
     }
    
    암호 가 설정 되 어 있 지 않 으 면 제스처 를 그 릴 때 이 반전 에 들 어 갑 니 다.그 려 진 터치 포인트 의 수 를 되 돌려 줍 니 다.onFirst InputComplete 에서 true 를 되 돌려 주면 두 번 째 제스처 암 호 를 그립 니 다.두 번 입력 하면 자동 으로 암 호 를 저장 합 니 다.
    재 시도 횟수 제한 감청 초과
    
    private void gestureRetryLimitListener() {
      mGestureLockViewGroup.setGestureUnmatchedExceedListener(3, new GestureUnmatchedExceedListener() {
       @Override
       public void onUnmatchedExceedBoundary() {
        tv_state.setTextColor(Color.RED);
        tv_state.setText("      ,     !");
       }
      });
     }
    
    이 감청 사건 이 설정 되 어 있 으 면 입력 오 류 는 횟수 제한 이 있 고 상한 선 을 초과 한 후 리 셋 에 들 어가 이 리 셋 에서 처리 합 니 다.
    암 호 를 지 우 는 논 리 는 스스로 판단 처 리 를 하면 됩 니 다.구체 적 으로 github 의 demo 를 볼 수 있 습 니 다.
    기타 API
    
    public void removePassword() :    
    public void savePassword() :     ,              ,              
    public void getPassword():     
    public void setRetryTimes(int retryTimes) :         
    public boolean isSetPassword() :              
    public void resetView() :    Reset
    
    프로젝트 에서 이 라 이브 러 리 가 져 오기
    두 줄 코드 만 추가:
    프로젝트 의 build.gradle 에 추가:
    
    allprojects {
      repositories {
       ...
       maven { url "https://jitpack.io" }
      }
     }
    
    module 의 build.gradle 에 의존 도 를 추가 합 니 다:
    
    dependencies {
       compile 'com.github.autume:GestureLock:1.0.0'
     }
    
    전체적인 사용 이 이 렇 습 니 다.간단 하지 않 습 니까?
    구체 적 실현 과정
    실현 과정 에 대해 서 는 직접 가 져 다 쓰 는 것 만으로 도 이 부분 을 생략 할 수 있다.
    사용자 정의 제스처 암호 의 원형 view
    이 부분 은 주로 Hongyang 의 큰 블 로 그 를 참고 하여 조금 수정 하 였 습 니 다.
    입력 매개 변수 초기 화
    
    public GestureLockView(Context context, int colorNoFingerr, int colorFingerOn, int colorCorrect, int colorError) {
      super(context);
      this.mColorNoFinger = colorNoFingerr;
      this.mColorFingerOn = colorFingerOn;
      this.mColorFingerUpCorrect = colorCorrect;
      this.mColorFingerUpError = colorError;
      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mArrowPath = new Path();
     }
    
    터치 상태 에 따라 원 을 그립 니 다.
    
    @Override
     protected void onDraw(Canvas canvas) {
    
      switch (mCurrentStatus) {
       case STATUS_FINGER_ON:
        //     
        mPaint.setStyle(Style.STROKE);
        mPaint.setColor(mColorFingerOn);
        mPaint.setStrokeWidth(2);
        canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
        //     
        mPaint.setStyle(Style.FILL);
        canvas.drawCircle(mCenterX, mCenterY, mRadius * mInnerCircleRadiusRate, mPaint);
        break;
       case STATUS_FINGER_UP:
        //     
        if (GestureLockViewGroup.isCorrect)
         mPaint.setColor(mColorFingerUpCorrect);
        else
         mPaint.setColor(mColorFingerUpError);
        mPaint.setStyle(Style.STROKE);
        mPaint.setStrokeWidth(2);
        canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
        //     
        mPaint.setStyle(Style.FILL);
        canvas.drawCircle(mCenterX, mCenterY, mRadius * mInnerCircleRadiusRate, mPaint);
        drawArrow(canvas);
        break;
       case STATUS_NO_FINGER:
        //     
        mPaint.setStyle(Style.STROKE);
        mPaint.setColor(mColorNoFinger);
        canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
        //     
        mPaint.setStyle(Style.FILL);
        mPaint.setColor(mColorNoFinger);
        canvas.drawCircle(mCenterX, mCenterY, mRadius * mInnerCircleRadiusRate, mPaint);
        break;
      }
     }
    
    
    화살표 그리 기
    
    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
      mWidth = MeasureSpec.getSize(widthMeasureSpec);
      mHeight = MeasureSpec.getSize(heightMeasureSpec);
    
      //         
      mWidth = mWidth < mHeight ? mWidth : mHeight;
      mRadius = mCenterX = mCenterY = mWidth / 2;
      mRadius -= mStrokeWidth / 2;
    
      //      ,                   ,       ,     GestureLockView         
      float mArrowLength = mWidth / 2 * mArrowRate;
      mArrowPath.moveTo(mWidth / 2, mStrokeWidth + 2);
      mArrowPath.lineTo(mWidth / 2 - mArrowLength, mStrokeWidth + 2 + mArrowLength);
      mArrowPath.lineTo(mWidth / 2 + mArrowLength, mStrokeWidth + 2 + mArrowLength);
      mArrowPath.close();
      mArrowPath.setFillType(Path.FillType.WINDING);
     }
    
     private void drawArrow(Canvas canvas) {
      if (mArrowDegree != -1) {
       mPaint.setStyle(Paint.Style.FILL);
    
       canvas.save();
       canvas.rotate(mArrowDegree, mCenterX, mCenterY);
       canvas.drawPath(mArrowPath, mPaint);
       canvas.restore();
      }
     }
    
    
    제스처 암 호 를 사용자 정의 하 는 ViewGroup
    사용자 정의 view 속성 추가
    
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
     <attr name="color_no_finger" format="color" />
     <attr name="color_finger_on" format="color" />
     <attr name="color_finger_up_correct" format="color" />
     <attr name="color_finger_up_error" format="color" />
     <attr name="count" format="integer" />
     <attr name="preference_id" format="integer" />
    
     <declare-styleable name="GestureLockViewGroup">
      <attr name="color_no_finger" />
      <attr name="color_finger_on" />
      <attr name="color_finger_up_correct" />
      <attr name="color_finger_up_error" />
      <attr name="count" />
      <attr name="preference_id" />
     </declare-styleable>
    
    </resources>
    
    
    매개 변수 가 져 오기 및 초기 화
    
    public GestureLockViewGroup(Context context, AttributeSet attrs,
            int defStyle) {
      super(context, attrs, defStyle);
    
      /**
       *             
       */
      TypedArray a = context.obtainStyledAttributes(attrs,
        R.styleable.GestureLockViewGroup, defStyle, 0);
    
      mNoFingerColor = a.getColor(R.styleable.GestureLockViewGroup_color_no_finger, mNoFingerColor);
      mFingerOnColor = a.getColor(R.styleable.GestureLockViewGroup_color_finger_on, mFingerOnColor);
      mFingerUpColorCorrect = a.getColor(R.styleable.GestureLockViewGroup_color_finger_up_correct, mFingerUpColorCorrect);
      mFingerUpColorError = a.getColor(R.styleable.GestureLockViewGroup_color_finger_up_error, mFingerUpColorError);
      mCount = a.getInt(R.styleable.GestureLockViewGroup_count, mCount);
      mPrferenceId = a.getInt(R.styleable.GestureLockViewGroup_preference_id, mPrferenceId);
    
      a.recycle();
    
      /**
       *       
       */
      gesturePreference = new GesturePreference(context, mPrferenceId);
      password = gesturePreference.ReadStringPreference();
      Log.d(TAG, "password now is : " + password);
      isSetPassword = !password.equals("null"); //           
      isInPasswordSettingMode = !isSetPassword;  //      ,        
    
      //      
      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setStrokeCap(Paint.Cap.ROUND);
      mPaint.setStrokeJoin(Paint.Join.ROUND);
      mPath = new Path();
     }
    
    
    매개 변수 에 따라 원 그리 기
    onMeasure 후 이 방법 을 사용 하여 원형 행렬 을 그립 니 다.
    
    private GestureLockView[] mGestureLockViews; //     GestureLockView
    
    private void initViews() {
      //    mGestureLockViews
      if (mGestureLockViews == null) {
       mGestureLockViews = new GestureLockView[mCount * mCount];
       //     GestureLockView   
       mGestureLockViewWidth = (int) (4 * mWidth * 1.0f / (5 * mCount + 1));
       //    GestureLockView   
       mMarginBetweenLockView = (int) (mGestureLockViewWidth * 0.25);
       //         GestureLockView         
       mPaint.setStrokeWidth(mGestureLockViewWidth * 0.29f);
    
       for (int i = 0; i < mGestureLockViews.length; i++) {
        //     GestureLockView
        mGestureLockViews[i] = new GestureLockView(getContext(), mNoFingerColor, mFingerOnColor, mFingerUpColorCorrect, mFingerUpColorError);
        mGestureLockViews[i].setId(i + 1);
        //    ,     GestureLockView    
        RelativeLayout.LayoutParams lockerParams = new RelativeLayout.LayoutParams(
          mGestureLockViewWidth, mGestureLockViewWidth);
    
        //         ,            
        if (i % mCount != 0) {
         lockerParams.addRule(RelativeLayout.RIGHT_OF,
           mGestureLockViews[i - 1].getId());
        }
        //       ,          View   
        if (i > mCount - 1) {
         lockerParams.addRule(RelativeLayout.BELOW,
           mGestureLockViews[i - mCount].getId());
        }
        //         
        int rightMargin = mMarginBetweenLockView;
        int bottomMargin = mMarginBetweenLockView;
        int leftMagin = 0;
        int topMargin = 0;
        /**
         *   View                               
         */
        if (i >= 0 && i < mCount)//    
        {
         topMargin = mMarginBetweenLockView;
        }
        if (i % mCount == 0)//    
        {
         leftMagin = mMarginBetweenLockView;
        }
    
        lockerParams.setMargins(leftMagin, topMargin, rightMargin,
          bottomMargin);
        mGestureLockViews[i].setMode(Mode.STATUS_NO_FINGER);
        addView(mGestureLockViews[i], lockerParams);
       }
      }
     }
    
    
    터치 감청 에서 서로 다른 사건 을 처리 하 다.
    
    @Override
     public boolean onTouchEvent(MotionEvent event) {
      int action = event.getAction();
      int x = (int) event.getX();
      int y = (int) event.getY();
      Log.d(TAG, "mTryTimes : " + mTryTimes);
    
      //        ,    
      if (mTryTimes <= 0 && isRetryTimeLimit) { 
       return true;
      }
    
      switch (action) {
       case MotionEvent.ACTION_DOWN:
        reset();  //   
        break;
       case MotionEvent.ACTION_MOVE:
        drawAndGetSelectedWhenTouchMove(x, y);
        break;
       case MotionEvent.ACTION_UP:
        if (isInPasswordSettingMode) {
         if (gesturePasswordSettingListener != null)
          setPasswordHandle(); //    
        } else {
         if (mChoose.size() > 0) {
          isCorrect = checkAnswer();
         } else {
          return true;
         }
    
         if (gestureEventListener != null) {
          gestureEventListener.onGestureEvent(isCorrect); //     
         }
         if (this.mTryTimes == 0) {
          gestureUnmatchedExceedListener.onUnmatchedExceedBoundary(); //      ,    
         }
        }
        drawWhenTouchUp();
        break;
      }
      invalidate();
      return true;
     }
    
     private void drawAndGetSelectedWhenTouchMove(int x, int y) {
      mPaint.setColor(mFingerOnColor);
      mPaint.setAlpha(50);
      GestureLockView child = getChildIdByPos(x, y);
      if (child != null) {
       int cId = child.getId();
       if (!mChoose.contains(cId)) {
        mChoose.add(cId);
        mChooseString = mChooseString + cId;
        child.setMode(Mode.STATUS_FINGER_ON);
        //         
        mLastPathX = child.getLeft() / 2 + child.getRight() / 2;
        mLastPathY = child.getTop() / 2 + child.getBottom() / 2;
    
        if (mChoose.size() == 1)//         
        {
         mPath.moveTo(mLastPathX, mLastPathY);
        } else
        //     ,        
        {
         mPath.lineTo(mLastPathX, mLastPathY);
        }
       }
      }
      //       
      mTmpTarget.x = x;
      mTmpTarget.y = y;
     }
    
     private void drawWhenTouchUp() {
      if (isCorrect) {
       mPaint.setColor(mFingerUpColorCorrect);
      } else {
       mPaint.setColor(mFingerUpColorError);
      }
      mPaint.setAlpha(50);
      Log.d(TAG, "mChoose = " + mChoose);
      //           ,      
      mTmpTarget.x = mLastPathX;
      mTmpTarget.y = mLastPathY;
    
      //          UP
      setItemModeUp();
    
      //                 
      for (int i = 0; i + 1 < mChoose.size(); i++) {
       int childId = mChoose.get(i);
       int nextChildId = mChoose.get(i + 1);
    
       GestureLockView startChild = (GestureLockView) findViewById(childId);
       GestureLockView nextChild = (GestureLockView) findViewById(nextChildId);
    
       int dx = nextChild.getLeft() - startChild.getLeft();
       int dy = nextChild.getTop() - startChild.getTop();
       //     
       int angle = (int) Math.toDegrees(Math.atan2(dy, dx)) + 90;
       startChild.setArrowDegree(angle);
      }
     }
    
    
     암호 처리 설정:
    
    private void setPasswordHandle() {
      if (isWaitForFirstInput) {
       if (gesturePasswordSettingListener.onFirstInputComplete(mChooseString.length())) {
        firstInputPassword = mChooseString;
        isWaitForFirstInput = false;
       }
      } else {
       if (firstInputPassword.equals(mChooseString)) {
        gesturePasswordSettingListener.onSuccess();
        savePassword(mChooseString);
        isInPasswordSettingMode = false;
       } else {
        gesturePasswordSettingListener.onFail();
       }
      }
      reset();
     }
    
    제스처 암호 가 올 바른 지 확인 하기:
    
    public boolean checkAnswer() {
      if (password.equals(mChooseString)) {
       return true;
      } else {
       if (isRetryTimeLimit)
        this.mTryTimes--;
       return false;
      }
     }
    
    초기 화:
    
    private void reset() {
      mChoose.clear();
      mChooseString = "";
      mPath.reset();
      for (GestureLockView gestureLockView : mGestureLockViews) {
       gestureLockView.setMode(Mode.STATUS_NO_FINGER);
       gestureLockView.setArrowDegree(-1);
      }
     }
    
    대외 적 으로 공개 하 는 방법 들
    
    public void setGestureEventListener(GestureEventListener gestureEventListener) {
      this.gestureEventListener = gestureEventListener;
     }
    
     public void setGestureUnmatchedExceedListener(int retryTimes, GestureUnmatchedExceedListener gestureUnmatchedExceedListener) {
      isRetryTimeLimit = true;
      this.mTryTimes = retryTimes;
      this.gestureUnmatchedExceedListener = gestureUnmatchedExceedListener;
     }
    
     public void setGesturePasswordSettingListener(GesturePasswordSettingListener gesturePasswordSettingListener) {
      this.gesturePasswordSettingListener = gesturePasswordSettingListener;
     }
    
     public void removePassword() {
      gesturePreference.WriteStringPreference("null");
      this.isSetPassword = false;
      isWaitForFirstInput = true;
      isInPasswordSettingMode = true;
     }
    
     public void savePassword(String password) {
      this.password = password;
      gesturePreference.WriteStringPreference(password);
     }
    
     public String getPassword() {
      return password;
     }
    
     public void resetView() {
      reset();
      invalidate();
     }
    
     public void setRetryTimes(int retryTimes) {
      this.mTryTimes = retryTimes;
     }
    
     public boolean isSetPassword() {
      return isSetPassword;
     }
    
    
    암호 로 저 장 된 Preference 정의
    간단 한 저장 과 읽 기 입 니 다.
    
    public GesturePreference(Context context, int nameTableId) {
      this.context = context;
      if (nameTableId != -1)
       this.nameTable = nameTable + nameTableId;
     }
    
     public void WriteStringPreference(String data) {
      SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
      SharedPreferences.Editor editor = preferences.edit();
      editor.putString(nameTable, data);
      editor.commit();
     }
    
     public String ReadStringPreference() {
      SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
      return preferences.getString(nameTable, "null");
     }
    
    
    총결산
    ok,이로써 전체 제스처 암호 의 실현 이 완료 되 었 습 니 다.
    이상 은 안 드 로 이 드 에 대한 간단 한 제스처 비밀 번 호 를 실현 하 는 자 료 를 정리 하고 관련 자 료 를 계속 정리 하 는 것 입 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기