实现一个Android锁屏App功能的难点总结

自定义一个漂亮实用的锁屏app,如果能赢得用户的认可,替换系统自带的锁屏,绝对是一个不小的日活入口。这段时间正好总结一下最近调研的Android平台的锁屏app开发中的难点。

一、前言

锁屏的大概实现原理都很简单。监听系统的亮屏广播,在亮屏的时候展示自己的锁屏界面,用户在锁屏界面上进行一系列的动作才能解锁。有的手机启动锁屏界面的过程会很卡,所以会明显看到亮屏之后锁屏界面的启动有延时,因此也可以选择监听系统灭屏的广播,屏幕关掉的时候就将锁屏界面准备好,直接亮屏展示(灭屏后你的app会比较容易被杀死,这点要注意做保活)。

还需要注意,亮屏和灭屏广播,SCREEN_ON/SCREEN_OFF都是只能动态监听的,所以要另开一个Service来注册,这个Service的自启动和保活也要做好。

基本的实现细节就不多讲了,这篇文章只会讲遇到的几个难点。

二、锁屏实现中的难点

1.屏蔽Home键

既然是锁屏界面,当然只能通过界面上的一些滑动或者输入动作来解开锁屏,不能简单的直接被Home键一按,就解开了。从4.0开始,Home直接在framework层就被系统响应到,强退到桌面,第三方应用里已经无法再通过Activity.onKeyDown方法来监听和拦截Home键,尽管还象征性的保留了Home键的KeyCode来向前兼容,但是Home键按下去,并不会回调这个方法。

除了onKeyDown,有没有其他办法监听Home键,有的。前台App退到后台会有广播ACTION_CLOSE_SYSTEM_DIALOGS,收到广播携带的intent之后,解析里面的"reason"参数,就可以知道退出原因是什么了。home键按下后,reason是"homekey",最近任务键按下后,reason是"recentapps"。

这当然不是最终方案,因为有些三星ROM里并不会有这个广播。而且广播的意思只是通知你一下,人家framework层已经把你的应用退回桌面了,你能监听home键,但没有办法拦截home键。也许想到了可以监听到home键的时候,马上把自己的Activity又重新打开展示,我试了一下,home键按下后startActivity会有延时3秒左右,这应该是Google早就想到了我们会这么干,做了这么一个延时方案。

直接拦截行不通了,想想别的路子。按Home键是让系统退回到Launcher(即桌面启动器),那么如果我们的锁屏Activity本身就是Launcher的话,那按Home键不就等于回到我们的锁屏Activity,也就可以阻止它把锁屏Activity关掉了。

怎么把自己的Activity声明为Launcher,在Activity中添加intent-filter:

<intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.HOME" />
 <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

这样,新安装的app会是一个能够作为launcher的app,所以首次按Home键的时候,就会有弹窗提示你选择要进入哪个launcher,选择我们自己的Activity,这样home键就被我们接管了。

不过这样有一个很明显的问题,如果不在我们的锁屏界面按Home键,同样会进入到锁屏Activity。当然,解决的方式也简单,当我们按Home时进入锁屏Activity的onCreate里做一个判断,如果前一个前台Activity是锁屏Activity,那就不用对Home键处理,如果不是锁屏Activity,那就要关闭锁屏Activity,跳到用户真正的桌面启动器去了。真正的桌面启动器是哪一个,我们可以这样来找:

List<String> pkgNamesT = new ArrayList<String>();
List<String> actNamesT = new ArrayList<String>();
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);  
for (int i = 0; i < resolveInfos.size(); i++) {
 String string = resolveInfos.get(i).activityInfo.packageName;
 if (!string.equals(context.getPackageName())) {//自己的launcher不要      
  pkgNamesT.add(string);
  string = resolveInfos.get(i).activityInfo.name;
  actNamesT.add(string);
 }
}

如果实际的launcher只有一个,那直接跳转过去就可以了:

ComponentName componentName = new ComponentName(pkgName, actName);
Intent intent = new Intent();
intent.setComponent(componentName);
context.startActivity(intent);
((Activity) context).finish();

如果手机安装有多个launcher(如360桌面一类的app)就会麻烦一点,需要展示一个列表让用户来选取用哪个launcher,这个在产品形态上可能会让用户觉得有点不解。

