一个简单的屏幕保护例子

Demos简介:

     当屏幕或按键没有被触碰的时间超过5s时,会进入屏幕保护模式。屏幕保护模式下,原来的布局文件被隐藏,只显示图片背景,且每1s图片切换一次,图片切换时有淡入、淡出效果。

package com.example.screensaverdemos;

import java.util.Date;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * @author Administrator
 * ScreenSaveSetting summary:
 * 当屏幕或按键没有被触碰的时间超过5s时,会进入屏幕保护模式。屏幕保护模式下,原来的布局文件被隐藏,只显示图片背景,
 * 且每1s图片切换一次,图片切换时有淡入、淡出效果。本实例中使用了4个Handler来处理不同的功能模块。
 * mMainTask每1s执行一次,
 * 手机处于无人触碰状态时:
 * 1s后,mCounter1 = 1
 * 2s后,mCounter1 = 2;
 * ...
 * 5s后,mCounter = 5,mTimePeriod  = 5.009s,进入屏幕保护模式。显示屏幕淡出效果
 * 6s后,执行mSwitchImageTask切换背景图片,同时又屏幕淡入效果
 * 7s后,nothing
 * 8s后,nothing
 * 9s后,nothing
 * 10s后,显示屏幕淡出效果
 * 11s后,切换背景图片,显示屏幕淡入效果
 * ...
 * 注:所有的Handler都在一个Thread中运行
 */
public class ScreenSaveSettingActivity extends Activity {
	private static final String TAG = "yxf";

	private final static long INTERVAL_SCREENSAVER = 1000;
	private final static long INTERVAL_KEYPADESAVER = 1000;
	private final static long INTERVAL_FADE = 100;
	private final static float HOLD_STILL_SECONDS = (float) 5;

	private int mCounter1;// Calculate the count in mMainTask
	private int mCounter2;//Calculate the count in mSetImageTask
	private int mCounter3;//Calculate the count in mFadeOutTask
	private int mCounter4;//Calculate the count in mFadeInTask
	
	private long mTimePeriod;
	private Date mLastUpdateTime;
	/*每隔5s中更换一张照片*/
	private int mSecondsToChange = 5;
	private boolean mIsShowingScreenSaver;
	/*flag to control whether to show fade out animation*/
	private boolean mFadeOutFlag;
	/*flag to control whether to show fade in animation*/
	private boolean mFadeInFlag;
	
	private TextView mTextView;
	private ImageView mImageView;
	private EditText mEditText;
	
