android4.0实现一个简单的锁屏程序

时间:2021-03-29 17:15:56

根据网上资料,在android4.0上实现一个简单的锁屏程序。

先贴上布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >


    <com.wind.dragimg.SliderRelativeLayout
        android:id="@+id/slider_layout"
        android:layout_width="match_parent"
        android:layout_height="63dip"
        android:layout_marginTop="200dip"
        android:background="@drawable/step2_tip_2">
        
        <ImageView 
            android:id="@+id/getup_finish_ico"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dip"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:background="@drawable/slider_ico_alarm"
            android:contentDescription="@string/app_name"/>
        
        <ImageView 
            android:id="@+id/getup_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dip"
            android:layout_toLeftOf="@id/getup_finish_ico"
            android:layout_alignTop="@id/getup_finish_ico"
            android:src="@drawable/slider_tip_anim"
            android:contentDescription="@string/app_name"
            />
        
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ff0000"
            android:layout_marginRight="20dip"
            android:layout_toLeftOf="@id/getup_arrow"
            android:layout_alignTop="@id/getup_finish_ico"
            android:text="@string/hint_unlock"/>
        
        <!-- slider img -->
        <ImageView  android:id="@+id/slider_icon"
            android:layout_width="wrap_content"
   android:layout_height="wrap_content" 
   android:layout_marginRight="5dip"
   android:src="@drawable/getup_slider_ico_normal"
   android:contentDescription="@string/app_name"/>
        
    </com.wind.dragimg.SliderRelativeLayout>


</LinearLayout>


布局文件中用了一个自定义的ViewGroup :SliderRelativeLayout,滑动解锁的主要功能就是在这个class文件中实现的。

下边先看下这个class文件

package com.wind.dragimg;


import java.lang.ref.WeakReference;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;


public class SliderRelativeLayout extends RelativeLayout{
private Context mContext;
private ImageView tv_slider_icon;
private Bitmap dragBitmap;
private int mLastMoveX;
private Handler mainHandler;
private Handler mHandler;
private static final int MSG_BACK_SLIDER_IMG = 1;
private static final int DELAY_TIME = 5;
public SliderRelativeLayout(Context context) {
super(context);
mContext = context;
mHandler = new MyHandler(this);
initDragBitmap();
}


private void initDragBitmap() {
if (dragBitmap == null) {
dragBitmap = BitmapFactory.decodeResource(mContext.getResources(), 
R.drawable.getup_slider_ico_pressed);
}
}


public SliderRelativeLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
mContext = context;
mHandler = new MyHandler(this);
initDragBitmap();
}


public SliderRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mHandler = new MyHandler(this);
initDragBitmap();
}

@Override
protected void onFinishInflate() {
// TODO Auto-generated method stub
super.onFinishInflate();
tv_slider_icon = (ImageView)findViewById(R.id.slider_icon);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastMoveX = (int)event.getX();
return handleActionDownEvent(event);

case MotionEvent.ACTION_MOVE:
mLastMoveX = (int)event.getX();
invalidate();
return true;

case MotionEvent.ACTION_UP:
handleActionUpEvent(event);
return true;

default:
break;
}
return super.onTouchEvent(event);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
invalidateDragImg(canvas);
}
private void invalidateDragImg(Canvas canvas) {
int drawX = mLastMoveX - dragBitmap.getWidth();
int drawY = tv_slider_icon.getTop();
canvas.drawBitmap(dragBitmap, drawX < 0 ? 5 : drawX, drawY, null);
}


private void handleActionUpEvent(MotionEvent event) {
int x = (int)event.getX();
boolean isSuccess = Math.abs(x - getRight()) <= 15;

if (isSuccess) {
Toast.makeText(mContext, R.string.unlock_success, Toast.LENGTH_LONG).show();
resetViewState();
vibrate();
mainHandler.obtainMessage(MainActivity.MSG_LOCK_SUCCESS).sendToTarget();
} else {
mLastMoveX = x;
int distance = x - tv_slider_icon.getRight();
if (distance > 0) {
mHandler.sendEmptyMessageDelayed(MSG_BACK_SLIDER_IMG, DELAY_TIME);
} else {
resetViewState();
}
}
}


private void vibrate() {
Vibrator vibrator= (Vibrator)mContext.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(200);
}