现在,如果在其他APP里按一下Home键,会跳到我们的锁屏Activity然后跳转到真正的launcher。这里可能会有Activity闪现一下的场景,影响用户体验。最优的办法其实是另外弄一个Activity来作为Home键跳转的Activity,这个Activity设为透明的,就不会被用户感知。如此,产品形态就变成了,锁屏Activity中按Home键,跳转到透明Activity,跳转回锁屏Activity,相当于Home键无效;其他APP中按Home键,跳转到透明Activity,跳转到真正的桌面。

实现透明的Activity,只需要在xml中声明

android:theme="@android:style/Theme.Translucent.NoTitleBar"

这样的界面是透明的,实际上有占位在屏幕的顶层,所以跳转后记得要finish掉,不然会阻断跳转后的界面的交互。另外,Theme.NoDisplay也能将Activity设置为不可见,而且不占位,但是笔者实现的时候发现,NoDisplay的Activity无法被系统设置为launcher(设置后会弹窗让你重新设置,如此反复)

2.悬浮窗的实现方式

由于受Home键无法直接拦截的限制,Activity实现的锁屏会需要绕较多的路。所以有的锁屏应用会使用悬浮窗来实现,悬浮窗能够无视Home键,在按下home键的时候不会退到后台。所以不需要在home键的问题上纠结。悬浮窗统一由WindowManager来管理,具体的实现比较简单,笔者就不赘述了,有个坑要注意,悬浮窗需要声明权限:

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

有的手机设置里,默认是不给应用授权悬浮窗使用权的,所以应用里还要考虑引导用户授权悬浮窗使用。

此外,有些应急解锁的场景,比如来电接听,闹铃处理,对于Activity实现的锁屏界面,系统会自动把所有的前台Activity隐藏,让用户直接去处理这些场景。但是悬浮窗会盖住场景,所以遇到这些场景,悬浮窗实现的锁屏界面要自己去处理这些特殊场景的自动解锁。

3.禁用系统锁屏

有了自己的锁屏界面,还需要禁用掉系统的锁屏,以免造成用户需要解锁两次的局面。

首先我们需要知道用户是否设置了锁屏,方法如下:

对于API Level 16及以上SDK,可以使用如下方法判断是否有锁:

((KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE)).isKeyguardSecure()

对API Level 15及以下SDK,可以使用反射来判断:

try {
 Class<?> clazz = Class.forName("com.android.internal.widget.LockPatternUtils");
 Constructor<?> constructor = clazz.getConstructor(Context.class);
 constructor.setAccessible(true);
 Object utils = constructor.newInstance(this);
 Method method = clazz.getMethod("isSecure");
 return (Boolean) method.invoke(utils);
}catch (Exception e){
 e.printStackTrace();
}

好了,得知用户设置了系统锁屏,怎么关掉呢?有前人建议了这种方法

KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("");
keyguardLock.disableKeyguard();

需要权限

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

但经笔者测验,这种方法只能禁用滑动锁,如果用户设置的是图案或者PIN的锁的话,是无法直接取消的。禁用掉密码锁或者图案锁是一个很危险的行为,基于此,Google应该是不会把它开放给开发者的,所以现在的锁屏应用的禁用锁的办法,都是直接跳到系统锁屏设置界面,直接引导用户去手动关闭。可以通过如下代码跳到用户锁屏设置界面:

Intent in = new Intent(Settings.ACTION_SECURITY_SETTINGS);
startActivity(in);

这个也会有些许的兼容性问题,比如,360手机的ROM并没有把设置系统锁屏的功能放在安全设置中,所以打开安全设置的界面找不到取消系统锁屏的地方,这个在一众锁屏应用中并没有做兼容。

三、附加功能中的难点

上面的功能都是直接针对锁屏本身的实现来说的。锁屏应用除了本身能够有“锁住屏幕”的功能外,还应该有其他一些漂亮又实用的功能,最起码应该是尽量往系统锁屏的样式上靠拢并发挥,才方便被用户接受。

1.获取通知

