@maximilien0405/capacitor-android-launcher 0.0.3 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
This Capacitor plugin allows you to open the launcher settings to set your app as the default launcher on Android.
|
|
4
4
|
|
|
5
|
-
It can also, if needed, start (and stop) and immersive mode that hides all UI elements
|
|
5
|
+
It can also, if needed, start (and stop) and immersive mode that hides the all UI elements (status bar and navigation bar). This is usefull for an Kiosk App, or for special apps made for childrens or seniors.
|
|
6
|
+
|
|
7
|
+
## Support
|
|
8
|
+
|
|
9
|
+
ANDROID Only.
|
|
10
|
+
|
|
11
|
+
- v7.X.X supports Capacitor V7 (Android minSdkVersion 23+).
|
|
6
12
|
|
|
7
13
|
## Installation
|
|
8
14
|
|
|
@@ -14,7 +20,7 @@ npx cap sync
|
|
|
14
20
|
## Usage
|
|
15
21
|
|
|
16
22
|
|
|
17
|
-
####
|
|
23
|
+
#### Open Launcher Settings
|
|
18
24
|
|
|
19
25
|
This method opens the settings page where the user can set your app as the default launcher.
|
|
20
26
|
|
|
@@ -24,7 +30,7 @@ await AndroidLauncher.openLauncherSettings();
|
|
|
24
30
|
|
|
25
31
|
#### Start Immersive Mode
|
|
26
32
|
|
|
27
|
-
This method hides all system controls
|
|
33
|
+
This method hides all system controls.
|
|
28
34
|
|
|
29
35
|
> ⚠️ The app must be set as the launcher for it to work.
|
|
30
36
|
|
|
@@ -34,28 +40,17 @@ await AndroidLauncher.startImmersiveMode();
|
|
|
34
40
|
|
|
35
41
|
#### Stop Immersive Mode
|
|
36
42
|
|
|
37
|
-
This method restores the system controls
|
|
43
|
+
This method restores the system controls.
|
|
38
44
|
|
|
39
45
|
```ts
|
|
40
46
|
await AndroidLauncher.stopImmersiveMode();
|
|
41
47
|
```
|
|
42
48
|
|
|
43
|
-
#### Check if
|
|
49
|
+
#### Check if is the Launcher
|
|
44
50
|
|
|
45
51
|
This method checks if your app is currently set as the default launcher.
|
|
46
52
|
|
|
47
53
|
```ts
|
|
48
54
|
const isLauncher = await AndroidLauncher.isLauncherApp();
|
|
49
55
|
console.log(isLauncher); // true or false
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## API
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
interface AndroidLauncherPlugin {
|
|
56
|
-
openLauncherSettings(): Promise<void>;
|
|
57
|
-
startImmersiveMode(): Promise<void>;
|
|
58
|
-
stopImmersiveMode(): Promise<void>;
|
|
59
|
-
isLauncherApp(): Promise<boolean>;
|
|
60
|
-
}
|
|
61
56
|
```
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
package com.maximilien0405.androidlauncher;
|
|
2
2
|
|
|
3
|
-
import android.view.View;
|
|
4
3
|
import android.content.Intent;
|
|
5
|
-
import android.provider.Settings;
|
|
6
4
|
import android.content.pm.PackageManager;
|
|
7
5
|
import android.content.pm.ResolveInfo;
|
|
8
|
-
import android.
|
|
6
|
+
import android.os.Handler;
|
|
7
|
+
import android.os.Build;
|
|
8
|
+
import android.os.Looper;
|
|
9
|
+
import android.view.View;
|
|
10
|
+
import android.view.WindowInsetsController;
|
|
9
11
|
import androidx.appcompat.app.AppCompatActivity;
|
|
10
|
-
|
|
11
|
-
import com.getcapacitor.JSObject;
|
|
12
|
+
import androidx.annotation.RequiresApi;
|
|
12
13
|
import com.getcapacitor.Plugin;
|
|
13
14
|
import com.getcapacitor.PluginCall;
|
|
14
|
-
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
15
15
|
import com.getcapacitor.PluginMethod;
|
|
16
|
+
import com.getcapacitor.Bridge;
|
|
17
|
+
import android.provider.Settings;
|
|
16
18
|
|
|
17
19
|
public class AndroidLauncher {
|
|
18
|
-
|
|
19
20
|
private AppCompatActivity activity;
|
|
21
|
+
private Bridge bridge;
|
|
22
|
+
private boolean immersiveModeEnabled = false;
|
|
20
23
|
|
|
21
|
-
public AndroidLauncher(AppCompatActivity activity) {
|
|
22
|
-
|
|
24
|
+
public AndroidLauncher(AppCompatActivity activity, Bridge bridge) {
|
|
25
|
+
this.activity = activity;
|
|
26
|
+
this.bridge = bridge;
|
|
27
|
+
setupSystemUiVisibilityListener();
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
// Opens the settings to allow the user to set the app as launcher
|
|
@@ -35,32 +40,88 @@ public class AndroidLauncher {
|
|
|
35
40
|
|
|
36
41
|
// Starts immersive mode and prevents the user from leaving the app (if it's the launcher)
|
|
37
42
|
public void startImmersiveMode(PluginCall call) {
|
|
38
|
-
if (!isLauncherApp()) {
|
|
39
|
-
call.reject("App is not set as the launcher.");
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
43
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
45
|
+
enableImmersiveMode();
|
|
46
|
+
call.resolve();
|
|
47
|
+
} else {
|
|
48
|
+
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
|
49
|
+
@Override
|
|
50
|
+
public void run() {
|
|
51
|
+
enableImmersiveMode();
|
|
52
|
+
call.resolve();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
50
56
|
} catch (Exception e) {
|
|
51
57
|
call.reject("Error starting immersive mode", e);
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
private void enableImmersiveMode() {
|
|
62
|
+
try {
|
|
63
|
+
immersiveModeEnabled = true;
|
|
64
|
+
View decorView = this.bridge.getActivity().getWindow().getDecorView();
|
|
65
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
|
66
|
+
WindowInsetsController insetsController = decorView.getWindowInsetsController();
|
|
67
|
+
if (insetsController != null) {
|
|
68
|
+
insetsController.hide(android.view.WindowInsets.Type.statusBars()
|
|
69
|
+
| android.view.WindowInsets.Type.navigationBars());
|
|
70
|
+
|
|
71
|
+
insetsController.setSystemBarsBehavior(
|
|
72
|
+
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
76
|
+
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
77
|
+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
78
|
+
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
|
79
|
+
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
80
|
+
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
|
81
|
+
decorView.setSystemUiVisibility(flags);
|
|
82
|
+
}
|
|
83
|
+
} catch (Exception e) {
|
|
84
|
+
e.printStackTrace();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
56
88
|
public void stopImmersiveMode(PluginCall call) {
|
|
89
|
+
try {
|
|
90
|
+
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
91
|
+
clearImmersiveMode();
|
|
92
|
+
call.resolve();
|
|
93
|
+
} else {
|
|
94
|
+
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
|
95
|
+
@Override
|
|
96
|
+
public void run() {
|
|
97
|
+
clearImmersiveMode();
|
|
98
|
+
call.resolve();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
} catch (Exception e) {
|
|
103
|
+
call.reject("Error stopping immersive mode", e);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private void clearImmersiveMode() {
|
|
57
108
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
109
|
+
immersiveModeEnabled = false;
|
|
110
|
+
View decorView = this.bridge.getActivity().getWindow().getDecorView();
|
|
111
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
112
|
+
WindowInsetsController insetsController = decorView.getWindowInsetsController();
|
|
113
|
+
if (insetsController != null) {
|
|
114
|
+
insetsController.hide(WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE);
|
|
115
|
+
insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH);
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
int uiOptions = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
|
119
|
+
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
|
120
|
+
View.SYSTEM_UI_FLAG_FULLSCREEN;
|
|
121
|
+
decorView.setSystemUiVisibility(uiOptions);
|
|
122
|
+
}
|
|
62
123
|
} catch (Exception e) {
|
|
63
|
-
|
|
124
|
+
e.printStackTrace();
|
|
64
125
|
}
|
|
65
126
|
}
|
|
66
127
|
|
|
@@ -72,4 +133,32 @@ public class AndroidLauncher {
|
|
|
72
133
|
ResolveInfo resolveInfo = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
|
73
134
|
return resolveInfo.activityInfo.packageName.equals(activity.getPackageName());
|
|
74
135
|
}
|
|
136
|
+
|
|
137
|
+
// Listen to system UI changes and hide UI if swiped
|
|
138
|
+
private void setupSystemUiVisibilityListener() {
|
|
139
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
|
140
|
+
// For Android 11+, use a window focus change listener instead
|
|
141
|
+
activity.getWindow().getDecorView().setOnApplyWindowInsetsListener(
|
|
142
|
+
(view, windowInsets) -> {
|
|
143
|
+
if (immersiveModeEnabled &&
|
|
144
|
+
windowInsets.isVisible(android.view.WindowInsets.Type.statusBars() | android.view.WindowInsets.Type.navigationBars())) {
|
|
145
|
+
if (immersiveModeEnabled) {
|
|
146
|
+
enableImmersiveMode();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return view.onApplyWindowInsets(windowInsets);
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
// For older Android versions
|
|
153
|
+
activity.getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(
|
|
154
|
+
visibility -> {
|
|
155
|
+
if (immersiveModeEnabled && (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
|
156
|
+
if (immersiveModeEnabled) {
|
|
157
|
+
enableImmersiveMode();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
75
164
|
}
|
|
@@ -14,7 +14,7 @@ public class AndroidLauncherPlugin extends Plugin {
|
|
|
14
14
|
@Override
|
|
15
15
|
public void load() {
|
|
16
16
|
super.load();
|
|
17
|
-
androidLauncher = new AndroidLauncher(getActivity());
|
|
17
|
+
androidLauncher = new AndroidLauncher(getActivity(), getBridge());
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// Opens the launcher settings
|
package/package.json
CHANGED