美文网首页Android开发Android技术知识Android开发
Android-一个简单的手机屏保程序

Android-一个简单的手机屏保程序

作者: 见哥哥长高了 | 来源:发表于2019-07-18 14:53 被阅读27次

    本实例实现了一个手机屏保功能,控制和判断用户静止未触动手机键盘或者屏幕的时间及其事件,并且通过动态全屏幕渐入渐出的交换效果。我们以时间戳的方式,判断距离上一次单击键盘或者屏幕的时间,计算两个时间的差值。当超过了设置的时间后,会进入屏保程序。具体实现代码如下:
    在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();
        }
    

    相关文章

      网友评论

        本文标题:Android-一个简单的手机屏保程序

        本文链接:https://www.haomeiwen.com/subject/tldllctx.html