新的Notification到来时应该展示在锁屏界面上,所以我们需要对通知栏进行监听。从Android 4.3(api 18)开始,Google给我们提供了一个NotificationListenerService类,第三方应用可以更方便的获得通知栏使用权(Notification Access),当然,这么敏感的权限得要应用自己声明,同时还要引导用户手动授权。如下,建立一个NotificationMonitor类继承于NotificationListenerService,并声明权限:

<service android:name=".NotificationMonitor"
 android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
 <intent-filter>
  <action android:name="android.service.notification.NotificationListenerService" />
 </intent-filter>
</service>

然后同引导用户关闭系统锁屏一样,要引导用户来授权通知栏使用权:

startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));

可以通过如下代码检查到通知栏使用权是否已经拿到:

private boolean isNotificationListenEnabled(){
  String pkgName = getPackageName();
  final String flat = Settings.Secure.getString(getContentResolver(),
    "enabled_notification_listeners");
  if (!TextUtils.isEmpty(flat)) {
   final String[] names = flat.split(":");
   for (int i = 0; i < names.length; i++) {
    final ComponentName cn = ComponentName.unflattenFromString(names[i]);
    if (cn != null) {
     if (TextUtils.equals(pkgName, cn.getPackageName())) {
      return true;
     }
    }
   }
  }
  return false;
 }

拿到通知栏使用权后,系统通知栏的变化就可以在NotificationMonitor里面监听到了:

public class NotificationMonitor extends NotificationListenerService {
 @Override
 public IBinder onBind(Intent intent) {
  // TODO: Return the communication channel to the service.
  return null;
 }

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  return super.onStartCommand(intent,flags,startId);
 }

 //新的Notification到达
 @Override
 public void onNotificationPosted(StatusBarNotification sbn) {
  super.onNotificationPosted(sbn);
 }

 //新的Notification到达,api 21新增
 @Override
 public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
  super.onNotificationPosted(sbn, rankingMap);
 }

 //Notification被移除
 @Override
 public void onNotificationRemoved(StatusBarNotification sbn) {
  super.onNotificationRemoved(sbn);
 }

 //Notification被移除,api 21新增
 @Override
 public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
  super.onNotificationRemoved(sbn, rankingMap);
 }

 //Notification排序变动,api 21新增
 @Override
 public void onNotificationRankingUpdate(RankingMap rankingMap) {
  super.onNotificationRankingUpdate(rankingMap);
 }

 //Service与系统通知栏完成绑定时回调,绑定后才能收到通知栏回调,api 21新增
 @Override
 public void onListenerConnected() {
  super.onListenerConnected();
 }
}

同时,NotificationListenerService还提供了cancelNotification和cancelAllNotification方法,用于移除通知栏的通知,可以很方便的实现在自定义的锁屏界面移除掉通知了。

笔者实现这个类的时候发现了一个坑,所有的代码都是OK的,通知栏使用权也授权了,但是来通知时始终没有回调onNotificationPosted,查问题查了很久,后来看到网上有人遇到同样的问题,另外新建了一个类把代码复制过去,就OK了,这样看来应该是编译器的问题。

获取了通知栏使用权的Service天然就能被保活,如果被杀死,Android系统能够将它重启。所以平时看到一些应用要求获取通知栏使用权时,要注意这类应用会永久驻存后台的。当然,如果这个Service所在进程崩溃达到一定次数的话,Android系统也会灰心,在下次关机重启前不会再将Service重启,所以,开发中最好能将这个Service放在一个轻量独立的进程中。

2.获取HotSeat区快捷方式

桌面快捷方式分为两类,Desktop区,指随着屏幕滚动的那部分,HotSeat区,指放置于桌面底部不随屏幕滚动的部分。用户自定义的HotSeat区里的快捷方式属于常用的应用。如果能够在锁屏界面也添加这部分的快捷启动,会是一个比较友好的功能。这个的主要问题是,怎么获取到HotSeat区的快捷方式呢。

系统快捷方式存储在数据库文件launcher.db中的favorites表中,如图所示:
可以看到有对应的快捷方式的id,title和intent,这个container属性是用来指示所在文件夹的id,然而可以看到有的container为负数。这是为什么,笔者查看了一下Android Launcher相关的源码,找到这么两句:

/**
* The icon is a resource identified by a package name and an integer id.
*/
public static final int CONTAINER_DESKTOP = -100;
public static final int CONTAINER_HOTSEAT = -101;

