├── .gitignore ├── LICENSE.md ├── README.md ├── package.json ├── plugin.xml ├── src └── android │ └── com │ └── oddmouse │ └── plugins │ └── LockTask.java └── www └── LockTask.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015 Lindy Roquemore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LockTask 2 | 3 | A Cordova plugin that provides access to Android’s screen pinning APIs. 4 | 5 | ## Installation 6 | 7 | LockTask will only work on Android devices for apps targeting Lollipop (API 21) or above. 8 | 9 | Navigate to your project root and run: 10 | 11 | ```sh 12 | cordova plugin add https://github.com/oddmouse/cordova-plugin-locktask.git 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### startLockTask 18 | 19 | - **successCallback:** [Function optional] - success callback 20 | 21 | - **errorCallback:** [Function(error) optional] - error callback, error message string is passed 22 | 23 | - **className:** [String optional] - DeviceAdminReceiver subclass name if device owner is enabled 24 | 25 | ```js 26 | window.plugins.locktask.startLockTask(successCallback, errorCallback, className); 27 | ``` 28 | 29 | ### stopLockTask 30 | 31 | - **successCallback:** [Function optional] - success callback 32 | 33 | - **errorCallback:** [Function(error) optional] - error callback, error message string is passed 34 | 35 | ```js 36 | window.plugins.locktask.stopLockTask(successCallback, errorCallback); 37 | ``` 38 | 39 | ## Device admin 40 | 41 | If the app is not set up as the device owner, the user will have to accept a prompt when `startLockTask` is called. The user will also be able to unpin the screen with a navigation button combination. With device owner set, there is no prompt and only the app itself can unpin the screen. 42 | 43 | *IMPORTANT: Once set, you cannot unset device owner or uninstall the app without factory resetting the device.* 44 | 45 | There are several ways to set device owner but this is the method that worked for me. 46 | 47 | 1. Enable Developer options on the device by repeatedly tapping `Build number` under `Settings > About Tablet`. 48 | 49 | 1. Check the USB debugging option under `Settings > Developer options`. 50 | 51 | 1. Add a device admin sub class of `DeviceAdminReceiver` next to the project source. (e.g., `platforms/android/src/com/example/package/ExampleAppAdmin.java`) 52 | 53 | ```java 54 | package com.example.package; 55 | import android.app.admin.DeviceAdminReceiver; 56 | public class ExampleAppAdmin extends DeviceAdminReceiver { 57 | // Some code here if you want but not necessary 58 | } 59 | ``` 60 | 61 | 1. Add the receiver to `AndroidManifest.xml` directly below ``, giving it the same name as the `DeviceAdminReceiver` sub class. 62 | 63 | ```xml 64 | 65 | 66 | 67 | 68 | 69 | 70 | ``` 71 | 72 | 1. Declare security policies in `res/xml/device_admin.xml` 73 | 74 | ```xml 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | ``` 88 | 89 | 1. Connect device via USB. 90 | 91 | 1. Install the app to the device. 92 | 93 | 1. Use Android Debug Bridge and Device Policy Manager to set device owner. 94 | 95 | ```sh 96 | adb shell 97 | dpm set-device-owner com.example.package/.ExampleAppAdmin 98 | ``` 99 | 100 | 1. All done! 101 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-locktask", 3 | "version": "1.0.0", 4 | "description": "A Cordova plugin that provides access to Android’s screen pinning APIs.", 5 | "cordova": { 6 | "id": "cordova-plugin-locktask", 7 | "platforms": [ 8 | "android" 9 | ] 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://oddmouse@github.com/oddmouse/cordova-plugin-locktask.git" 14 | }, 15 | "keywords": [ 16 | "cordova-android", 17 | "cordova", 18 | "ecosystem:cordova", 19 | "locktask", 20 | "screen pinning" 21 | ], 22 | "author": "Lindy Roquemore", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/oddmouse/cordova-plugin-locktask/issues" 26 | }, 27 | "homepage": "https://github.com/oddmouse/cordova-plugin-locktask#readme" 28 | } 29 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | LockTask 7 | A Cordova plugin that provides access to Android’s screen pinning APIs. 8 | cordova,android,screen pinning,startLockTask,stopLockTask,lollipop,api 21 9 | MIT 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/android/com/oddmouse/plugins/LockTask.java: -------------------------------------------------------------------------------- 1 | package com.oddmouse.plugins; 2 | 3 | import android.app.Activity; 4 | import android.app.ActivityManager; 5 | import android.app.admin.DevicePolicyManager; 6 | import android.content.ComponentName; 7 | import android.content.Context; 8 | 9 | import org.apache.cordova.CordovaPlugin; 10 | import org.apache.cordova.CallbackContext; 11 | import org.json.JSONArray; 12 | import org.json.JSONException; 13 | 14 | public class LockTask extends CordovaPlugin { 15 | 16 | private static final String ACTION_START_LOCK_TASK = "startLockTask"; 17 | private static final String ACTION_STOP_LOCK_TASK = "stopLockTask"; 18 | 19 | private Activity activity = null; 20 | 21 | @Override 22 | public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { 23 | 24 | activity = cordova.getActivity(); 25 | ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); 26 | String adminClassName = ""; 27 | 28 | if (args.length() > 0) { 29 | adminClassName = args.getString(0); 30 | } 31 | 32 | try { 33 | if (ACTION_START_LOCK_TASK.equals(action)) { 34 | 35 | if (!activityManager.isInLockTaskMode()) { 36 | 37 | if (!adminClassName.isEmpty()) { 38 | 39 | DevicePolicyManager mDPM = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); 40 | ComponentName mDeviceAdmin = new ComponentName(activity.getPackageName(), activity.getPackageName() + "." + adminClassName); 41 | 42 | if (mDPM.isDeviceOwnerApp(activity.getPackageName())) { 43 | String[] packages = {activity.getPackageName()}; 44 | mDPM.setLockTaskPackages(mDeviceAdmin, packages); 45 | } 46 | 47 | } 48 | 49 | activity.startLockTask(); 50 | } 51 | 52 | callbackContext.success(); 53 | 54 | return true; 55 | 56 | } else if (ACTION_STOP_LOCK_TASK.equals(action)) { 57 | 58 | if (activityManager.isInLockTaskMode()) { 59 | activity.stopLockTask(); 60 | } 61 | 62 | callbackContext.success(); 63 | return true; 64 | 65 | } else { 66 | 67 | callbackContext.error("The method '" + action + "' does not exist."); 68 | return false; 69 | 70 | } 71 | } catch (Exception e) { 72 | 73 | callbackContext.error(e.getMessage()); 74 | return false; 75 | 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /www/LockTask.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | startLockTask: function (successCallback, errorCallback, adminClassName) { 3 | if (adminClassName == null) { 4 | adminClassName = ''; 5 | } 6 | cordova.exec(successCallback, errorCallback, "LockTask", "startLockTask", [adminClassName]); 7 | }, 8 | stopLockTask: function (successCallback, errorCallback) { 9 | cordova.exec(successCallback, errorCallback, "LockTask", "stopLockTask", []); 10 | } 11 | }; 12 | --------------------------------------------------------------------------------