前阵子收到客户要求,要做一款安卓手机和平板上使用的屏保,其实蛮奇怪的,电脑用屏保倒是见得多了,可是手机不使用的时候关掉屏幕不就OK了吗?话说现在的智能手机电池都不耐用的可怜,还装屏保岂不是很费电。原来客户是用于放在营业厅(手机相关),通过手机或者平板来使用相关设备投射到电子屏幕上展示广告的用途,24小时不断电,只是展示用,故电量不作考虑。要求在服务端上传欲展示的图片,PDA上可以进行获取更新图片,只要不断滚动他们的广告就可以了。起初并不是我来做的,同事已经都写的差不多了,他突然有别的项目很急,留给我来做,也好,以前没做过,顺便了解一下android屏保相关的知识,写下来做积累。

-------------------------------------------------------------------------------------------------------

首先接触到了KeyguardManager,用来对系统的屏保进行屏蔽

public class KeyguardManager extends Object

Class that can be used to lock and unlock the keyboard. Get an instance of this class by calling Context.getSystemService(java.lang.String) with argument Context.KEYGUARD_SERVICE. The actual class to control the keyboard locking is KeyguardManager.KeyguardLock.

一个用于锁屏和解锁的类,通过调用Context.getSystemService(Context.KEYGUARD_SERVICE)来获取实例。实际上用于操控锁屏的是KeyguardManager.KeyguardLock类

KeyguardManager 两个内部类分别是:

(1)KeyguardManager.KeyguardLock(l两个函数)

记得加权限

<uses-permission   android:name="android.permission.DISABLE_KEYGUARD"/>

disableKeyguard()函数来解除锁屏

reenableKeyguard()反解除锁屏.reenableKeyguard()反解除锁屏的意思是:如果在调用disableKeyguard()函数之前是锁屏的,那么就进行锁屏,否则不进行任何操作。当然如果之前没调用disableKeyguard()函数,也不进行任何操作。

(2)KeyguardManager.OnKeyguardExitResult(boolean success)  :返回true表示exitKeyguardSecurely()函数执行成功,否则表示失败<具体自己没用到,是个做判断和debug用的吧估计>

-----------------------------------------------------------------------------------------------------

而后用到的是开启和关闭屏幕唤醒的内容,PowerManager和WakeLock这部分之前用到过,不在详述,这次把这部分单独写成一个工具类,简化代码

package com.eyu.screen.util;
import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
public class PowerManagerWakeLock {
private static WakeLock wakeLock;
/**开启 保持屏幕唤醒*/
public static void acquire(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE, "PowerManagerWakeLock");
wakeLock.acquire();
}
/**关闭 保持屏幕唤醒*/
public static void release() {
if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}
}
}

-------------------------------------------------------------------------------------------------------------------------------------------

其实最主要的应该就是上面的内容,后续就是编写Service和发送广播的操作,并实现和服务端的通信。

做完之后抛开服务端和下载更新的内容,自己做了一个单机用的留底,基本思路和操作与公司项目的一致,只是图片需要手动添加而已,使用后会一直监听屏幕的状态,一旦屏幕灭掉会立刻唤醒,使用viewpager和定时器来控制图片自动的翻页,想彻底停掉就需要断掉后台的service,下面是小程序的截图,启动后会先做判断,如果sd卡指定目录没有图片的话,则加载资源文件,有图片加载SD卡中的。

                                                

                                                      

Service的代码:

package com.eyu.screen.UI;
import com.eyu.screen.util.PowerManagerWakeLock;
import android.app.KeyguardManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
public class ScreenSaverS extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onCreate() {
// 屏蔽系统的屏保
KeyguardManager manager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock lock = manager
.newKeyguardLock("KeyguardLock");
lock.disableKeyguard();
// 注册一个监听屏幕开启和关闭的广播
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(screenReceiver, filter);
}
BroadcastReceiver screenReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_ON)) {
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {//如果接受到关闭屏幕的广播
if (!ScreenSaverShowA.isShow) {
//开启屏幕唤醒,常亮
PowerManagerWakeLock.acquire(ScreenSaverS.this);
}
PowerManagerWakeLock.acquire(ScreenSaverS.this);
Intent intent2 = new Intent(ScreenSaverS.this,
ScreenSaverShowA.class);
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent2);
PowerManagerWakeLock.release();
}
}
};
public void onDestroy() {
PowerManagerWakeLock.release();
unregisterReceiver(screenReceiver);
};
}