也就是说,container为-100的是Desktop区的快捷方式,container为-101的正是要找的HotSeat区的快捷方式。

现在知道了快捷方式的存储方式,接下来的问题就是去找launcher.db文件的路径。

在不同版本的Android原生api中,由于默认使用的launcher启动器的包名不一样,launcher.db存储的路径也不一样。

Android API 7及以下:/data/data/com.android.launcher/databases/laucher.db
Android API 8~18:/data/data/com.android.launcher2/databases/laucher.db
Android API 19及以上:/data/data/com.android.launcher3/databases/laucher.db

而对于各式各样的第三方ROM,使用了千奇百怪的laucher包名,这个路径就更乱了:

HTC: /data/data/com.htc.launcher/databases/laucher.db
360: /data/data/net.qihoo360.launcher/databases/laucher.db
华为: /data/data/com.huawei.launcher3/databases/laucher.db
小米: /data/data/com.miui.mihome2/databases/laucher.db
...

当然,我们不会通过直接读取数据库的方式来获取快捷方式的信息,系统自带的laucher会提供ContentProvider给外部读取。避开了对数据库路径做兼容的大坑,转眼就掉进了另一个大坑,通过Provider来读取快捷方式,所需要的权限和URI也需要做兼容。

从快捷方式的存储可见,Android 的碎片化是多么的严重,所以最后笔者决定不再深入去兼容实现,这是得不偿失的行为,有兴趣实现的可以看看这篇文章,判断一个快捷方式是否存在是多么的难:http://www.jianshu.com/p/dc3d...

3.获取壁纸

锁屏界面的背景和手机桌面壁纸保持一致,不至于让用户觉得突兀,这里有两种办法实现获取壁纸。

Activity Style模式

如果是Activity实现的锁屏界面,可以直接设置Activity的theme就可以用壁纸做背景了。

android:theme="@android:style/Theme.Wallpaper.NoTitleBar"

WallPaperManager模式

悬浮窗模式的锁屏界面无法用theme,那么可以通过WallPaperManager来获取壁纸。

// 获取壁纸管理器
WallpaperManager wallpaperManager = WallpaperManager
    .getInstance(this);
// 获取当前壁纸
Drawable wallpaperDrawable = wallpaperManager.getDrawable();
// 将Drawable,转成Bitmap
Bitmap bm = ((BitmapDrawable) wallpaperDrawable).getBitmap();
mRootView.setBackgroundDrawable(new BitmapDrawable(bm));

