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

深入理解 Android 中的 KeyguardManager 是 Android 系统中管理锁屏界面的核心服务,提供了丰富的 API 供开发者与锁屏界面进行交互。通过,开发者可以检查锁屏状态、请求用户解锁设备、临时禁用锁屏以及检查设备是否设置了锁屏密码等功能。在实际开发中,合理使用可以显著提升应用的安全性和用户体验。希望本文的分析能够帮助开发者更好地理解和使用,从而开发出更加安全、高效的 Android 应用。 阅读详情

 前阵子收到客户要求,要做一款安卓手机和平板上使用的屏保,其实蛮奇怪的,电脑用屏保倒是见得多了,可是手机不使用的时候关掉屏幕不就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这部分之前用到过,不在详述,这次把这部分单独写成一个工具类,简化代码

[java]  view plain copy
  1. package com.eyu.screen.util;  
  2.   
  3. import android.content.Context;  
  4. import android.os.PowerManager;  
  5. import android.os.PowerManager.WakeLock;  
  6.   
  7. public class PowerManagerWakeLock {  
  8.   
  9.     private static WakeLock wakeLock;  
  10.       
  11.     /**开启 保持屏幕唤醒*/  
  12.     public static void acquire(Context context) {  
  13.         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
  14.         wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE, "PowerManagerWakeLock");  
  15.         wakeLock.acquire();  
  16.     }  
  17.       
  18.     /**关闭 保持屏幕唤醒*/  
  19.     public static void release() {         
  20.         if (wakeLock != null) {  
  21.             wakeLock.release();  
  22.             wakeLock = null;  
  23.         }  
  24.     }  
  25. }  


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

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

 

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

                                                

                                                      

 

Service的代码:

[java]  view plain copy
  1. package com.eyu.screen.UI;  
  2.   
  3. import com.eyu.screen.util.PowerManagerWakeLock;  
  4. import android.app.KeyguardManager;  
  5. import android.app.Service;  
  6. import android.content.BroadcastReceiver;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.content.IntentFilter;  
  10. import android.os.IBinder;  
  11.   
  12. public class ScreenSaverS extends Service {  
  13.   
  14.     @Override  
  15.     public IBinder onBind(Intent intent) {  
  16.         // TODO Auto-generated method stub  
  17.         return null;  
  18.     }  
  19.   
  20.     public void onCreate() {  
  21.         // 屏蔽系统的屏保  
  22.         KeyguardManager manager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);  
  23.         KeyguardManager.KeyguardLock lock = manager  
  24.                 .newKeyguardLock("KeyguardLock");  
  25.         lock.disableKeyguard();  
  26.   
  27.         // 注册一个监听屏幕开启和关闭的广播  
  28.         IntentFilter filter = new IntentFilter();  
  29.         filter.addAction(Intent.ACTION_SCREEN_ON);  
  30.         filter.addAction(Intent.ACTION_SCREEN_OFF);  
  31.         registerReceiver(screenReceiver, filter);  
  32.     }  
  33.   
  34.     BroadcastReceiver screenReceiver = new BroadcastReceiver() {  
  35.   
  36.         @Override  
  37.         public void onReceive(Context context, Intent intent) {  
  38.             // TODO Auto-generated method stub  
  39.             String action = intent.getAction();  
  40.             if (action.equals(Intent.ACTION_SCREEN_ON)) {  
  41.   
  42.             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {//如果接受到关闭屏幕的广播  
  43.                 if (!ScreenSaverShowA.isShow) {  
  44.                     //开启屏幕唤醒,常亮  
  45.                     PowerManagerWakeLock.acquire(ScreenSaverS.this);  
  46.                 }  
  47.                 PowerManagerWakeLock.acquire(ScreenSaverS.this);  
  48.                 Intent intent2 = new Intent(ScreenSaverS.this,  
  49.                         ScreenSaverShowA.class);  
  50.                 intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  51.                 startActivity(intent2);  
  52.                 PowerManagerWakeLock.release();  
  53.             }  
  54.         }  
  55.     };  
  56.   
  57.     public void onDestroy() {  
  58.         PowerManagerWakeLock.release();  
  59.         unregisterReceiver(screenReceiver);  
  60.   
  61.     };  
  62.   
  63. }  

 

屏保展示页面代码:

