Android-一个简单的手机屏保程序
本实例实现了一个手机屏保功能,控制和判断用户静止未触动手机键盘或者屏幕的时间及其事件,并且通过动态全屏幕渐入渐出的交换效果。我们以时间戳的方式,判断距离上一次单击键盘或者屏幕的时间,计算两个时间的差值。当超过了设置的时间后,会进入屏保程序。具体实现代码如下:
在activity_main.xml文件中:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:layout_gravity="center"
android:id="@+id/imageview"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textview"
android:visibility="visible"
android:text="就是显示文字"
android:textColor="#66ff0000"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入内容"
android:id="@+id/edittext"/>
接下来在MainActivity声明需要的变量
private ImageView imageView;
private TextView textView;
//LayoutInflater对象,作为新建AlertDialog之用
private LayoutInflater mInflater;
//用mView来输入解锁的View 通过Menu选项identifier 用以表示具体的事件
//输入解锁的View
private View mView01;
private EditText mEditText01,mEditText02;
//Menu选项identifier 用以识别事件
static final private int MENU_ABOUT = Menu.FIRST;
static final private int MENU_EXIT = Menu.FIRST + 1;
private Handler mHandle01 = new Handler();
private Handler mHandle02 = new Handler();
private Handler mHandle03 = new Handler();
private Handler mHandle04 = new Handler();
//分别定义控制user静止与否的Counter,控制FadeIn和FadeOut的Counter,控制循序替换背景图ID的Counter
//控制User静止与否的Counter
private int intCounter1,intCounter2;
//控制FadeIn和FadeOut的Counter,
private int intCounter3,intCounter4;
//控制循序替换背景图ID的Counter
private int intDrawable = 0;
//设置timePeriod,设置当静止超过n秒将自动进入屏幕保护
//上一次user有动作的Time Steamp
private Date lastUpdateTime;
//计算User共几秒没有动作
private long timePeriod;
//静止超过n秒将自动进入屏幕保护
private float fHoldStillSecond = (float)5;
private boolean bIfRunScreenSaver;
private boolean bFadeFlagOut,bfadeFlagIn = false;
private long intervarScreenSaver = 1000;
private long intervarKeypadeSaver = 1000;
private long intervarFade = 100;
private int screenWidth,screenHeight;
//设置每5秒置换图片 用Screen Saver保存需要用到的背景图
//置换间隔
private int intSecondToChange = 5;
//设置Screen Saver用到的背景图
private static int[] screenDrawable = new int[]{
R.drawable.user,
R.drawable.two,
R.drawable.three,
R.drawable.four
};
设置在setContentView之前调用全屏幕显示,通过lastUpdateTime初始取得User触摸手机的时间,并用recorverOriginalLayout()来初始化Layou上的idget可见性
@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);
textView = (TextView) findViewById(R.id.textview);
imageView = (ImageView) findViewById(R.id.imageview);
mEditText01 = (EditText) findViewById(R.id.edittext);
//初始失去的用户触摸手机的时间
lastUpdateTime = new Date(System.currentTimeMillis());
recorverOriginalLayout();
}
设置menu群组ID 然后通过menu.add创建具有subMenu的Menu
public boolean onCreateOptionsMenu(Menu menu){
int idGroup1 = 0;
int orderMenuItem1 = Menu.NONE;
int orderMenuItem2 = Menu.NONE + 1;
menu.add(idGroup1,MENU_ABOUT,orderMenuItem1,"呵呵");
menu.add(idGroup1,MENU_EXIT,orderMenuItem2,"退出");
menu.setGroupCheckable(idGroup1,true,true);
return super.onCreateOptionsMenu(menu);
}
根据用户选择的Menu选项显示对应的AlertDialog提示框
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case MENU_ABOUT:
new AlertDialog.Builder(MainActivity.this).setTitle("嘎嘎嘎嘎").setIcon(R.drawable.user1).setMessage("message内容啊")
.setPositiveButton("好的", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).show();
break;
case MENU_EXIT:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
用mTasks监控User没有动作的运行线程,通过timePeroid计算User静止不动的时间间距, 如果静止不动 超过设置的时间5秒,则运行对应的线程
private Runnable mTasks = new Runnable() {
@Override
public void run() {
intCounter1 ++;
// 计算用户静止不动作的时间间隔
Date timeNew = new Date(System.currentTimeMillis());
timePeriod = (long)timeNew.getTime() - (long)lastUpdateTime.getTime();
float timePeriodSecond = ((float)timePeriod / 1000);
//如果超过时间静止不动
if (timePeriodSecond > fHoldStillSecond){
//如果超过时间静止不动
if (bIfRunScreenSaver == false){
//启动运行线程2
mHandle02.postDelayed(mTasks02,intervarScreenSaver);
if (intCounter1 % (intSecondToChange) == 0){
bFadeFlagOut = true;
mHandle03.postDelayed(mTasks03,intervarFade);
}else {
if (bFadeFlagOut == true){
bfadeFlagIn = true;
mHandle04.postDelayed(mTasks04,intervarFade);
}else{
bfadeFlagIn = false;
intCounter4 = 0;
mHandle04.removeCallbacks(mTasks04);
}
intCounter3 = 0;
bFadeFlagOut = false;
}
bIfRunScreenSaver = true;
}else {
//screen save正在进行中
if (intCounter1 % (intSecondToChange) == 0){
bFadeFlagOut = true;
mHandle03.postDelayed(mTasks03,intervarFade);
}else {
if (bFadeFlagOut == true){
bfadeFlagIn = true;
mHandle04.postDelayed(mTasks04,intervarFade);
}else {
bfadeFlagIn = false;
intCounter4 = 0;
mHandle04.removeCallbacks(mTasks04);
}
intCounter3 = 0;
bFadeFlagOut = false;
}
}
}else {
//当User没有动作的间距未超过时间
bIfRunScreenSaver = false;
//回复原来的Layout Visible
recorverOriginalLayout();
}
//以Logcat监看User静止不动的时间间距
Log.i("HIPPO","Counter1:"+Integer.toString(intCounter1)+"/"+Float.toString(timePeriodSecond));
mHandle01.postDelayed(mTasks,intervarKeypadeSaver);
}
};
使用mTasks02设置每一秒运行一次屏保程序,隐藏原有的Layout上面的Widget, 并调用ScreenSaver()加载图片 即轮换显示预设的图片
private Runnable mTasks02 = new Runnable() {
@Override
public void run() {
if (bIfRunScreenSaver == true){
intCounter2++;
hideOriginallayout();
showScreenSaver();
mHandle02.postDelayed(mTasks02,intervarScreenSaver);
}else {
mHandle02.removeCallbacks(mTasks02);
}
}
};
定义mTasks03 通过setAlpha设置ImageView的透明度渐暗下去
private Runnable mTasks03 = new Runnable() {
@Override
public void run() {
if (bIfRunScreenSaver == true && bFadeFlagOut == true ){
intCounter3++;
imageView.setAlpha(255-intCounter3*28);
Log.i("HIPPO","Fade Out:"+Integer.toString(intCounter3));
mHandle03.postDelayed(mTasks03,intervarFade);
}else {
mHandle03.removeCallbacks(mTasks03,intervarFade);
}
}
};
定义mTasks04 通过setAlpha设置ImageView的透明度渐亮起来
private Runnable mTasks04 = new Runnable() {
@Override
public void run() {
if (bIfRunScreenSaver == true && bfadeFlagIn == true){
intCounter4++;
imageView.setAlpha(intCounter4 * 28);
mHandle04.postDelayed(mTasks04,intervarFade);
Log.i("HIPPO","Fade In:"+Integer.toString(intCounter4));
}else {
mHandle04.removeCallbacks(mTasks04,intervarFade);
}
}
};
定义可视性隐藏与恢复方法
//恢复原有的layout的可视性
private void recorverOriginalLayout(){
textView.setVisibility(View.VISIBLE);
mEditText01.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE);
}
//隐藏原有的应用程序里的布局配置组合
private void hideOriginallayout(){
textView.setVisibility(View.INVISIBLE);
mEditText01.setVisibility(View.INVISIBLE);
}
屏保程序的开始
private void showScreenSaver(){
//保护屏幕之后要做的事情写在此
if (intDrawable > 4){
intDrawable = 0;
}
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels;
Bitmap bmp = BitmapFactory.decodeResource(getResources(),screenDrawable[intDrawable]);
//使用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 resizeBitmap = Bitmap.createBitmap(
bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true
);
//新建Drawable放大图文件至全屏幕
BitmapDrawable myNewBitmapDrawable = new BitmapDrawable(resizeBitmap);
imageView.setImageDrawable(myNewBitmapDrawable);
//是Imageview可见
imageView.setVisibility(View.VISIBLE);
//每间隔设置描述切换图片Id,与下一次runable2才会生效
if (intCounter2 % intSecondToChange == 0){
intDrawable++;
}
}
定义方法onUserWakeUpEvent实现解锁和加密处理
public void onUserWakeUpEvent(){
if (bIfRunScreenSaver == true){
try{
mInflater = LayoutInflater.from(MainActivity.this);
mView01 = mInflater.inflate(R.layout.layout,null);
mEditText02 = (EditText)mView01.findViewById(R.id.edit_text01);
new AlertDialog.Builder(this).setView(mView01)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (mEditText01.getText().toString().equals(mEditText02.getText().toString())){
//比较输入的密码与原Activity的设置是否相等
resetScreenSaverListerner();
}
}
}).show();
}catch (Exception e){
e.printStackTrace();
}
}
}
定义updateUserActionTime(),用于统计用户单击键盘或者屏幕的时间间隔,首先取得点击按钮事件时的系统时间TimeMillis,然后重新计算点击按键距离上一次静止的时间间隔。
public void updateUserActionTime(){
//获取点击按键事件的系统 time Millis
Date timeNow = new Date(System.currentTimeMillis());
//重新计算点击按键距离上一次静止的时间间隔
timePeriod = (long)timeNow.getTime() - (long)lastUpdateTime.getTime();
lastUpdateTime.setTime(timeNow.getTime());
}
定义方法resetScreenSaverListerner()来重新设置屏幕
public void resetScreenSaverListerner(){
//删除现有的Runable
mHandle01.removeCallbacks(mTasks);
mHandle02.removeCallbacks(mTasks02);
//取得点击按键时间时的系统时间
Date timeNow = new Date(System.currentTimeMillis());
//重新计算点击按键距离上一次静止时的时间间距
timePeriod = (Long)timeNow.getTime() - (long)lastUpdateTime.getTime();
lastUpdateTime.setTime(timeNow.getTime());
//取消屏幕保护
bIfRunScreenSaver = false;
intCounter1 = 0;
intCounter2 = 0;
//回复原来的layout Visible
recorverOriginalLayout();
//重新postDelayed新的Runnable
mHandle01.postDelayed(mTasks,intervarKeypadeSaver);
}
定义onKeyDown(int keyCode, KeyEvent event)来监听用户的触摸单击事件
public boolean onKeyDown(int keyCode, KeyEvent event){
if (bIfRunScreenSaver == true && keyCode != 4){
//当屏幕保护程序在运行中,触动解除屏幕保护程序
onUserWakeUpEvent();
}else {
//更新User未触动手机的时间戳
updateUserActionTime();
}
return super.onKeyDown(keyCode,event);
}
其它
@Override
public boolean onTouchEvent(MotionEvent event) {
if (bIfRunScreenSaver == true){
onUserWakeUpEvent();
}else {
updateUserActionTime();
}
return super.onTouchEvent(event);
}
@Override
protected void onResume() {
mHandle01.postDelayed(mTasks,intervarKeypadeSaver);
super.onResume();
}
@Override
protected void onPause() {
try{
//删除运行中的线程
mHandle01.removeCallbacks(mTasks);
mHandle02.removeCallbacks(mTasks02);
mHandle03.removeCallbacks(mTasks03);
mHandle04.removeCallbacks(mTasks04);
}catch (Exception e){
e.printStackTrace();
}
super.onPause();
}