程序参考com.android.settings:
程序中使用:import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell;
这三个类属于隐藏类,程序需要在源码中build。(该程序需系统权限)
package com.wistron.screen.lock; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Vibrator; import android.R.integer; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.DialogInterface; import android.util.Log; import android.view.Gravity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView.Cell; import com.wistron.screen.lock.CustomPattern.OnChangePointListenter; public class ScreenLock extends Activity implements OnClickListener, OnChangePointListenter, OnItemSelectedListener { private final int SCREEN_LOCK_NONE = 0; private final int SCREEN_LOCK_SLIDE = 1; private final int SCREEN_LOCK_PATTERN = 2; private final int SCREEN_LOCK_PIN = 3; private final int SCREEN_LOCK_PASSWORD = 4; private DevicePolicyManager mDevicePolicyManager; private LockPatternUtils mLockPatternUtils; private Spinner mScreenModeSpinner; private Button mUpdateButton; private CustomPattern mCustomPattern; private int mQuilty; private boolean mMode; private int mSelectID = -1; protected List<LockPatternView.Cell> mChosenPattern = null; private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; private ArrayList<PatternPoint> mPatternPointsList = new ArrayList<ScreenLock.PatternPoint>(); private Vibrator mVibrator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_screen_lock); findView(); mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); mLockPatternUtils = new LockPatternUtils(ScreenLock.this); mVibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE); mChosenPattern = new ArrayList<LockPatternView.Cell>(); // mChosenPattern.add(LockPatternView.Cell.of(0, 0)); // mChosenPattern.add(LockPatternView.Cell.of(0, 1)); // mChosenPattern.add(LockPatternView.Cell.of(1, 1)); // mChosenPattern.add(LockPatternView.Cell.of(2, 1)); } public void findView() { mScreenModeSpinner = (Spinner) findViewById(R.id.select_mode); mUpdateButton = (Button) findViewById(R.id.update); String[] mode = getResources().getStringArray(R.array.screen_lock_mode); List<String> mModeList = new ArrayList<String>(); mModeList = Arrays.asList(mode); SpinnerTest mSpinnerTest = new SpinnerTest(mModeList); mScreenModeSpinner.setAdapter(mSpinnerTest); mScreenModeSpinner.setOnItemSelectedListener(this); mCustomPattern = (CustomPattern)findViewById(R.id.pattern_view); mCustomPattern.SetOnChangePointListener(this); mCustomPattern.setVisibility(View.GONE); mUpdateButton.setOnClickListener(this); } private void updateUnlockMethodAndFinish(int quality, boolean disabled) { // TODO Auto-generated method stub int minQuality = mDevicePolicyManager.getPasswordQuality(null); if (quality < minQuality) { quality = minQuality; } quality = upgradeQualityForEncryption(quality); if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { mRequestedQuality = Math.max(quality, mLockPatternUtils.getRequestedPasswordQuality()); mLockPatternUtils.clearLock(true); mLockPatternUtils.saveLockPassword("123456", mRequestedQuality); } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { mLockPatternUtils.clearLock(true); mLockPatternUtils.setLockScreenDisabled(disabled); } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { saveChosenPatternAndFinish(); } } private int upgradeQualityForEncryption(int quality) { int encryptionStatus = mDevicePolicyManager.getStorageEncryptionStatus(); boolean encrypted = (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) || (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING); if (encrypted) { if (quality < DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { quality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; } } return quality; } public class SpinnerTest extends BaseAdapter { private List<String> mList; public SpinnerTest(List<String> list) { mList = list; } @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub TextView mView = new TextView(ScreenLock.this); mView.setText(mList.get(position)); mView.setTextSize(25); mView.setGravity(Gravity.CENTER); return mView; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.screen_lock, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v == mUpdateButton) { getScreenLockMode(); updateUnlockMethodAndFinish(mQuilty, mMode); if(mSelectID == SCREEN_LOCK_PATTERN){ mCustomPattern.ClearTrack(); mCustomPattern.RetryTrack(); } } } public void getScreenLockMode() { int id = -1; id = (int) mScreenModeSpinner.getSelectedItemId(); mSelectID = id; Log.i("Flag", "id= " + id); switch (id) { case SCREEN_LOCK_NONE: mQuilty = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; mMode = true; break; case SCREEN_LOCK_SLIDE: mQuilty = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; mMode = false; break; case SCREEN_LOCK_PATTERN: mQuilty = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; mMode = false; break; case SCREEN_LOCK_PIN: mQuilty = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; mMode = false; break; case SCREEN_LOCK_PASSWORD: mQuilty = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; mMode = false; break; } } private void saveChosenPatternAndFinish() { LockPatternUtils utils = mLockPatternUtils; final boolean lockVirgin = !utils.isPatternEverChosen(); Log.i("Flag", "lockVirgin= " + lockVirgin); utils.saveLockPattern(mChosenPattern); utils.setLockPatternEnabled(true); if (lockVirgin) { // utils.setVisiblePatternEnabled(true); // utils.setTactileFeedbackEnabled(false); } } @Override public void isVibration(int x, int y) { // TODO Auto-generated method stub PatternPoint mPatternPoint = new PatternPoint(); mPatternPoint.mXValue = x; mPatternPoint.mYValue = y; mPatternPointsList.add(mPatternPoint); mHandler.sendEmptyMessage(0); } @Override public void isDone() { // TODO Auto-generated method stub mHandler.sendEmptyMessage(2); } @Override public void isTouchDown() { // TODO Auto-generated method stub mHandler.sendEmptyMessage(1); } public Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if(msg.what == 0){ mVibrator.vibrate(50); }else if(msg.what == 1){ mUpdateButton.setEnabled(false); }else if(msg.what == 2){ mUpdateButton.setEnabled(true); if(mPatternPointsList.size() < 4){ Toast.makeText(ScreenLock.this, getString(R.string.pattern_point_less),Toast.LENGTH_LONG).show(); }else { for(int i = 0 ; i < mPatternPointsList.size() ; i ++){ mChosenPattern.add(LockPatternView.Cell.of(mPatternPointsList.get(i).mXValue, mPatternPointsList.get(i).mYValue)); } } } } }; public class PatternPoint{ int mXValue; int mYValue; } @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub if(arg2 == SCREEN_LOCK_PATTERN){ mCustomPattern.setVisibility(View.VISIBLE); }else { mCustomPattern.setVisibility(View.GONE); } } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }
自定义Pattern:
package com.wistron.screen.lock; import java.util.ArrayList; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class CustomPattern extends View { private Paint mPaint, mSizePaint, mLinePaint; private int mScreenWidth; private int mScreenHeight; private float mXActionDown, mYActionDown; private int mCircleRadiu = 25; private int mSide = 20 + mCircleRadiu; private boolean isFirstPoint = false; private float mOldPointX, mOldPointY; private ArrayList<CirclePoint> mCirclePointsList = new ArrayList<CustomPattern.CirclePoint>(); private boolean isActionUp = false; private boolean isClear = true; public CustomPattern(Context context) { super(context); // TODO Auto-generated constructor stub init(context); } public CustomPattern(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(context); } public CustomPattern(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub init(context); } public void init(Context context) { mPaint = new Paint(); mPaint.setColor(Color.WHITE); mPaint.setStyle(Style.STROKE); mSizePaint = new Paint(); mSizePaint.setColor(Color.GREEN); mSizePaint.setStyle(Style.STROKE); mLinePaint = new Paint(); mLinePaint.setColor(Color.GRAY); invalidate(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); mScreenWidth = getWidth(); mScreenHeight = getHeight(); canvas.drawColor(Color.BLACK); for (int j = 0; j < 3; j++) { for (int i = 0; i < 3; i++) { canvas.drawCircle(mSide + i * mScreenWidth / 3, mSide + j * mScreenHeight / 3, 5, mPaint); } } for (int j = 0; j < 3; j++) { for (int i = 0; i < 3; i++) { float distance = Distance(mSide + i * mScreenWidth / 3, mSide + j * mScreenHeight / 3, mXActionDown, mYActionDown); if (distance < mCircleRadiu) { float mTempX = mSide + i * mScreenWidth / 3; float mTempY = mSide + j * mScreenHeight / 3; boolean isHave = false; for (int k = 0; k < mCirclePointsList.size(); k++) { if (mCirclePointsList.get(k).x == mTempX) { if (mCirclePointsList.get(k).y == mTempY) { isHave = true; } } } if (!isHave && isClear) { mOldPointX = mTempX; mOldPointY = mTempY; CirclePoint mCirclePoint = new CirclePoint(); mCirclePoint.x = mOldPointX; mCirclePoint.y = mOldPointY; mCirclePointsList.add(mCirclePoint); isFirstPoint = true; Message message = new Message(); message.what = 0; message.arg1 = j; message.arg2 = i; handler.sendMessage(message); } } } } for (int i = 0; i < mCirclePointsList.size(); i++) { canvas.drawCircle(mCirclePointsList.get(i).x, mCirclePointsList.get(i).y, mCircleRadiu, mSizePaint); } if (mCirclePointsList.size() >= 2) { for (int i = 0; i < mCirclePointsList.size() - 1; i++) { canvas.drawLine(mCirclePointsList.get(i).x, mCirclePointsList.get(i).y, mCirclePointsList.get(i + 1).x, mCirclePointsList.get(i + 1).y, mLinePaint); } } if (isFirstPoint && !isActionUp) { canvas.drawLine(mOldPointX, mOldPointY, mXActionDown, mYActionDown, mLinePaint); } } public float Distance(float x0, float y0, float x1, float y1) { return (float) Math.sqrt(((x1 - x0) * (x1 - x0)) + ((y1 - y0) * (y1 - y0))); } public void RetryTrack(){ isClear = true; } public void ClearTrack(){ isClear = false; mCirclePointsList.clear(); invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub addTouchEvent(event); return true; } public void addTouchEvent(MotionEvent event) { mXActionDown = event.getX(); mYActionDown = event.getY(); postInvalidate(); if (event.getAction() == MotionEvent.ACTION_UP) { isActionUp = true; handler.sendEmptyMessage(1); } if (event.getAction() == MotionEvent.ACTION_DOWN) { handler.sendEmptyMessage(2); mCirclePointsList.clear(); } } public class CirclePoint { float x; float y; } public OnChangePointListenter mChangePointListenter; public void SetOnChangePointListener(OnChangePointListenter listenter) { this.mChangePointListenter = listenter; } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if (msg.what == 0) { mChangePointListenter.isVibration(msg.arg1, msg.arg2); } else if (msg.what == 1) { mChangePointListenter.isDone(); } else if (msg.what == 2) { mChangePointListenter.isTouchDown(); } } }; public abstract interface OnChangePointListenter { public abstract void isVibration(int x, int y); public abstract void isDone(); public abstract void isTouchDown(); } }