Android开发Android技术知识Android开发

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

2019-07-18  本文已影响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();
    }
上一篇下一篇

猜你喜欢

热点阅读