@maximilien0405/capacitor-android-launcher 7.0.1 → 7.0.2
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
|
@@ -4,11 +4,8 @@ This Capacitor plugin allows you to open the launcher settings to set your app a
|
|
|
4
4
|
|
|
5
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
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ANDROID Only.
|
|
10
|
-
|
|
11
|
-
- v7.X.X supports Capacitor V7 (Android minSdkVersion 23+).
|
|
7
|
+
> When set as the default launcher, your user will still be able to exit it, but when it happens it will re-open the app.
|
|
8
|
+
If you really want to prevent your user from leaving, i suggest "pinning" the app, and then setting it as the default launcher.
|
|
12
9
|
|
|
13
10
|
## Installation
|
|
14
11
|
|
|
@@ -19,7 +16,6 @@ npx cap sync
|
|
|
19
16
|
|
|
20
17
|
## Usage
|
|
21
18
|
|
|
22
|
-
|
|
23
19
|
#### Open Launcher Settings
|
|
24
20
|
|
|
25
21
|
This method opens the settings page where the user can set your app as the default launcher.
|
|
@@ -30,9 +26,7 @@ await AndroidLauncher.openLauncherSettings();
|
|
|
30
26
|
|
|
31
27
|
#### Start Immersive Mode
|
|
32
28
|
|
|
33
|
-
This method hides all system controls.
|
|
34
|
-
|
|
35
|
-
> ⚠️ The app must be set as the launcher for it to work.
|
|
29
|
+
This method hides all system controls.
|
|
36
30
|
|
|
37
31
|
```ts
|
|
38
32
|
await AndroidLauncher.startImmersiveMode();
|
|
@@ -4,10 +4,14 @@ import android.content.Intent;
|
|
|
4
4
|
import android.content.pm.PackageManager;
|
|
5
5
|
import android.content.pm.ResolveInfo;
|
|
6
6
|
import android.os.Handler;
|
|
7
|
+
import android.app.Activity;
|
|
7
8
|
import android.os.Build;
|
|
8
9
|
import android.os.Looper;
|
|
9
10
|
import android.view.View;
|
|
11
|
+
import android.view.ViewTreeObserver;
|
|
12
|
+
import android.view.WindowInsets;
|
|
10
13
|
import android.view.WindowInsetsController;
|
|
14
|
+
|
|
11
15
|
import androidx.appcompat.app.AppCompatActivity;
|
|
12
16
|
import androidx.annotation.RequiresApi;
|
|
13
17
|
import com.getcapacitor.Plugin;
|
|
@@ -20,11 +24,12 @@ public class AndroidLauncher {
|
|
|
20
24
|
private AppCompatActivity activity;
|
|
21
25
|
private Bridge bridge;
|
|
22
26
|
private boolean immersiveModeEnabled = false;
|
|
27
|
+
private ViewTreeObserver.OnWindowFocusChangeListener focusChangeListener;
|
|
28
|
+
private View.OnSystemUiVisibilityChangeListener systemUiVisibilityChangeListener;
|
|
23
29
|
|
|
24
30
|
public AndroidLauncher(AppCompatActivity activity, Bridge bridge) {
|
|
25
31
|
this.activity = activity;
|
|
26
32
|
this.bridge = bridge;
|
|
27
|
-
setupSystemUiVisibilityListener();
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
// Opens the settings to allow the user to set the app as launcher
|
|
@@ -38,39 +43,29 @@ public class AndroidLauncher {
|
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
// Starts immersive mode
|
|
46
|
+
// Starts immersive mode
|
|
42
47
|
public void startImmersiveMode(PluginCall call) {
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
runOnMainThread(() -> {
|
|
49
|
+
try {
|
|
45
50
|
enableImmersiveMode();
|
|
46
51
|
call.resolve();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@Override
|
|
50
|
-
public void run() {
|
|
51
|
-
enableImmersiveMode();
|
|
52
|
-
call.resolve();
|
|
53
|
-
}
|
|
54
|
-
});
|
|
52
|
+
} catch (Exception e) {
|
|
53
|
+
call.reject("Error starting immersive mode", e);
|
|
55
54
|
}
|
|
56
|
-
}
|
|
57
|
-
call.reject("Error starting immersive mode", e);
|
|
58
|
-
}
|
|
55
|
+
});
|
|
59
56
|
}
|
|
60
57
|
|
|
61
58
|
private void enableImmersiveMode() {
|
|
62
|
-
try {
|
|
63
59
|
immersiveModeEnabled = true;
|
|
60
|
+
setupSystemUiVisibilityListener();
|
|
64
61
|
View decorView = this.bridge.getActivity().getWindow().getDecorView();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
|
73
|
-
}
|
|
62
|
+
|
|
63
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
64
|
+
WindowInsetsController insetsController = decorView.getWindowInsetsController();
|
|
65
|
+
if (insetsController != null) {
|
|
66
|
+
insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
|
|
67
|
+
insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
|
68
|
+
}
|
|
74
69
|
} else {
|
|
75
70
|
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
76
71
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
@@ -80,48 +75,43 @@ public class AndroidLauncher {
|
|
|
80
75
|
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
|
81
76
|
decorView.setSystemUiVisibility(flags);
|
|
82
77
|
}
|
|
83
|
-
} catch (Exception e) {
|
|
84
|
-
e.printStackTrace();
|
|
85
|
-
}
|
|
86
78
|
}
|
|
87
79
|
|
|
80
|
+
// Stops immersive mode
|
|
88
81
|
public void stopImmersiveMode(PluginCall call) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
clearImmersiveMode();
|
|
98
|
-
call.resolve();
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
} catch (Exception e) {
|
|
103
|
-
call.reject("Error stopping immersive mode", e);
|
|
104
|
-
}
|
|
82
|
+
runOnMainThread(() -> {
|
|
83
|
+
try {
|
|
84
|
+
clearImmersiveMode();
|
|
85
|
+
call.resolve();
|
|
86
|
+
} catch (Exception e) {
|
|
87
|
+
call.reject("Error stopping immersive mode", e);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
105
90
|
}
|
|
106
91
|
|
|
107
92
|
private void clearImmersiveMode() {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
93
|
+
immersiveModeEnabled = false;
|
|
94
|
+
removeSystemUiVisibilityListener();
|
|
95
|
+
View decorView = this.bridge.getActivity().getWindow().getDecorView();
|
|
96
|
+
|
|
97
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
98
|
+
WindowInsetsController insetsController = decorView.getWindowInsetsController();
|
|
99
|
+
if (insetsController != null) {
|
|
100
|
+
insetsController.show(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
|
|
101
|
+
insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
|
105
|
+
decorView.setSystemUiVisibility(flags);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Helper to run things on the UI thread
|
|
110
|
+
private void runOnMainThread(Runnable runnable) {
|
|
111
|
+
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
112
|
+
runnable.run();
|
|
113
|
+
} else {
|
|
114
|
+
new Handler(Looper.getMainLooper()).post(runnable);
|
|
125
115
|
}
|
|
126
116
|
}
|
|
127
117
|
|
|
@@ -136,29 +126,41 @@ public class AndroidLauncher {
|
|
|
136
126
|
|
|
137
127
|
// Listen to system UI changes and hide UI if swiped
|
|
138
128
|
private void setupSystemUiVisibilityListener() {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
enableImmersiveMode();
|
|
147
|
-
}
|
|
129
|
+
Activity activity = this.bridge.getActivity();
|
|
130
|
+
View decorView = activity.getWindow().getDecorView();
|
|
131
|
+
|
|
132
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
133
|
+
focusChangeListener = hasFocus -> {
|
|
134
|
+
if (immersiveModeEnabled && hasFocus) {
|
|
135
|
+
enableImmersiveMode();
|
|
148
136
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
activity.getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(
|
|
154
|
-
visibility -> {
|
|
137
|
+
};
|
|
138
|
+
decorView.getViewTreeObserver().addOnWindowFocusChangeListener(focusChangeListener);
|
|
139
|
+
} else {
|
|
140
|
+
systemUiVisibilityChangeListener = visibility -> {
|
|
155
141
|
if (immersiveModeEnabled && (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
|
156
|
-
|
|
157
|
-
enableImmersiveMode();
|
|
158
|
-
}
|
|
142
|
+
enableImmersiveMode();
|
|
159
143
|
}
|
|
144
|
+
};
|
|
145
|
+
decorView.setOnSystemUiVisibilityChangeListener(systemUiVisibilityChangeListener);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Remove the listener
|
|
150
|
+
private void removeSystemUiVisibilityListener() {
|
|
151
|
+
Activity activity = this.bridge.getActivity();
|
|
152
|
+
View decorView = activity.getWindow().getDecorView();
|
|
153
|
+
|
|
154
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
155
|
+
if (focusChangeListener != null) {
|
|
156
|
+
decorView.getViewTreeObserver().removeOnWindowFocusChangeListener(focusChangeListener);
|
|
157
|
+
focusChangeListener = null;
|
|
160
158
|
}
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
} else {
|
|
160
|
+
if (systemUiVisibilityChangeListener != null) {
|
|
161
|
+
decorView.setOnSystemUiVisibilityChangeListener(null);
|
|
162
|
+
systemUiVisibilityChangeListener = null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
163
165
|
}
|
|
164
166
|
}
|
package/package.json
CHANGED