精華區beta AndroidDev 關於我們 聯絡資訊
有圖網誌有排版好讀版 http://goo.gl/8QyDzd ------ 前言 市面上有許多一鍵鎖屏的軟體,在 Google Play 上可以找到 一堆 https://play.google.com/store/search?q=%E4%B8%80%E9%8D%B5%E9%8E%96%E5%B1%8F 這類型的軟體,不外乎是想要像 iOS 內建的 AssistiveTouch 一樣, 透過點擊螢幕上的 icon 來關掉螢幕,減少電源鍵因為按壓次數過多所導致的損耗! 我們以 一鍵鎖屏 這個 App 為例子 https://play.google.com/store/apps/details?id=wq.lockscreen 當使用者下載了以後,只要放在桌面上的任何位置,如下左圖 第一次點擊時會進到 Android 系統的裝置管理員頁面 讓使用者再次確認此 App 所需要的權限,如下右圖 一旦點選「啟用」以後,下次再次點選就會直接關掉螢幕不會再跳出提示 這種類型的權限通常會比 Market 上的權限還要來的更進階 某些可以取得將整隻手機重設的權限,所以使用上要特別注意! 另一個值得注意的地方,就是當此類型的 App 啟用裝置管理員以後 我們並不能直接將 App 移除! 必須先到 設定 > 安全性 > 裝置管理員 裡頭取消此 App 的勾選 才能夠正常移除! 以下我們就要來實作這樣子一鍵鎖屏的功能! Step 1: 設定 DeviceAdminReceiver deviceAdminReceiver.class 由於會存取到系統的裝置管理員權限, 我們必須透過 DeviceAdminReceiver來幫我們處理 首先先建立一個新的 class deviceAdminReceiver public class deviceAdminReceiver extends DeviceAdminReceiver { } 不要懷疑你的眼睛,裡面不用實作任何東西沒有錯! res/xml/device_admin.xml 接著在 res 資料夾底下新增資料夾 xml 並在 xml 下新增 device_admin.xml 檔 由於我們只需要自動屏的功能, 因此在 user-policies 底下只需要 force-lock 的權限 <device-admin xmlns:Android="http://schemas.android.com/apk/res/android" > <!-- limit-password 設置密碼的規則 watch-login 監控屏幕解鎖嘗試次數 reset-password 更改屏幕解鎖密碼 force-lock 設備自動鎖屏 wipe-data 刪除全部的數據 --> <uses-policies> <force-lock /> </uses-policies> </device-admin> AndroidManifest.xml 記得要在 manifest 底下加入剛才的 deviceAdminReceiver 的資訊 注意在這裡我們加入了 android.permission.BIND_DEVICE_ADMIN 來讓我們取得裝置管理員的資料 <receiver android:name=".deviceAdminReceiver" android:description="@string/description" android:label="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN" > <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver> res/values/strings.xml Receiver 底下可以加入 description 目的只是在裝置管理員底下會出現的文字敘述 這邊不設定也沒有關係 <string name="description">Designed by Kenji Chao</string> Step 2: Activity 設定 LockScreenAndOffActivity 在你的 launch activity 一開始加入以下兩行 REQUEST_CODE 是之後在接 onActivityResult 所需要的常數 devicePolicyManager 是實際上執行鎖屏的實體 private final int REQUEST_CODE = 100; DevicePolicyManager devicePolicyManager; 接著修改onCreate 記住這邊我們並不需要一個 UI 介面來操作我們的 Activity 所以可以不用 setContentView 我們先判斷裝置管理員有沒有被勾選 沒被勾選就使用 intent 導入啟用的頁面 有被勾選直接進行鎖屏,並且關閉這個 Activity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_lock_screen_and_off); ComponentName componentName = new ComponentName(getApplicationContext(), deviceAdminReceiver.class); devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); // 偵測裝置管理員是否被勾選 boolean isAdminActive = devicePolicyManager.isAdminActive(componentName); if (!isAdminActive) { Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "若要解除安裝此程式,請至 設定 > 安全性 > 裝置管理員 內取消此 App 的勾選"); startActivityForResult(intent, REQUEST_CODE); } else { // 鎖屏 devicePolicyManager.lockNow(); finish(); } } 如果只有上面那段程式碼 在第一次啟用時並不會進行鎖屏 所以我們要實作 onActivityResult 利用前面宣告的 REQUEST_CODE 來判斷是從原來的 Activity 發出 intent 回來的 如果使用者確認啟用就執行鎖屏 同樣的最後執行 finish() 來關閉此 Activity protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE) { if (resultCode == RESULT_OK) { devicePolicyManager.lockNow(); } finish(); } } AndroidManifest.xml 最後再做一點細部修改 在 manifest 的 application tag 底下加入這行 讓整個 Application 是不顯示 UI 的 android:theme="@android:style/Theme.NoDisplay" 如果沒有加的話開啟這個 app 會閃一下 代表實際上有開啟 UI 只是馬上又被 finish 了 總結 在這次我們學到了透過 deviceAdminReceiver 來取得更高的使用權限 雖然程式碼不多 但是從這些設定我們仍舊學到了蠻實用的功能! 很簡單吧! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 36.224.175.45 ※ 編輯: punk86862001 來自: 36.224.175.45 (01/15 22:03)
sdyy:原來有nodisplay阿 我以前都是用透明那個 01/15 22:25
sdyy:不過有些系統用locknow會失敗 例如小米... 01/15 22:27
punk86862001:小米機本身有bug...內建的設定應用程式點選有出現 01/15 22:58
punk86862001:...的icon要叫出進階選單時會crash 01/15 22:58
asadman1523:謝謝分享!!!!!! 01/15 23:48
Fonger:推!! 01/15 23:57
ian90911:推分享 01/16 01:22
sorkayi:推分享 01/16 12:24
dementia:推 01/16 15:18
nonebelieve:推! 我以前也做過類似的~ 01/16 17:04
pkmilk:推 01/17 23:05