Android APP一段時間無操作顯示屏保
阿新 • • 發佈:2019-01-22
開發環境為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