屏保展示页面代码:

package com.eyu.screen.UI;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import com.eyu.screen.R;
import com.eyu.screen.adapter.ScreenSaverShowAdapter;
import com.eyu.screen.util.FolderUtil;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@SuppressLint("HandlerLeak")
public class ScreenSaverShowA extends Activity {
public static boolean isShow = false;
private ViewPager viewPager;
private Bitmap[] bmps = null;
private Drawable[] drawables = new Drawable[5];
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.screenshow);
isShow = true;
initControl();
autoSwitch();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
isShow = false;
//将bitmap回收,尽量避免OOM
if (bmps != null) {
for (int i = 0; i < bmps.length; i++) {
bmps[i].recycle();
}
} else {
return;
}
super.onDestroy();
}
private void initControl() {
findViewById(R.id.btn_jiesuo).setOnClickListener(new OnClick());
viewPager = (ViewPager) findViewById(R.id.viewpager);
File f = new File(FolderUtil.getSaveFolder());
File[] files = f.listFiles();// 得到所有子目录
bmps = new Bitmap[files.length];
//如果文件夹为空,则从资源文件加载图片
if (files.length == 0) {
drawables[0] = getResources().getDrawable(R.drawable.bg_01);
drawables[1] = getResources().getDrawable(R.drawable.bg_02);
drawables[2] = getResources().getDrawable(R.drawable.bg_03);
drawables[3] = getResources().getDrawable(R.drawable.bg_04);
drawables[4] = getResources().getDrawable(R.drawable.bg_05);
ScreenSaverShowAdapter adapter = new ScreenSaverShowAdapter(
ScreenSaverShowA.this, drawables);
viewPager.setAdapter(adapter);
} else {
//文件夹不为空则循环遍历加载sd卡指定目录中图片
for (int i = 0; i < files.length; i++) {
String path = files[i].getAbsolutePath();
bmps[i] = BitmapFactory.decodeFile(path);
Log.d("PDA", "====H===" + path);
}
ScreenSaverShowAdapter adapter = new ScreenSaverShowAdapter(
ScreenSaverShowA.this, bmps);
viewPager.setAdapter(adapter);
}
}
/** 图片定时自动切换 */
private void autoSwitch() {
int interval = 3000;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Message message = new Message();
handler.sendMessage(message);
}
};
timer.schedule(task, interval, interval);
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
int currentPage = viewPager.getCurrentItem();
int tempNum = bmps.length == 0 ? drawables.length : bmps.length;
int nextPage = (currentPage + 1) % tempNum;
viewPager.setCurrentItem(nextPage);
super.handleMessage(msg);
}
};
class OnClick implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ScreenSaverShowA.this.finish();
}
}
}

总结和注意:

1.系统屏保的屏蔽方法以及屏幕唤醒的知识参考API就可以了,比较简单的新知识

2.如果很多张图片来加载的话,很可能出现令人最头疼的OOM,由于屏保就需求全屏显示,所以图片缩放的方式不合适,没想到好办法。不过为了避免反复解锁过程中出现OOM,在onDestroy()方法中对图片进行了recycle。

3.在模拟器上运行没有发现问题,但可能在不同的机型上会出现问题,比如有些手机将安卓的源码改掉了,甚至不允许使用屏蔽系统屏保的方法。还是原生态的android系统最好了,都瞎改什么呢。

