锁屏流程如下(参考于Android一键锁屏开发全过程【源码】【附图】)
源码参考于一键锁屏 源码
一共有2个Java文件:
1 package com.example.onekeylock.app; 2 3 import android.app.admin.DeviceAdminReceiver; 4 5 public class AdminReceiver extends DeviceAdminReceiver{}
1 package com.example.onekeylock.app; 2 3 import android.app.Activity; 4 import android.app.admin.DevicePolicyManager; 5 import android.content.ComponentName; 6 import android.content.Context; 7 import android.content.Intent; 8 import android.os.Bundle; 9 import android.support.v7.app.ActionBarActivity; 10 11 public class MainActivity extends ActionBarActivity 12 { 13 private DevicePolicyManager policyManager; 14 private ComponentName componentName; 15 private static final int MY_REQUEST_CODE = 9999; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) 19 { 20 super.onCreate(savedInstanceState); 21 //获取设备管理服务 22 policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); 23 componentName = new ComponentName(this, AdminReceiver.class); 24 /* 25 * 假如先判断是否有权限,如果没有则调用activeManage(),然后立即锁屏,再finish()。 26 * 这样做是有问题的,因为activeManage()可能还在等待另一个Activity的结果,那么此时依然没有权限却 27 * 执行了lockNow(),这样就出错了。 28 * 处理方法有2个: 29 * 1、是重写OnActivityResult()函数,在里面判断是否获取权限成功,是则锁屏并finish() 30 * 否则继续调用activeManage()获取权限(这样激活后立即锁屏,效果很好) 31 * 2、不重写OnActivityResult()函数,第一次获取权限后不锁屏而立即finish(),这样从理论上说也可能 32 * 失败,可能权限还没获取好就finish了(这样激活后就回到桌面,还得再按一次锁屏才能锁) 33 * 综上推荐第一种方法。*/ 34 35 //判断是否有锁屏权限,若有则立即锁屏并结束自己,若没有则获取权限 36 if (policyManager.isAdminActive(componentName)) 37 { 38 policyManager.lockNow(); 39 finish(); 40 } 41 else 42 { 43 activeManage(); 44 } 45 setContentView(R.layout.activity_main); //把这句放在最后,这样锁屏的时候就不会跳出来(闪一下) 46 } 47 48 //获取权限 49 private void activeManage() 50 { 51 // 启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器 52 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 53 54 //权限列表 55 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); 56 57 //描述(additional explanation) 58 intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "激活后才能使用锁屏功能哦亲^^"); 59 60 startActivityForResult(intent, MY_REQUEST_CODE); 61 } 62 63 @Override 64 protected void onActivityResult(int requestCode, int resultCode, Intent data) 65 { 66 //获取权限成功,立即锁屏并finish自己,否则继续获取权限 67 if (requestCode == MY_REQUEST_CODE && resultCode == Activity.RESULT_OK) 68 { 69 policyManager.lockNow(); 70 finish(); 71 } 72 else 73 { 74 activeManage(); 75 } 76 super.onActivityResult(requestCode, resultCode, data); 77 } 78 }
布局文件:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="fill_parent"> 4 </RelativeLayout>
这个是获取权限时显示的权限列表
1 <?xml version="1.0" encoding="UTF-8"?> 2 <device-admin 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 <uses-policies> 7 <!--强制锁屏--> 8 <force-lock/> 9 </uses-policies> 10 </device-admin>
修改原来的styles.xml
1 <resources> 2 <!-- Base application theme. --> 3 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 4 <!-- Customize your theme here. --> 5 <item name="android:windowNoTitle">true</item> 6 <item name="android:windowIsTranslucent">true</item> 7 </style> 8 </resources>
配置文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.onekeylock.app"> 4 <application 5 android:allowBackup="true" 6 android:icon="@drawable/onekeylock" 7 android:label="@string/app_name" 8 android:theme="@style/AppTheme"> 9 <activity 10 android:name="com.example.onekeylock.app.MainActivity" 11 android:label="@string/app_name"> 12 <intent-filter> 13 <action android:name="android.intent.action.MAIN"/> 14 <category android:name="android.intent.category.LAUNCHER"/> 15 </intent-filter> 16 </activity> 17 <receiver 18 android:name=".AdminReceiver" 19 android:label="@string/app_name" 20 android:description="@string/app_name" 21 android:permission="android.permission.BIND_DEVICE_ADMIN"> 22 <meta-data 23 android:name="android.app.device_admin" 24 android:resource="@layout/lock"/> 25 <intent-filter> 26 <action 27 android:name="android.app.action.DEVICE_ADMIN_ENABLED"/> 28 </intent-filter> 29 </receiver> 30 </application> 31 </manifest>
一个Activity,打开来默认是显示它的TitleBar(标题栏)的,而锁屏的原理就是先打开Activity,再启动锁屏功能,最后把自己结束掉。
而最难的部分在于,当打开软件的时候,该软件会出现闪屏(闪现标题栏),然后才锁屏。
一个比较好的解决方法是把该Activity设置为透明的,这样即使出现标题栏也看不到。
网上大部分代码是这样解决的,在配置文件中,为Activity标签添加一个属性android:theme=@android:style/Theme.Translucent
但是由于我新建项目的时候为该项目选择了系统自带的主题(Theme.AppCompat.Light.DarkActionBar),所以配置文件中,Application标签已经声明了主题(见下图),如果继续在Activity中添加主题的话会运行出错!
OK,那我把Application的主题删了,只为Activity配置透明主题行了吧………………可是还是运行出错!没深入研究过Android,所以不知怎么会这样……
最后磕磕碰碰,摸索出一个方法,修改Application的主题,添加下面2句(只添加1句透明的应该也行,没试过)
至此,终于不再闪屏了……