开发环境为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();
}
}
1.Demo下载地址
屏保Activity:
全局屏保实现思路:首先你要用service和广播来做开机启动,困难的就是要监听用户操作,只要有用户操作设备就要重置锁屏计时器,把你的锁屏计时器等一些操作放在service后台运行,做一下保活防止被杀死,至于监听用户的操作,由于是操作的别的app,只能通过Android设备的自动锁屏,拦截系统的自动锁屏跳出我们自己的屏保,两篇文章请参考:http://www.jb51.net/article/97067.htm 和 http://blog.youkuaiyun.com/mengweiqi33/article/details/18094221