感謝:http://www.cnblogs.com/chenyg32/p/3719714.html
本文是從網上找來的,我自己進行了修改和優化。主要用到了系統的設備管理器,是個可以拋磚引玉的程序。需要說明的是,一旦應用激活了設備管理器,那么在卸載錢必須要取消激活。這點可以用來防止被惡意卸載。
下面開始上代碼:
1.在Manifest中寫上receiver需要設備管理器的方式
<!-- 設備管理 --> <!-- 其中,permission表示此功能所需的權限; android:name="android.app.device_admin"表示這個動作的跳轉界面 --> <receiver android:name=".AdminReceiver" android:label="@string/app_name" android:description="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/lock"/> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/> </intent-filter> </receiver>
其中,resource是說明設備管理器中需要的權限。於是我在xml文件夾中寫上了下面的文件。這里可以有多種權限,設置可以直接進入系統的鎖屏界面。具體自己Google吧
<?xml version="1.0" encoding="UTF-8"?> <device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <uses-policies> <!--強制鎖屏--> <force-lock/> </uses-policies> </device-admin>
這里面定義的receive其實就是繼承了設備管理的廣播類,沒寫代碼
package com.kale.kalelock; import android.app.admin.DeviceAdminReceiver; /** * @author:Jack Tony * @tips :這個類的父類是BroadcastReceiver,通過其OnReceive方法可以根據不同的Action執行不同的動作。 * @date :2014-8-10 */ public class AdminReceiver extends DeviceAdminReceiver{ }
全部的Manifest
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kale.kalelock" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/lock" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 設備管理 --> <!-- 其中,permission表示此功能所需的權限; android:name="android.app.device_admin"表示這個動作的跳轉界面 --> <receiver android:name=".AdminReceiver" android:label="@string/app_name" android:description="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/lock"/> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/> </intent-filter> </receiver> </application> </manifest>
MainActivity
package com.kale.kalelock; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; public class MainActivity extends Activity { /** * DevicePolicyManager 顧名思義,這個類的作用是管理設備。通過這個類,我們可以實現屏幕鎖定、亮度調節甚至是恢復出廠設置等功能。 */ private DevicePolicyManager policyManager; private ComponentName componentName; private static final int MY_REQUEST_CODE = 9999; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 獲取設備管理服務 policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); // ComponentName這個我們在用intent跳轉的時候用到過。 // 自己的AdminReceiver 繼承自 DeviceAdminReceiver componentName = new ComponentName(this, AdminReceiver.class); /* * 假如先判斷是否有權限,如果沒有則調用activeManage(),然后立即鎖屏,最后再finish()。 * 這樣做是有問題的,因為activeManage()可能還在等待另一個Activity的結果,那么此時依然沒有權限卻 * 執行了lockNow(),這樣就出錯了。 處理方法有2個: * 1、是重寫OnActivityResult()函數,在里面判斷是否獲取權限成功,是則鎖屏並finish() * 否則繼續調用activeManage()獲取權限(這樣激活后立即鎖屏,效果很好) * 2、不重寫OnActivityResult()函數,第一次獲取權限后不鎖屏而立即finish(),這樣從理論上說也可能 * 失敗,可能權限還沒獲取好就finish了(這樣激活后就回到桌面,還得再按一次鎖屏才能鎖) 綜上推薦第一種方法。 */ // 判斷是否有鎖屏權限,若有則立即鎖屏並結束自己,若沒有則獲取權限 if (policyManager.isAdminActive(componentName)) { policyManager.lockNow();// 鎖屏 finish(); } else { activeManage(); //獲取權限 } //setContentView(R.layout.activity_main); // 把這句放在最后,這樣鎖屏的時候就不會跳出來(閃一下) } /** * 獲取權限 */ private void activeManage() { // 啟動設備管理(隱式Intent) - 在AndroidManifest.xml中設定相應過濾器 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); // 權限列表 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); // 描述(additional explanation) 在申請權限時出現的提示語句 intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "激活后就能一鍵鎖屏了"); startActivityForResult(intent, MY_REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // 獲取權限成功,立即鎖屏並finish自己,否則繼續獲取權限 if (requestCode == MY_REQUEST_CODE && resultCode == Activity.RESULT_OK) { policyManager.lockNow(); finish(); } else { //activeManage(); finish(); } super.onActivityResult(requestCode, resultCode, data); } }
原文中有閃屏的解決辦法,我這里直接設置Acitvity沒有布局文件,並且在Manifest中的Application標簽下寫了如下主題:
android:theme="@android:style/Theme.Translucent" >
原文的解決辦法如下:
而最難的部分在於,當打開軟件的時候,該軟件會出現閃屏(閃現標題欄),然后才鎖屏。
一個比較好的解決方法是把該Activity設置為透明的,這樣即使出現標題欄也看不到。
網上大部分代碼是這樣解決的,在配置文件中,為Activity標簽添加一個屬性android:theme=@android:style/Theme.Translucent
但是由於我新建項目的時候為該項目選擇了系統自帶的主題(Theme.AppCompat.Light.DarkActionBar),所以配置文件中,Application標簽已經聲明了主題(見下圖),如果繼續在Activity中添加主題的話會運行出錯!
OK,那我把Application的主題刪了,只為Activity配置透明主題行了吧………………可是還是運行出錯!沒深入研究過Android,所以不知怎么會這樣……
最后磕磕碰碰,摸索出一個方法,修改Application的主題,添加下面2句(只添加1句透明的應該也行,沒試過)
至此,終於不再閃屏了……
源碼下載:http://download.csdn.net/detail/shark0017/7778991