Android屏幕保护KeyguardManager相关内容学习相关推荐

  1. linux/android驱动工程师面试相关内容总结

    理论的东西不常用时就会慢慢的被遗忘,但是找工作就是一个如何让别人相信自己的过程,理论知识就是一个非常重要的途径. 一次次机会在错失,每次想找工作时,刷一下简历就去面试了,一次次因为理论被鄙视,也该长长 ...

  2. 音频处理相关内容学习——自动编码器——变分自动编码器——频谱图

    文章目录 概述 一.Approaches And Challenges 生成的声音是什么类型 训练模型使用的是什么特征 原始音频Raw Audio 频谱图Spectrograms 声音生成模型常用的结 ...

  3. Android 屏幕保护程序制作及源码

    首先,需要启动一个后台服务,用于注册一个BroadcastReceiver 这个BroadcastReceiver用于监听Intent.ACTION_SCREEN_OFF 这样在发生这个事件Inten ...

  4. Gazebo相关内容学习

    什么是Gazebo和ros,以及二者的关系? Gazebo是一个不错的仿真工具,它使用物理引擎模拟真实的世界,使得我们可以通过仿真的方式从原理上验证算法,计算负载和受力情况,进而指引我们做结构和算法的 ...

  5. ROS 命令以及相关内容学习(二)

    在上一节中我们已经学习了package node topic message 这些的运行方式,下面我们去理解service 的运行方式. 1.sevice 1 #命令 2 rosservice lis ...

  6. DNS相关内容学习笔记1

    记录dns协议学习中的一些内容,全程无图. 目录 DNS简介 DNS查询过程 DNS缓存 DNS劫持 DoH基本原理 Firefox开启DoH DNS报文格式 DNS几个关键字段 DNS类型字段 DN ...

  7. Maven相关内容学习笔记一:基本配置和使用

    首先必须推荐的这本书<Maven实战> 许晓斌,机械工业出版社 Maven简介 其实使用Maven也有很久时间了,大部分都是别人建好了工程我使用一下,实际上并没有非常详细的使用经验,这次到 ...

  8. C++ const相关内容学习

    const 作用 修饰变量,说明变量不可以被修改 修饰指针,分为指向常量的指针(pointer to const)和自身是常量的指针(常量指针,const pointer) 修饰引用,指向常量的引用( ...

  9. Android开发环境——Eclipse ADT相关内容汇总

     Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...

最新文章

  1. 不断审视自己,做一个长期主义者
  2. labview虚拟心电监测系统_机器视觉系统单相机模型
  3. weex componet 简单扩展
  4. java wait 线程安全吗_Java多线程中的wait与notify
  5. NSNumber, NSValue的使用
  6. (35)FPGA面试题FPGA工程师努力的方向
  7. linux c 运行脚本,linux 将c源代码当作shell一样脚本运行_沃航科技
  8. 选购多媒体音箱常见哪些误区?
  9. jquery操作radio,checkbox
  10. Qt sender()函数
  11. MariaDB 在 RedHat Linux 上的安装过程以及 MySQL 相关命令的使用
  12. 技术干货 | Serverless技术架构——极简运维 无限扩容
  13. 如何搜索你想要的R包?
  14. centos7上克隆虚拟机后设置静态IP无效的解决方法
  15. (二)路径规划算法---C++结合OpenCV实现RRT算法
  16. STM32CubeMx之硬件SPI驱动W25Q64
  17. maya建模模型变黑问题解决
  18. 对软件项目开发的一点思考
  19. 缺陷管理工具大PK:UniPro、Bugzilla和Teambition哪家强
  20. Ubuntu文件管理快捷键

热门文章

  1. shell脚本如何取得当前脚本所在目录
  2. CSS flex-direction用法解释
  3. 三分钟快速安装 facebookresearch SlowFast
  4. 数据采集-呼吸心跳信号检测方法(二)
  5. vue如何在filter中使用this
  6. 破解IT公司高管频繁离职的密码
  7. AttributeError: Layer my_model has no inbound nodes.
  8. facebook语言_如何在Facebook上更改语言设置
  9. 徐无忌MySQL笔记:乐观锁VS悲观锁
  10. linux查看脚本运行进度,实用小脚本: 查看 MLDonkey 下载进度