1. 程式人生 > >Android APP一段時間無操作顯示屏保

Android APP一段時間無操作顯示屏保

     開發環境為eclipse,因為demo簡單就沒有使用android studio,android studio每次執行都要gradle編譯一次,速度慢。 

     專案需要,做了一個Android TV 視訊播放器的屏保,大概的需求就是app在沒有播放視訊的情況了五分鐘沒有操作就跳出屏保,屏保接入廣告系統。我下面給出的例子demo在時間超時的時候會跳出螢幕,在接收到鎖屏廣播的時候也會顯示屏保。

     主要講一下使用雙執行緒來實現五分鐘無操作跳出屏保,可以在application裡面啟動監聽執行緒,也可以在activity的oncreated方法裡面啟動監聽,下面是雙執行緒實現的屏保:

package com.example.screensaverdemo;

import java.util.Date;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
/**
 * 
 * @author Danxingxi created on 2015/11/29
 *
 */
public class MainActivity extends Activity {

	private Handler mHandler01 = new Handler();
	private Handler mHandler02 = new Handler();
	
	/* 上一次User有動作的Time Stamp */
	private Date lastUpdateTime;
	/* 計算User有幾秒沒有動作的 */
	private long timePeriod;
	
	/* 靜止超過N秒將自動進入屏保 */
	private float mHoldStillTime = 10;
	/*標識當前是否進入了屏保*/
	private boolean isRunScreenSaver;
    
	/*時間間隔*/
	private long intervalScreenSaver = 1000;
	private long intervalKeypadeSaver = 1000;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		((Button)findViewById(R.id.start_screen_Saver)).setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent mService = new Intent(MainActivity.this, ScreenService.class);
				mService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				startService(mService);
			}
		});
		
		/* 初始取得User可觸碰螢幕的時間 */
		lastUpdateTime = new Date(System.currentTimeMillis());
	}
	
	/**
	 * 計時執行緒
	 */
	private Runnable mTask01 = new Runnable() {
		
		@Override
		public void run() {
			Date timeNow = new Date(System.currentTimeMillis());
			/* 計算User靜止不動作的時間間距 */
			/**當前的系統時間 - 上次觸控式螢幕幕的時間 = 靜止不動的時間**/
			timePeriod = (long) timeNow.getTime() - (long) lastUpdateTime.getTime();
			
			/*將靜止時間毫秒換算成秒*/
			float timePeriodSecond = ((float) timePeriod / 1000);
			
			if(timePeriodSecond > mHoldStillTime){
				if(isRunScreenSaver == false){  //說明沒有進入屏保
					/* 啟動執行緒去顯示屏保 */
					mHandler02.postAtTime(mTask02, intervalScreenSaver);
					/*顯示屏保置為true*/
					isRunScreenSaver = true;
				}else{
					/*屏保正在顯示中*/
				}
			}else{
				/*說明靜止之間沒有超過規定時長*/
				isRunScreenSaver = false;
			}
			/*反覆呼叫自己進行檢查*/
			mHandler01.postDelayed(mTask01, intervalKeypadeSaver);	
		}
	};
	
	/**
	 * 持續屏保顯示執行緒
	 */
	private Runnable mTask02 = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (isRunScreenSaver == true) {  //如果屏保正在顯示,就計算不斷持續顯示  
//				hideOriginalLayout();
				showScreenSaver();
				mHandler02.postDelayed(mTask02, intervalScreenSaver);
			} else {
				mHandler02.removeCallbacks(mTask02);  //如果屏保沒有顯示則移除執行緒
			}
		}
	};
	
	/**
	 * 顯示屏保
	 */
	private void showScreenSaver(){
		Log.d("danxx", "顯示屏保------>");
		Intent intent = new Intent(MainActivity.this, ScreenSaverActivity.class);
		startActivity(intent);
		
	}
	
	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		updateUserActionTime();
		return super.dispatchKeyEvent(event);
	}
	
	/*使用者有操作的時候不斷重置靜止時間和上次操作的時間*/
	public void updateUserActionTime() {
		Date timeNow = new Date(System.currentTimeMillis());
		timePeriod = timeNow.getTime() - lastUpdateTime.getTime();
		lastUpdateTime.setTime(timeNow.getTime());
	}
	
	@Override
	protected void onResume() {
		/*activity顯示的時候啟動執行緒*/
		mHandler01.postAtTime(mTask01, intervalKeypadeSaver);
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		/*activity不可見的時候取消執行緒*/
		mHandler01.removeCallbacks(mTask01);
		mHandler02.removeCallbacks(mTask02);
		super.onPause();
	}
	
}

     屏保就是一個新的Activity,我們可以在屏保activity裡接入展示廣告,做任意操作,下面是啟動一個服務,當用戶按鎖屏鍵鎖屏的時候會發送一個廣播,我們在服務中接受到廣播後可以遮蔽系統的鎖屏,顯示我們自己的鎖屏:

package com.example.screensaverdemo;

import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;

public class ScreenService extends Service {
	KeyguardManager mKeyguardManager = null;   
    private KeyguardLock mKeyguardLock = null;  
    BroadcastReceiver mMasterResetReciever;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	 @Override   
	    public void onCreate() { 
	    	 //Log.e("ScreenService","onCreate()");
	        // TODO Auto-generated method stub 
	    	startScreenService();
	        super.onCreate();   
	      }   
	    
     @Override   
     public void onStart(Intent intent, int startId) {  
    	// Log.e("ScreenService","onStart");
        // TODO Auto-generated method stub   
    	 startScreenService();
      }
	     
     private void startScreenService(){
    	 mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);   
         mKeyguardLock = mKeyguardManager.newKeyguardLock("");
         
         
         mKeyguardLock.disableKeyguard();   
         
         //Intent.ACTION_SCREEN_OFF
         mMasterResetReciever = new BroadcastReceiver() {   
             @Override
				public void onReceive(Context context, Intent intent) {   
                 try { 
	                     Intent i = new Intent();   
	                     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
	                     i.setClass(context, ScreenSaverActivity.class);                        
	                     context.startActivity(i); 
                 } catch (Exception e) {                     	
                     Log.i("mMasterResetReciever:", e.toString());   
                 }   
             }   
         };           
       registerReceiver(mMasterResetReciever, new IntentFilter(Intent.ACTION_SCREEN_OFF));   
     }
     
     @Override
 	public void onDestroy() {
 		//Log.e("ScreenService","onDestroy()");
 		super.onDestroy();
 		unregisterReceiver(mMasterResetReciever);  
         ScreenService.this.stopSelf();
     }
}


    屏保Activity:

全域性屏保實現思路:首先你要用service和廣播來做開機啟動,困難的就是要監聽使用者操作,只要有使用者操作裝置就要重置鎖屏計時器,把你的鎖屏計時器等一些操作放在service後臺執行,做一下保活防止被殺死,至於監聽使用者的操作,由於是操作的別的app,只能通過Android裝置的自動鎖屏,攔截系統的自動鎖屏跳出我們自己的屏保,兩篇文章請參考:http://www.jb51.net/article/97067.htm 和 http://blog.csdn.net/mengweiqi33/article/details/18094221