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

jopen 10年前

在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);  }  }    }  }

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