程序参考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();
}
}