这种方式在小米等仿iOS的一屏桌面上是OK的,但是在原生Android那样的两屏桌面(快捷方式与全部app分别在不同屏),快捷方式那屏获取的壁纸是一整张大壁纸,而实际laucher显示的是切割后的壁纸。所以以上方式会把尺寸不符的壁纸设为了背景。需要自己去根据laucher的屏数和当前是第几屏来进行切图,laucher的总屏数可以在上述launcher.db里的workspaceScreens表里找到,而具体当前在第几屏是存在launcher app内存实例中的,无法获取。如果真要切的话,建议直接按照屏幕宽高切下整张壁纸的左边一屏就好了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android 自定义控件实现显示文字的功能

    Android 自定义控件实现显示文字的功能 自定义控件-–逐个显示文字 ONE Goal ,ONE Passion ! 前言: 今天要实现的效果时.让我们的文字一个一个显示出来.上效果图吧: 实现原理: 1,拿到要显示的文字. 2,计算文字显示的速率 字体显示的速度 v = 总的字体长度 / 总的显示时间 3,将文字根据速率显示到控件上. 自定义View: public class printTextView extends TextView { /** * 字体显示出来的时间 */ priv

  • Android的ImageButton当显示Drawable图片时就不显示文字

    很多人对 Android提供的ImageButton有个疑问,当显示Drawable图片时就不会再显示文字了,其实解决的方法有三种: 第一种:就是图片中就写入文字,但是这样解决会增加程序体积,同时硬编码方式会影响多国语言的发布. 第二种:解决方法很简单,通过分析可以看到ImageButton的 layout,我们可以直接直接继承,添加一个TextView,对齐方式为右侧即可实现ImageButton支持文字右侧显示. 第三种:更简洁效率的方法:使用Button ,然后设定Button 的 and

  • Android ListView适配器(Adapter)优化方法详解

    Android ListView的优化,在做Android项目的时候,在用到ListView 界面及数据显示,这个时候如果资源过大,对项目来说,用户体验肯定是不好的,这里就对如何优化做了详细介绍: Adapter的作用就是ListView界面与数据之间的桥梁,当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View.想过没有? 在我们的列表有1000000项时会是什么样的?是不是会占用极大的系统资源? ListView的Adapter的作用如下图所示: 先看看下面

  • Android 实现界面刷新的几种方法

    Android 界面刷新 Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用. Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面. 利用Handler刷新界面 实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界

  • Android控件RefreshableView实现下拉刷新

    需求:自定义一个ViewGroup,实现可以下拉刷新的功能.下拉一定距离后(下拉时显示的界面可以自定义任何复杂的界面)释放手指可以回调刷新的功能,用户处理完刷新的内容后,可以调用方法onCompleteRefresh()通知刷新完毕,然后回归正常状态.效果如下: 源代码:RefreshableView(https://github.com/wangjiegulu/RefreshableView) 分析: 我们的目的是不管什么控件,只要在xml中外面包一层标签,那这个标签下面的所有子标签所在的控件

  • Android开发仿咸鱼键盘DEMO(修改版)

    在这里布局我就不贴出来了 /** * 最终被调用的修改价格dialog */ protected void editPriceDialog() { // TODO Auto-generated method stub editPriceView = View.inflate(this, R.layout.dialog_price_input_keyboard, null); priceDialog = new Dialog(this, R.style.contactdialog); priceD

  • Android自定义软键盘的设计与实现代码

    偶然间发现了Android.inputmethodservice.Keyboard类,即android可以自定义键盘类,做了一个简单例子供大家参考. 效果如下: 先看界面布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout

  • Android 自定义View时使用TypedArray配置样式属性详细介绍

     Android 自定义View时使用TypedArray配置样式属性详细介绍 在自定义view时为了提高复用性和扩展性,可以为自定义的view添加样式属性的配置,比如自定义图片资源.文字大小.控件属性等,就这需要用到TypedArray类,下面以一个自定义的可点击扩展和收缩的TextView为例记录下这个类的简单使用. 先上效果图: 点击以后为 再贴代码: 1.自定义view类: /** * @title ExpandTextView * @description 可扩展TextView,可以

  • 实现一个Android锁屏App功能的难点总结

    自定义一个漂亮实用的锁屏app,如果能赢得用户的认可,替换系统自带的锁屏,绝对是一个不小的日活入口.这段时间正好总结一下最近调研的Android平台的锁屏app开发中的难点. 一.前言 锁屏的大概实现原理都很简单.监听系统的亮屏广播,在亮屏的时候展示自己的锁屏界面,用户在锁屏界面上进行一系列的动作才能解锁.有的手机启动锁屏界面的过程会很卡,所以会明显看到亮屏之后锁屏界面的启动有延时,因此也可以选择监听系统灭屏的广播,屏幕关掉的时候就将锁屏界面准备好,直接亮屏展示(灭屏后你的app会比较容易被杀死

  • Python+uiautomator2实现手机锁屏解锁功能

    业务需求:需要测试手机滑动解锁失败时事件的次数及等待的时间,本来想利用Python+Appium实现,但是Appium运行时自动给我解锁了.... 部分解释摘抄自:https://testerhome.com/topics/11357 python-uiautomator2是一个自动化测试开源工具,仅支持Android平台的原生应用测试 python-uiautomator2封装了谷歌自带的uiautomator2测试框架,提供便利的python接口.他允许测试人员直接在PC上编写Python的

  • Android截屏分享功能

    最近项目需要实现Android截屏分享功能,包括Android截屏获取图片.将图片保存到本地.通知系统相册更新.通过微信.QQ.微博分享截屏图片,本篇文章作为总结回顾.     一.Android截屏获取图片 通过对view进行绘制,得到bitmap,可以对Activity.Fragment进行绘制,也可以对其他的View进行绘制.    1 Activity截图(带空白的状态栏) public Bitmap shotScreen(Activity activity) { View view =

  • 轻松实现Android锁屏功能

    锁屏需要引入设备超级管理员.在文档Android开发文档的Administration中有详细的说明.Android设备管理系统功能和控制访问. 主要有一下几个步骤: 1  创建广播接收者,实现DeviceAdminReceiver package com.andy.lockscreen; import android.app.admin.DeviceAdminReceiver; /** * @author Zhang,Tianyou * @version 2014年11月20日 下午9:51:

  • Android实现带页面切换的锁屏功能

    一个简单的Android 锁屏小Demo,可以设置左滑有滑,我简单的了解一下自定义锁屏,顺便总结了一下思路顺便画个图帮助理解. 我的效果图 代码思路 锁屏分为两块,一块是UI(自定义布局)另一块这就是服务了 自定义锁屏布局 ACTION_DOWN按下:中间的ImageView会变成另一种形态 ACTION_MOVE移动: 移动到左/右边,左/右ImageView形态也要发生变化, ACTION_UP抬起:判断滑动到左/右那边,或者回到最初位置 *服务 @Override public void

  • Android屏幕锁屏弹窗的正确姿势DEMO详解

    在上篇文章给大家介绍了Android程序开发仿新版QQ锁屏下弹窗功能.今天通过本文给大家分享android锁屏弹窗的正确姿势. 最近在做一个关于屏幕锁屏悬浮窗的功能,于是在网上搜索了很多安卓屏幕锁屏的相关资料,鉴于网上的资料比较零碎,所以我在这里进行整理总结.本文将从以下两点对屏幕锁屏进行解析: 1. 如何监听系统屏幕锁屏 2. 如何在锁屏界面弹出悬浮窗 如何监听系统屏幕锁屏 经过总结,监听系统的锁屏可以通过以下两种方式: 1) 代码直接判定 2) 接收广播 1) 代码直接判定 代码判断方式,也

  • Android编程之自定义锁屏实例分析

    本文实例讲述了Android编程之自定义锁屏.分享给大家供大家参考,具体如下: 花了半天时间研究下了自定义锁屏,发现其实实现并不是很神秘.不过有些地方还是值得注意. 首先说流程,锁屏界面一般是在关闭屏幕时启用,打开屏幕时展现在我们面前,所以我们知道了锁屏的时机,恰好屏幕开关会发出相应的广播,所以我们也可以像系统一样捕获到屏幕开关的事件. 广播对应的两个action 引用 android.intent.action.SCREEN_ON android.intent.action.SCREEN_OF

  • Android截屏方案实现原理解析

    Android截屏的原理:获取具体需要截屏的区域的Bitmap,然后绘制在画布上,保存为图片后进行分享或者其它用途 在截屏功能中,有时需要截取全屏的内容,有时需要截取超过一屏的内容(比如:Listview,Scrollview,RecyclerView).下面介绍各种场景获取Bitmap的方法 普通截屏的实现 获取当前Window的DrawingCache的方式,即decorView的DrawingCache /** * shot the current screen ,with the sta

  • Qt超时锁屏的实现示例

    概述 Qt实现超时锁屏的功能(工控机触摸屏),当手长时间不触摸屏幕的时候,程序超时会显示锁屏窗口. 效果 主窗口超时显示锁屏窗口: 系统窗口超时显示锁屏窗口: 实现思路 首先开启一个线程用于QTimer定时器计时,最开始进入软件开启定时器计时,超时则显示锁屏窗口:而手触摸屏幕会触发鼠标点击事件,则停止计时:而手离开屏幕会触发鼠标释放事件,则重新开始计时. 因为是多窗口的应用软件,所以需要监控全局鼠标事件,所以需要子类化QApplication类. 核心代码 监控全局鼠标事件的类为GlobalAp

  • Android 仿小米锁屏实现九宫格解锁功能(无需图片资源)

    最近公司要求做个九宫格解锁,本人用的是小米手机,看着他那个设置锁屏九宫格很好看,就做了该组件,不使用图片资源,纯代码实现. 尊重每个辛苦的博主,在http://blog.csdn.net/mu399/article/details/38734449的基础上进行修改 效果图: 关键代码类: MathUtil.Java /** * @author SoBan * @create 2016/12/5 15:52. */ public class MathUtil { public static dou

随机推荐