[java]  view plain copy
  1. <span style="font-size:12px;">package com.eyu.screen.UI;  
  2.   
  3. import java.io.File;  
  4. import java.util.Timer;  
  5. import java.util.TimerTask;  
  6.   
  7. import com.eyu.screen.R;  
  8. import com.eyu.screen.adapter.ScreenSaverShowAdapter;  
  9. import com.eyu.screen.util.FolderUtil;  
  10.   
  11. import android.annotation.SuppressLint;  
  12. import android.app.Activity;  
  13. import android.graphics.Bitmap;  
  14. import android.graphics.BitmapFactory;  
  15. import android.graphics.drawable.Drawable;  
  16. import android.os.Bundle;  
  17. import android.os.Handler;  
  18. import android.os.Message;  
  19. import android.support.v4.view.ViewPager;  
  20. import android.util.Log;  
  21. import android.view.View;  
  22. import android.view.View.OnClickListener;  
  23.   
  24. @SuppressLint("HandlerLeak")  
  25. public class ScreenSaverShowA extends Activity {  
  26.     public static boolean isShow = false;  
  27.     private ViewPager viewPager;  
  28.     private Bitmap[] bmps = null;  
  29.     private Drawable[] drawables = new Drawable[5];  
  30.   
  31.     @Override  
  32.     protected void onCreate(Bundle savedInstanceState) {  
  33.         // TODO Auto-generated method stub  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.screenshow);  
  36.         isShow = true;  
  37.         initControl();  
  38.         autoSwitch();  
  39.     }  
  40.   
  41.     @Override  
  42.     protected void onDestroy() {  
  43.         // TODO Auto-generated method stub  
  44.   
  45.         isShow = false;  
  46.         //将bitmap回收,尽量避免OOM  
  47.         if (bmps != null) {  
  48.             for (int i = 0; i < bmps.length; i++) {  
  49.                 bmps[i].recycle();  
  50.             }  
  51.         } else {  
  52.             return;  
  53.         }  
  54.         super.onDestroy();  
  55.   
  56.     }  
  57.   
  58.     private void initControl() {  
  59.         findViewById(R.id.btn_jiesuo).setOnClickListener(new OnClick());  
  60.         viewPager = (ViewPager) findViewById(R.id.viewpager);  
  61.         File f = new File(FolderUtil.getSaveFolder());  
  62.         File[] files = f.listFiles();// 得到所有子目录  
  63.         bmps = new Bitmap[files.length];  
  64.           
  65.         //如果文件夹为空,则从资源文件加载图片  
  66.         if (files.length == 0) {  
  67.             drawables[0] = getResources().getDrawable(R.drawable.bg_01);  
  68.             drawables[1] = getResources().getDrawable(R.drawable.bg_02);  
  69.             drawables[2] = getResources().getDrawable(R.drawable.bg_03);  
  70.             drawables[3] = getResources().getDrawable(R.drawable.bg_04);  
  71.             drawables[4] = getResources().getDrawable(R.drawable.bg_05);  
  72.             ScreenSaverShowAdapter adapter = new ScreenSaverShowAdapter(  
  73.                     ScreenSaverShowA.this, drawables);  
  74.             viewPager.setAdapter(adapter);  
  75.         } else {  
  76.             //文件夹不为空则循环遍历加载sd卡指定目录中图片  
  77.             for (int i = 0; i < files.length; i++) {  
  78.                 String path = files[i].getAbsolutePath();  
  79.                 bmps[i] = BitmapFactory.decodeFile(path);  
  80.                 Log.d("PDA", "====H===" + path);  
  81.   
  82.             }  
  83.             ScreenSaverShowAdapter adapter = new ScreenSaverShowAdapter(  
  84.                     ScreenSaverShowA.this, bmps);  
  85.             viewPager.setAdapter(adapter);  
  86.   
  87.         }  
  88.   
  89.     }  
  90.   
  91.     /** 图片定时自动切换 */  
  92.     private void autoSwitch() {  
  93.         int interval = 3000;  
  94.         Timer timer = new Timer();  
  95.         TimerTask task = new TimerTask() {  
  96.   
  97.             @Override  
  98.             public void run() {  
  99.                 // TODO Auto-generated method stub  
  100.                 Message message = new Message();  
  101.                 handler.sendMessage(message);  
  102.             }  
  103.         };  
  104.         timer.schedule(task, interval, interval);  
  105.     }  
  106.   
  107.     Handler handler = new Handler() {  
  108.   
  109.         @Override  
  110.         public void handleMessage(Message msg) {  
  111.             int currentPage = viewPager.getCurrentItem();  
  112.             int tempNum = bmps.length == 0 ? drawables.length : bmps.length;  
  113.             int nextPage = (currentPage + 1) % tempNum;  
  114.             viewPager.setCurrentItem(nextPage);  
  115.             super.handleMessage(msg);  
  116.         }  
  117.   
  118.     };  
  119.   
  120.     class OnClick implements OnClickListener {  
  121.   
  122.         @Override  
  123.         public void onClick(View v) {  
  124.             // TODO Auto-generated method stub  
  125.             ScreenSaverShowA.this.finish();  
  126.         }  
  127.   
  128.     }  
  129. }  
  130. </span>  



 

