├── .gitattributes
├── index.js
├── android
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── rnlocktask
│ │ ├── MyAdmin.java
│ │ ├── RNLockTaskPackage.java
│ │ └── RNLockTaskModule.java
└── build.gradle
├── package.json
├── .gitignore
├── LICENSE
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { NativeModules } from 'react-native';
3 |
4 | const { RNLockTask } = NativeModules;
5 |
6 | export default RNLockTask;
7 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/src/main/java/com/rnlocktask/MyAdmin.java:
--------------------------------------------------------------------------------
1 | package com.rnlocktask;
2 |
3 | import android.app.admin.DeviceAdminReceiver;
4 |
5 |
6 | public class MyAdmin extends DeviceAdminReceiver{
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "react-native-lock-task",
4 | "version": "1.4.1",
5 | "description": "",
6 | "main": "index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/fast0490f/react-native-lock-taskt"
13 | },
14 | "license": "MIT",
15 | "keywords": [
16 | "react-native"
17 | ],
18 | "author": ""
19 | }
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # OSX
3 | #
4 | .DS_Store
5 |
6 | # node.js
7 | #
8 | node_modules/
9 | npm-debug.log
10 | yarn-error.log
11 |
12 |
13 | # Xcode
14 | #
15 | build/
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 | xcuserdata
25 | *.xccheckout
26 | *.moved-aside
27 | DerivedData
28 | *.hmap
29 | *.ipa
30 | *.xcuserstate
31 | project.xcworkspace
32 |
33 |
34 | # Android/IntelliJ
35 | #
36 | build/
37 | .idea
38 | .gradle
39 | local.properties
40 | *.iml
41 |
42 | # BUCK
43 | buck-out/
44 | \.buckd/
45 | *.keystore
46 |
--------------------------------------------------------------------------------
/android/src/main/java/com/rnlocktask/RNLockTaskPackage.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rnlocktask;
3 |
4 | import com.facebook.react.ReactPackage;
5 | import com.facebook.react.bridge.JavaScriptModule;
6 | import com.facebook.react.bridge.NativeModule;
7 | import com.facebook.react.bridge.ReactApplicationContext;
8 | import com.facebook.react.uimanager.ViewManager;
9 |
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | public class RNLockTaskPackage implements ReactPackage {
14 | @Override
15 | public List createNativeModules(ReactApplicationContext reactContext) {
16 | return Arrays.asList(new RNLockTaskModule(reactContext));
17 | }
18 |
19 | // Deprecated from RN 0.47
20 | public List> createJSModules() {
21 | return Collections.emptyList();
22 | }
23 |
24 | @Override
25 | public List createViewManagers(ReactApplicationContext reactContext) {
26 | return Collections.emptyList();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Artem Ivanov
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 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | def safeExtGet(prop, fallback) {
4 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
5 | }
6 |
7 | buildscript {
8 | repositories {
9 | google()
10 | }
11 |
12 | dependencies {
13 | classpath("com.android.tools.build:gradle")
14 | }
15 | }
16 |
17 | android {
18 | def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
19 | // Check AGP version for backward compatibility reasons (for RN < 0.71)
20 | if (agpVersion.tokenize('.')[0].toInteger() >= 7) {
21 | namespace "com.rnlocktask"
22 | }
23 |
24 | compileSdkVersion safeExtGet('compileSdkVersion', 35)
25 |
26 | defaultConfig {
27 | minSdkVersion safeExtGet('minSdkVersion', 21)
28 | targetSdkVersion safeExtGet('targetSdkVersion', 35)
29 | versionCode 1
30 | versionName "1.0"
31 | }
32 | lintOptions {
33 | abortOnError false
34 | }
35 | }
36 |
37 | repositories {
38 | mavenCentral()
39 | google()
40 | }
41 |
42 | dependencies {
43 | implementation 'com.facebook.react:react-native:+'
44 | }
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # react-native-lock-task
3 |
4 | ## Getting started
5 |
6 | `$ npm install react-native-lock-task --save`
7 |
8 | ### Mostly automatic installation
9 |
10 | `$ react-native link react-native-lock-task`
11 |
12 | ### Settings
13 |
14 | **`yourProject/android/app/src/main/AndroidManifest.xml`**
15 |
16 | ```diff
17 |
18 |
20 | +
21 | +
22 |
31 |
32 |
33 |
34 |
35 | +
36 |
37 |
38 |
39 |
40 | +
44 | +
46 | +
47 | +
48 | +
49 | +
50 |
51 |
52 | ```
53 |
54 |
55 | **`yourProject/android/app/src/main/res/values/strings.xml`**
56 |
57 | ```diff
58 |
59 | yourNameApp
60 | + yourNameApp
61 | + yourNameAppTitle
62 |
63 |
64 | ```
65 |
66 | **`yourProject/android/app/src/main/res/xml/my_admin.xml`**
67 |
68 | ```diff
69 | +
70 | +
71 | +
72 | +
73 | +
74 | +
75 | +
76 | +
77 | +
78 |
79 | ```
80 |
81 | Add the library types to your project by creating (or editing) a `index.d.ts` in your project root directory with the line:
82 | ```
83 | declare module 'react-native-lock-task';
84 | ```
85 | and then add it to your `tsconfig.json`
86 | ```
87 | {
88 | ...
89 | "include" : ["index.d.ts"]
90 | }
91 | ```
92 |
93 | ## Reinstall application
94 | * Start your emulator
95 | * Install project
96 |
97 | ## Set owner device adb
98 | * Settings --> Accounts --> Delete All
99 | * `adb shell dpm set-device-owner com.yourProject/com.rnlocktask.MyAdmin`
100 |
101 | ## Usage
102 | ```javascript
103 | import RNLockTask from 'react-native-lock-task';
104 | RNLockTask.isAppInLockTaskMode();
105 | RNLockTask.startLockTask();
106 | RNLockTask.startLockTaskWith(["com.google.android.youtube", "com.sega.sonicdash"]);
107 | RNLockTask.stopLockTask();
108 | RNLockTask.clearDeviceOwnerApp();
109 | ```
110 |
--------------------------------------------------------------------------------
/android/src/main/java/com/rnlocktask/RNLockTaskModule.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rnlocktask;
3 |
4 | import android.app.Activity;
5 | import android.app.ActivityManager;
6 | import android.app.admin.DevicePolicyManager;
7 | import android.content.ComponentName;
8 | import android.content.Context;
9 | import android.os.Build;
10 |
11 | import com.facebook.react.bridge.Promise;
12 | import com.facebook.react.bridge.ReactApplicationContext;
13 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
14 | import com.facebook.react.bridge.ReactMethod;
15 | import com.facebook.react.bridge.ReadableArray;
16 |
17 | import java.util.ArrayList;
18 |
19 | public class RNLockTaskModule extends ReactContextBaseJavaModule {
20 |
21 |
22 | private static final String ACTIVITY_GONE = "ACTIVITY_GONE";
23 | private static final String DEVICE_OWNER_CLEARED = "DEVICE_OWNER_CLEARED";
24 | private static final String LOCKED_TASK = "LOCKED_TASK";
25 | private static final String LOCKED_TASK_AS_OWNER = "LOCKED_TASK_AS_OWNER";
26 | private static final String UNLOCKED_TASK = "UNLOCKED_TASK";
27 | private static final String TAG = "RNLockTaskModule";
28 |
29 | public RNLockTaskModule(ReactApplicationContext reactContext) {
30 | super(reactContext);
31 | }
32 |
33 | @Override
34 | public String getName() {
35 | return "RNLockTask";
36 | }
37 |
38 | @ReactMethod
39 | public void isAppInLockTaskMode(Promise promise) {
40 | try {
41 | Activity mActivity = getCurrentActivity();
42 | if (mActivity != null) {
43 | ActivityManager activityManager = (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);
44 |
45 | // When SDK version is 23
46 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
47 | int lockTaskMode = activityManager.getLockTaskModeState();
48 | promise.resolve(lockTaskMode == ActivityManager.LOCK_TASK_MODE_PINNED);
49 | }
50 |
51 | //When SDK version <=21 and <23. This API is deprecated in 23.
52 | else {
53 | promise.resolve(activityManager.isInLockTaskMode());
54 | }
55 | }
56 | } catch (Exception e) {
57 | promise.reject(e);
58 | }
59 | }
60 |
61 | @ReactMethod
62 | public void clearDeviceOwnerApp(Promise promise) {
63 | try {
64 | Activity mActivity = getCurrentActivity();
65 | if (mActivity != null) {
66 | DevicePolicyManager myDevicePolicyManager = (DevicePolicyManager) mActivity.getSystemService(Context.DEVICE_POLICY_SERVICE);
67 | myDevicePolicyManager.clearDeviceOwnerApp(mActivity.getPackageName());
68 | promise.resolve(DEVICE_OWNER_CLEARED);
69 | }
70 | promise.reject(ACTIVITY_GONE, "Activity gone or mismatch");
71 | } catch (Exception e) {
72 | promise.reject(e);
73 | }
74 | }
75 |
76 | @ReactMethod
77 | public void startLockTaskWith(ReadableArray additionalPackages, Promise promise) {
78 | try {
79 | Activity mActivity = getCurrentActivity();
80 | if (mActivity != null) {
81 | DevicePolicyManager myDevicePolicyManager = (DevicePolicyManager) mActivity.getSystemService(Context.DEVICE_POLICY_SERVICE);
82 | ComponentName mDPM = new ComponentName(mActivity, MyAdmin.class);
83 |
84 | if (myDevicePolicyManager.isDeviceOwnerApp(mActivity.getPackageName())) {
85 | ArrayList packages = new ArrayList<>();
86 | packages.add(mActivity.getPackageName());
87 | if(additionalPackages != null){
88 | for (int i = 0; i < additionalPackages.size(); i++) {
89 | packages.add(additionalPackages.getString(i));
90 | }
91 | }
92 | myDevicePolicyManager.setLockTaskPackages(mDPM, packages.toArray(new String[0]));
93 | mActivity.startLockTask();
94 | promise.resolve(LOCKED_TASK_AS_OWNER);
95 | } else {
96 | mActivity.startLockTask();
97 | promise.resolve(LOCKED_TASK);
98 | }
99 | } else{
100 | promise.reject(ACTIVITY_GONE, "Activity gone or mismatch");
101 | }
102 | } catch (Exception e) {
103 | promise.reject(e);
104 | }
105 | }
106 |
107 | @ReactMethod
108 | public void startLockTask(Promise promise) {
109 | startLockTaskWith(null, promise);
110 | }
111 |
112 | @ReactMethod
113 | public void stopLockTask(Promise promise) {
114 | try {
115 | Activity mActivity = getCurrentActivity();
116 | if (mActivity != null) {
117 | mActivity.stopLockTask();
118 | promise.resolve(UNLOCKED_TASK);
119 | } else {
120 | promise.reject(ACTIVITY_GONE, "Activity gone or mismatch");
121 | }
122 | } catch (Exception e) {
123 | promise.reject(e);
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------