	private int mDrawablePos;
	/* 设定Screen Saver需要用到的背景图 */
	private static int[] mScreenDrawable = new int[]{
	    R.drawable.screen1,
	    R.drawable.screen2,
	    R.drawable.screen3,
	    R.drawable.screen4,
	    R.drawable.screen5
	  };
	private Handler mMainHandler = new Handler();
	private Handler mSwitchImageHandler = new Handler();
	private Handler mFadeOutHandler = new Handler();
	private Handler mFadeInHandler = new Handler();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_main);
		/* onCreate all Widget */
	    mTextView = (TextView)findViewById(R.id.textView1);
	    mImageView = (ImageView)findViewById(R.id.imageView1);
	    mEditText = (EditText)findViewById(R.id.editText1);
	    
	    /* get the last time that user touches the screen */
	    mLastUpdateTime = new Date(System.currentTimeMillis());
	    
	    /* set the original visibility */
	    recoverOriginalLayout();
	}
	
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		mMainHandler.postDelayed(mMainTask, INTERVAL_KEYPADESAVER);
	}

	/**
	 * mMainTask是核心代码,当mCounter=5时,timePeriodSecond>5s,第一次进入屏幕保护模式。
	 * 第6s(5s)期间的工作,:
	 *     1. 调用mFadeOutHandler推送mSwitchImageTask,1s后执行。
	 *     2. 设mFadeOutFlag=true,调用mFadeOutHandler推送mShowFadeOutTask,100ms后执行,接下来的1s也就是第6s期间会通过不停执行
	 *        mFadeOutTask来形成淡出动画。
	 *     3.设置mIsShowingScreenSaver为true。
	 * 第7s(6s后)期间的工作,mCounter1=6:
	 *     1. 上一秒的mSwitchImageTask这时候执行,设置背景为第一张图片。
	 *     2. 设置mFadeInFlag为true,调用mFadeInHandler推送mShowFadeInTask,0.1s后执行。
	 *     3. 设置mCountg3=0,mFadeOutFlag = false,这样就停止了mShowFadeOutTask的执行。
	 *     4. 不断的执行mShowFadeInTask形成淡入动画
	 * 7s后(第8s)做的工作,mCounter1=7:
	 *     1. 设置mFadeInFlag和mFadeOuntFlag均为false,mCounter3和mCounter4均为0,即使图片处于静止状态。
	 * 8s后(第9s)做的工作,mCounter1=8,与第8s一样;第10s也也与他一样;
	 * 10s后(第11s)时,mCounter1=10:
	 *     1.设置mFadeOutFlag为true,推送mFadeOutTask,0.1s后执行
	 *     2.重复调用mFadeOutTask形成淡出动画
	 *
	 */
    private Runnable mMainTask = new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			mCounter1++;
			Date timeNow = new Date(System.currentTimeMillis());
			mTimePeriod = timeNow.getTime() - mLastUpdateTime.getTime();
			float timePeriodSecond = ((float) mTimePeriod / 1000);
			if (timePeriodSecond > HOLD_STILL_SECONDS) {
				if (mIsShowingScreenSaver) {
					/* ScreenSaver is running already */
					if ((mCounter1 % mSecondsToChange) == 0) {
						mFadeOutFlag = true;
						mFadeOutHandler.postDelayed(mShowFadeOutTask, INTERVAL_FADE);
					} else {
						if (mFadeOutFlag) {
							mFadeInFlag = true;
							mFadeInHandler.postDelayed(mShowFadeInTask, INTERVAL_FADE);
						} else {
							mFadeInFlag = false;
							mCounter4 = 0;
							mFadeInHandler.removeCallbacks(mShowFadeInTask);
						}
						mCounter3 = 0;
						mFadeOutFlag = false;
					}
				} else {
					/*已经有足够长的时间没有用户触碰屏幕,进入屏幕保护模式*/
					mSwitchImageHandler.postDelayed(mSwitchImageTask, INTERVAL_SCREENSAVER);
					if ((mCounter1 % mSecondsToChange) == 0) {
						mFadeOutFlag = true;
						mFadeOutHandler.postDelayed(mShowFadeOutTask, INTERVAL_FADE);
					} else {
						if (mFadeOutFlag) {
							mFadeInFlag = true;
							mFadeInHandler.postDelayed(mShowFadeInTask, INTERVAL_FADE);
						} else {
							mFadeInFlag = false;
							mCounter4 = 0;
							mFadeInHandler.removeCallbacks(mShowFadeInTask);
						}
						mCounter3 = 0;
						mFadeOutFlag = false;
					}
					mIsShowingScreenSaver = true;
				}
			} else {
				mIsShowingScreenSaver = false;
				/* 恢复原来的Layout Visible */
		        recoverOriginalLayout();
			}
			mMainHandler.postDelayed(mMainTask, INTERVAL_KEYPADESAVER);
		}
	};
	
	private Runnable mSwitchImageTask = new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (mIsShowingScreenSaver) {
				mCounter2++;
				hideOriginalLayout();
				showScreenSaver();
				mSwitchImageHandler.postDelayed(mSwitchImageTask,
						INTERVAL_SCREENSAVER);
			} else {
				mSwitchImageHandler.removeCallbacks(mSwitchImageTask);
			}
		}
	};
	
	private Runnable mShowFadeOutTask = new Runnable() {
		@SuppressWarnings("deprecation")
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if(mFadeOutFlag && mIsShowingScreenSaver){
			    mCounter3++;
			    /* 设定ImageView的透明度渐暗下去 */
		        mImageView.setAlpha(255 - mCounter3*28);
		        mFadeOutHandler.postDelayed(mShowFadeOutTask, INTERVAL_FADE);
			}else{
				mFadeOutHandler.removeCallbacks(mShowFadeOutTask);
			}
		}
	};
	
	private Runnable mShowFadeInTask = new Runnable(){
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if(mFadeInFlag && mIsShowingScreenSaver){
				mCounter4++;
				/* 设定ImageView的透明度渐暗下去 */
		        mImageView.setAlpha(mCounter4 * 28);
		        mFadeInHandler.postDelayed(mShowFadeInTask, INTERVAL_FADE);
			}else {
				mFadeInHandler.removeCallbacks(mShowFadeInTask);
			}
		}
		
	};
	private void hideOriginalLayout(){
		mTextView.setVisibility(View.INVISIBLE);
	    mEditText.setVisibility(View.INVISIBLE);
	}
	
	private void showScreenSaver(){
		/* 屏幕保护之后要做的事件写在此*/
		if (mDrawablePos > 4) {
			mDrawablePos = 0;
		}
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		final int screenWidth = dm.widthPixels;
		final int screenHeight = dm.heightPixels;
		Bitmap bmp = BitmapFactory.decodeResource(getResources(),
				mScreenDrawable[mDrawablePos]);
		/* Matrix比例 */
		float scaleWidth = ((float) screenWidth) / bmp.getWidth();
		float scaleHeight = ((float) screenHeight) / bmp.getHeight();

		Matrix matrix = new Matrix();
		/* 使用Matrix.postScale设定维度ReSize */
		matrix.postScale(scaleWidth, scaleHeight);

		/* ReSize图文件吹屏幕分辨率 */
		Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
				bmp.getHeight(), matrix, true);
		BitmapDrawable myNewBitmapDrawable = new BitmapDrawable(resizedBitmap);
		mImageView.setImageDrawable(myNewBitmapDrawable);

		/* 使ImageView可见 */
		mImageView.setVisibility(View.VISIBLE);

		/* 每间隔设定秒数置换图片ID,在下一个runnable2才会生效 */
		// 在mTask2中将intDrawable加1,以显示下一张图片
		if (mCounter2 % mSecondsToChange == 0) {
			mDrawablePos++;
		}
	}
	
	private void recoverOriginalLayout(){
		mTextView.setVisibility(View.VISIBLE);
	    mEditText.setVisibility(View.VISIBLE);
	    mImageView.setVisibility(View.GONE);
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (mIsShowingScreenSaver && keyCode != 4) {
			/* 当屏幕保护程序正在执行中,触动解除屏幕保护程序 */
			onUserWakeUpEvent();
		} else {
			/* 更新User未触动手机的时间戳记 */
			updateUserActionTime();
		}
		return super.onKeyDown(keyCode, event);
		
	}

	public void updateUserActionTime() {
		/* 取得按键事件时的系统Time millis */
		Date timeNow = new Date(System.currentTimeMillis());
		mLastUpdateTime.setTime(timeNow.getTime());
	}
	
	private void onUserWakeUpEvent(){
		if(mIsShowingScreenSaver){
			try{
			    resetScreenSaverListener();
			}catch (Exception e){
				e.printStackTrace();
			}
		}
	}
	
	private void resetScreenSaverListener(){
		mMainHandler.removeCallbacks(mMainTask);
		mSwitchImageHandler.removeCallbacks(mSwitchImageTask);
		Date timeNow = new Date(System.currentTimeMillis());
		mLastUpdateTime.setTime(timeNow.getTime());
		
		mIsShowingScreenSaver = false;
		mCounter1 = 0;
		mCounter2 = 0;
		
		recoverOriginalLayout();
		mMainHandler.postDelayed(mMainTask, INTERVAL_KEYPADESAVER);
	}
	
	//当一个touch event事件没有被它下面的任一view处理、或者该事件发生在窗口的边界之外时,会调用该方法。
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		if(mIsShowingScreenSaver){
	        /* 当屏幕保护程序正执行中,触动解除屏幕保护程序 */
	        onUserWakeUpEvent();
	    }else{
	        /* 更新User未触动手机的时间戳记 */
	        updateUserActionTime();
	    }
		return super.onTouchEvent(event);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值