总结和注意:

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

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

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


Android调用密码锁屏校验 1:获取manager KeyguardManager mKeyguardMgr = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mKeyguardMgr = getSystemService(KeyguardManager.class); } 2:创建intent /** * 跳转锁屏密码校验页面 */ @RequiresApi(api = Buil 阅读详情

相关推荐

Andorid之KeyguardManager的介绍

android.app.KeyguardManager类用于对Keyguard进行管理,即对锁屏进行管理。 详细信息参考: http://blog.youkuaiyun.com/hudashi/article/details/7073373 下面的代码用来设定键盘锁和解锁 //声明键盘管理器并获取键盘的服务 KeyguardManager keyguardManager = (Keyguar

码莎拉蒂 3242

KeyguardManager介绍

目录 1.Manager获取方法: 2.方法详解: 3.KeyguardManager方法执行流程图: 4.KeyguardLock中方法执行流程: 5.KeyguardLock的disableKeyguard使用限制: 6.isKeyguardLocked注意项: 7.DISABLE_KEYGUARD权限的定义: 1.Manager获取方法: import android.a...

闯荡_脚印 4955

云漾AI创作平台实战:如何用GPT4.0+Midjourney快速生成商业级插画(附Prompt模板)

本文详细介绍了如何利用云漾AI创作平台结合GPT4.0和Midjourney快速生成商业级插画。通过智能文案生成与视觉化工作流,大幅提升创作效率,适用于电商、社交媒体等多种场景。文章包含实用Prompt模板和参数调整技巧,帮助设计师和内容创作者高效产出专业插画。

weixin_29251567的博客 217

锁屏解锁-KeyguardManager

判断是否锁屏 KM.isKeyguardLocked() 是否锁屏。不管有没有设置密码 KM.isDeviceLocked() 手机锁屏,且需要密码才能解锁 KM.isKeyguardSecure() 如果锁屏,需要密码(比isDeviceSecure 多了个sim锁)才能解锁。此时也可以没锁屏 KM.isDeviceSecure() 如果锁屏,需要密码才能解锁。此时可以没锁屏。 解锁 KeyguardManager.KeyguardLock.disableKeyguard() 描述: KeygaurdLo

weixin_38854248的博客 5189

C语言 在合并编译 ( 多.c文件 ) 情况下 实现 linked list ( 链表 ) 教程 . 更新ing

写在前面  依旧是参考借鉴了 浙江大学 温老师 的视频教程,很不错,在中国大学MOOC上,强力推荐!  虽说有借鉴,但是能保证的是每一行代码都是我自己经过理解后手敲出来的,所以才来做了这部分的教程。  最后,带 * 字符是我个人觉得可以添加的功能,按理来讲是可以不看的,而且大概率是可以有更好的改进的。  PS: 文章还在更新,如果文字蓝了(有超链接),说明写完了,如果没蓝,说明我在开军舰.jpg 源代码:  这里→源代码. 第一步:前置工作  先说一下每一篇都会出现 main 函数的,stage1 只是给没

weixin_47287635的博客 525

SAR ADC和sigma delta ADC的区别

0、ADC基本概念 ADC,即analog to digital converter,模拟到数字的转换器,简称模数转换器。 为什么需要ADC?因为现实的世界中,电信号是连续的,例如心电信号,或者声音信号,这些连续的信号被称为“模拟信号”。 图1:心电信号 图2:声音信号 然而这种连续的信号是无法被计算机处理的,计算机只认识0和1组成的“数字信号“。ADC就充当了这样一个桥梁,将“模拟信号”转换为计算机能识别的“数字信号”。举个例子,当前的心电电压为1.2V(实际没有这么高),ADC可能会得

长河柱天的博客 2万+
上一篇: android的PowerManager和PowerManager.WakeLock
下一篇: Android中Service类onStartCommand
代号码农
博客等级 码龄16年 5粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值