private void resetViewState() {
mLastMoveX = 1000;
tv_slider_icon.setVisibility(View.VISIBLE);
invalidate();
}


private boolean handleActionDownEvent(MotionEvent event) {
Rect rect = new Rect();
tv_slider_icon.getHitRect(rect);
boolean isHit = rect.contains((int)event.getX(), (int)event.getY());

if (isHit) {
tv_slider_icon.setVisibility(View.INVISIBLE);
}
return isHit;
}

private static class MyHandler extends Handler{
private WeakReference<SliderRelativeLayout> mLayout;

public MyHandler(SliderRelativeLayout layout) {
mLayout = new WeakReference<SliderRelativeLayout>(layout);
}
@Override
public void handleMessage(Message msg) {
SliderRelativeLayout layout = mLayout.get();
switch (msg.what) {
case MSG_BACK_SLIDER_IMG:
layout.backSliderImg();
break;


default:
break;
}
}
}

private void backSliderImg() {
mLastMoveX = mLastMoveX - 8;
invalidate();
boolean shoudEnd = Math.abs(mLastMoveX - tv_slider_icon.getRight()) <= 8;

if (!shoudEnd) {
mHandler.sendEmptyMessageDelayed(MSG_BACK_SLIDER_IMG, DELAY_TIME);
} else {
resetViewState();
}
}

public void setMainHandler(Handler handler) {
mainHandler = handler;
}
}


此应用中还用到了一个帧动画。布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/slider_arrow_1" android:duration="150"></item> 
    <item android:drawable="@drawable/slider_arrow_2" android:duration="150"></item> 
    <item android:drawable="@drawable/slider_arrow_3" android:duration="150"></item>   
</animation-list>

帧动画的具体实现看以参看我其他的文章


下边看下主activity类,这个类中有一些锁屏功能所需要的必要设置,比如屏蔽Home键等。

package com.wind.dragimg;


import java.lang.ref.WeakReference;


import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;


public class MainActivity extends Activity {
private ImageView animal;
private AnimationDrawable animationDrawable;
public final static int MSG_LOCK_SUCCESS = 1;
public static final int FLAG_HOMEKEY_DISPATCHED = 0x80000000;
private SliderRelativeLayout sliderRelativeLayout;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//窗口无标题
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//窗口全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);
//为窗口添加了这个标志后,当前activity运行的时候不会锁屏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, 
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
setContentView(R.layout.activity_main);
animal = (ImageView)this.findViewById(R.id.getup_arrow);
sliderRelativeLayout = (SliderRelativeLayout)this.findViewById(R.id.slider_layout);
animationDrawable = (AnimationDrawable)animal.getDrawable();
animationDrawable.start();
mHandler = new MyHandler(this);
sliderRelativeLayout.setMainHandler(mHandler);
startService(new Intent(MainActivity.this, DragImgService.class));
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}


//这个函数可以屏蔽Back键,Menu键
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
return true;

case KeyEvent.KEYCODE_MENU:
return true;

default:
break;
}
return super.onKeyDown(keyCode, event);
}

private static class MyHandler extends Handler {
private WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity mainAcvity) {
this.mActivity = new WeakReference<MainActivity>(mainAcvity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = mActivity.get();
switch (msg.what) {
case MSG_LOCK_SUCCESS:
activity.closeActivity();
break;


default:
break;
}
}
}

private void closeActivity() {
finish();
}
}

为了能实现手机灭屏后开启锁屏程序,我添加了一个service,具体实现如下

package com.wind.dragimg;


import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;


public class DragImgService extends Service{
private Intent mainIntent;
private BroadcastReceiver screenOffReceiver;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mainIntent = new Intent(DragImgService.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

IntentFilter screenOffFilter = new IntentFilter("android.intent.action.SCREEN_OFF");
screenOffReceiver = new ScreenOffReceiver();
registerReceiver(screenOffReceiver, screenOffFilter);
}

@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(screenOffReceiver);
startService(new Intent(DragImgService.this, DragImgService.class));
}
private class ScreenOffReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String screen_off_action = "android.intent.action.SCREEN_OFF";
if (action.equals(screen_off_action)) {
context.startActivity(mainIntent);
}
}

}
}

至此,锁屏的主要功能已经实现