html2apk 0.1.0 → 0.2.0
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 +10 -1
- package/examples/minimal/app.json +3 -0
- package/examples/minimal/dist/MeuApp-1.0.0-debug.apk +0 -0
- package/package.json +1 -1
- package/src/cli/index.js +13 -1
- package/src/cordova/config-xml.js +39 -5
- package/src/core/config.js +28 -5
- package/src/core/defaults.js +9 -1
- package/src/desktop/main.js +11 -4
- package/src/desktop/renderer/index.html +52 -2
- package/src/desktop/renderer/renderer.js +243 -2
- package/src/desktop/renderer/styles.css +93 -4
- package/src/templates/cordova-plugin-html2apk-bridge/plugin.xml +2 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/FloatingIconService.java +141 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/Html2ApkBridge.java +178 -1
- package/src/templates/cordova-plugin-html2apk-bridge/www/html2apk-bridge.js +40 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
package dev.html2apk.bridge;
|
|
2
2
|
|
|
3
3
|
import android.Manifest;
|
|
4
|
-
import android.app.Activity;
|
|
5
4
|
import android.app.AlarmManager;
|
|
6
5
|
import android.app.NotificationChannel;
|
|
7
6
|
import android.app.NotificationManager;
|
|
8
7
|
import android.app.PendingIntent;
|
|
8
|
+
import android.content.ClipData;
|
|
9
|
+
import android.content.ClipboardManager;
|
|
9
10
|
import android.content.Context;
|
|
10
11
|
import android.content.Intent;
|
|
11
12
|
import android.content.pm.PackageManager;
|
|
@@ -15,6 +16,7 @@ import android.os.VibrationEffect;
|
|
|
15
16
|
import android.os.Vibrator;
|
|
16
17
|
import android.provider.Settings;
|
|
17
18
|
import android.view.View;
|
|
19
|
+
import android.view.WindowManager;
|
|
18
20
|
import android.widget.Toast;
|
|
19
21
|
|
|
20
22
|
import androidx.core.app.NotificationCompat;
|
|
@@ -36,11 +38,13 @@ public class Html2ApkBridge extends CordovaPlugin {
|
|
|
36
38
|
|
|
37
39
|
private CallbackContext notificationPermissionCallback;
|
|
38
40
|
private JSONObject initialNotification;
|
|
41
|
+
private boolean overlaySettingsOpened;
|
|
39
42
|
|
|
40
43
|
@Override
|
|
41
44
|
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
|
42
45
|
super.initialize(cordova, webView);
|
|
43
46
|
handleNotificationIntent(cordova.getActivity().getIntent(), false);
|
|
47
|
+
startFloatingModeIfNeeded();
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
@Override
|
|
@@ -48,6 +52,12 @@ public class Html2ApkBridge extends CordovaPlugin {
|
|
|
48
52
|
handleNotificationIntent(intent, true);
|
|
49
53
|
}
|
|
50
54
|
|
|
55
|
+
@Override
|
|
56
|
+
public void onResume(boolean multitasking) {
|
|
57
|
+
super.onResume(multitasking);
|
|
58
|
+
startFloatingModeIfNeeded();
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
@Override
|
|
52
62
|
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
|
|
53
63
|
try {
|
|
@@ -83,6 +93,36 @@ public class Html2ApkBridge extends CordovaPlugin {
|
|
|
83
93
|
return true;
|
|
84
94
|
}
|
|
85
95
|
|
|
96
|
+
if ("keepScreenAwake".equals(action)) {
|
|
97
|
+
keepScreenAwake(args.optBoolean(0, true));
|
|
98
|
+
callbackContext.success();
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if ("setScreenBrightness".equals(action)) {
|
|
103
|
+
setScreenBrightness(args.optDouble(0, -1));
|
|
104
|
+
callbackContext.success();
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if ("copyText".equals(action)) {
|
|
109
|
+
copyText(args.optString(0, ""));
|
|
110
|
+
callbackContext.success();
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if ("shareText".equals(action)) {
|
|
115
|
+
shareText(args.optString(0, ""));
|
|
116
|
+
callbackContext.success();
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if ("openUrl".equals(action)) {
|
|
121
|
+
openUrl(args.optString(0, ""));
|
|
122
|
+
callbackContext.success();
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
86
126
|
if ("requestNotificationPermission".equals(action)) {
|
|
87
127
|
requestNotificationPermission(callbackContext);
|
|
88
128
|
return true;
|
|
@@ -104,6 +144,29 @@ public class Html2ApkBridge extends CordovaPlugin {
|
|
|
104
144
|
return true;
|
|
105
145
|
}
|
|
106
146
|
|
|
147
|
+
if ("overlayPermissionStatus".equals(action)) {
|
|
148
|
+
callbackContext.success(overlayPermissionStatus());
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if ("requestOverlayPermission".equals(action) || "openOverlaySettings".equals(action)) {
|
|
153
|
+
openOverlaySettings();
|
|
154
|
+
callbackContext.success(overlayPermissionStatus());
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if ("startFloatingIcon".equals(action)) {
|
|
159
|
+
startFloatingIcon();
|
|
160
|
+
callbackContext.success(overlayPermissionStatus());
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if ("stopFloatingIcon".equals(action)) {
|
|
165
|
+
stopFloatingIcon();
|
|
166
|
+
callbackContext.success();
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
|
|
107
170
|
if ("getInitialNotification".equals(action)) {
|
|
108
171
|
callbackContext.success(initialNotification == null ? new JSONObject() : initialNotification);
|
|
109
172
|
initialNotification = null;
|
|
@@ -140,6 +203,69 @@ public class Html2ApkBridge extends CordovaPlugin {
|
|
|
140
203
|
return this.cordova.getActivity().getApplicationContext();
|
|
141
204
|
}
|
|
142
205
|
|
|
206
|
+
private boolean isFloatingMode() {
|
|
207
|
+
return "floating".equals(preferences.getString("Html2ApkMode", ""));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private void startFloatingModeIfNeeded() {
|
|
211
|
+
if (!isFloatingMode()) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
|
216
|
+
@Override
|
|
217
|
+
public void run() {
|
|
218
|
+
try {
|
|
219
|
+
if (canDrawOverlays()) {
|
|
220
|
+
startFloatingIcon();
|
|
221
|
+
cordova.getActivity().moveTaskToBack(true);
|
|
222
|
+
} else if (!overlaySettingsOpened) {
|
|
223
|
+
overlaySettingsOpened = true;
|
|
224
|
+
openOverlaySettings();
|
|
225
|
+
}
|
|
226
|
+
} catch (Exception ignored) {
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private boolean canDrawOverlays() {
|
|
233
|
+
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context());
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private JSONObject overlayPermissionStatus() throws Exception {
|
|
237
|
+
JSONObject result = new JSONObject();
|
|
238
|
+
result.put("required", Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
|
|
239
|
+
result.put("granted", canDrawOverlays());
|
|
240
|
+
result.put("permission", "android.permission.SYSTEM_ALERT_WINDOW");
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private void openOverlaySettings() {
|
|
245
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
|
|
250
|
+
intent.setData(Uri.parse("package:" + context().getPackageName()));
|
|
251
|
+
cordova.getActivity().startActivity(intent);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private void startFloatingIcon() throws Exception {
|
|
255
|
+
if (!canDrawOverlays()) {
|
|
256
|
+
openOverlaySettings();
|
|
257
|
+
throw new Exception("SYSTEM_ALERT_WINDOW permission is not granted.");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
Intent intent = new Intent(context(), FloatingIconService.class);
|
|
261
|
+
context().startService(intent);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private void stopFloatingIcon() {
|
|
265
|
+
Intent intent = new Intent(context(), FloatingIconService.class);
|
|
266
|
+
context().stopService(intent);
|
|
267
|
+
}
|
|
268
|
+
|
|
143
269
|
static void ensureNotificationChannel(Context context) {
|
|
144
270
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
145
271
|
NotificationChannel channel = new NotificationChannel(
|
|
@@ -274,6 +400,57 @@ public class Html2ApkBridge extends CordovaPlugin {
|
|
|
274
400
|
});
|
|
275
401
|
}
|
|
276
402
|
|
|
403
|
+
private void keepScreenAwake(final boolean enabled) {
|
|
404
|
+
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
|
405
|
+
@Override
|
|
406
|
+
public void run() {
|
|
407
|
+
if (enabled) {
|
|
408
|
+
cordova.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
409
|
+
} else {
|
|
410
|
+
cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
private void setScreenBrightness(final double value) {
|
|
417
|
+
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
|
418
|
+
@Override
|
|
419
|
+
public void run() {
|
|
420
|
+
WindowManager.LayoutParams attributes = cordova.getActivity().getWindow().getAttributes();
|
|
421
|
+
if (value < 0) {
|
|
422
|
+
attributes.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
|
|
423
|
+
} else {
|
|
424
|
+
attributes.screenBrightness = (float) Math.max(0.01, Math.min(1, value));
|
|
425
|
+
}
|
|
426
|
+
cordova.getActivity().getWindow().setAttributes(attributes);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
private void copyText(String text) {
|
|
432
|
+
ClipboardManager clipboard = (ClipboardManager) context().getSystemService(Context.CLIPBOARD_SERVICE);
|
|
433
|
+
if (clipboard != null) {
|
|
434
|
+
clipboard.setPrimaryClip(ClipData.newPlainText("html2apk", text));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
private void shareText(String text) {
|
|
439
|
+
Intent intent = new Intent(Intent.ACTION_SEND);
|
|
440
|
+
intent.setType("text/plain");
|
|
441
|
+
intent.putExtra(Intent.EXTRA_TEXT, text);
|
|
442
|
+
cordova.getActivity().startActivity(Intent.createChooser(intent, "Compartilhar"));
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
private void openUrl(String url) throws Exception {
|
|
446
|
+
if (url == null || url.trim().length() == 0) {
|
|
447
|
+
throw new Exception("URL is required.");
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
|
451
|
+
cordova.getActivity().startActivity(intent);
|
|
452
|
+
}
|
|
453
|
+
|
|
277
454
|
private void handleNotificationIntent(Intent intent, boolean dispatchToJs) {
|
|
278
455
|
if (intent == null || !intent.getBooleanExtra(EXTRA_NOTIFICATION_CLICKED, false)) {
|
|
279
456
|
return;
|
|
@@ -61,6 +61,21 @@ var api = {
|
|
|
61
61
|
fullscreen: function (enabled) {
|
|
62
62
|
return call("fullscreen", [Boolean(enabled)]);
|
|
63
63
|
},
|
|
64
|
+
manterTelaAcordada: function (enabled) {
|
|
65
|
+
return call("keepScreenAwake", [Boolean(enabled)]);
|
|
66
|
+
},
|
|
67
|
+
brilhoTela: function (value) {
|
|
68
|
+
return call("setScreenBrightness", [Number(value)]);
|
|
69
|
+
},
|
|
70
|
+
copiarTexto: function (text) {
|
|
71
|
+
return call("copyText", [String(text || "")]);
|
|
72
|
+
},
|
|
73
|
+
compartilharTexto: function (text) {
|
|
74
|
+
return call("shareText", [String(text || "")]);
|
|
75
|
+
},
|
|
76
|
+
abrirUrl: function (url) {
|
|
77
|
+
return call("openUrl", [String(url || "")]);
|
|
78
|
+
},
|
|
64
79
|
solicitarPermissaoNotificacoes: function () {
|
|
65
80
|
return call("requestNotificationPermission");
|
|
66
81
|
},
|
|
@@ -73,6 +88,21 @@ var api = {
|
|
|
73
88
|
abrirConfiguracaoAlarmeExato: function () {
|
|
74
89
|
return call("openExactAlarmSettings");
|
|
75
90
|
},
|
|
91
|
+
statusPermissaoSobreposicao: function () {
|
|
92
|
+
return call("overlayPermissionStatus");
|
|
93
|
+
},
|
|
94
|
+
solicitarPermissaoSobreposicao: function () {
|
|
95
|
+
return call("requestOverlayPermission");
|
|
96
|
+
},
|
|
97
|
+
abrirConfiguracaoSobreposicao: function () {
|
|
98
|
+
return call("openOverlaySettings");
|
|
99
|
+
},
|
|
100
|
+
iniciarIconeFlutuante: function () {
|
|
101
|
+
return call("startFloatingIcon");
|
|
102
|
+
},
|
|
103
|
+
pararIconeFlutuante: function () {
|
|
104
|
+
return call("stopFloatingIcon");
|
|
105
|
+
},
|
|
76
106
|
obterNotificacaoInicial: function () {
|
|
77
107
|
return call("getInitialNotification").then(function (notification) {
|
|
78
108
|
initialNotification = notification && notification.id ? notification : null;
|
|
@@ -106,10 +136,20 @@ if (typeof window !== "undefined") {
|
|
|
106
136
|
window.vibrar = api.vibrar;
|
|
107
137
|
window.toast = api.toast;
|
|
108
138
|
window.fullscreen = api.fullscreen;
|
|
139
|
+
window.manterTelaAcordada = api.manterTelaAcordada;
|
|
140
|
+
window.brilhoTela = api.brilhoTela;
|
|
141
|
+
window.copiarTexto = api.copiarTexto;
|
|
142
|
+
window.compartilharTexto = api.compartilharTexto;
|
|
143
|
+
window.abrirUrl = api.abrirUrl;
|
|
109
144
|
window.solicitarPermissaoNotificacoes = api.solicitarPermissaoNotificacoes;
|
|
110
145
|
window.statusPermissaoNotificacoes = api.statusPermissaoNotificacoes;
|
|
111
146
|
window.podeAgendarNotificacaoExata = api.podeAgendarNotificacaoExata;
|
|
112
147
|
window.abrirConfiguracaoAlarmeExato = api.abrirConfiguracaoAlarmeExato;
|
|
148
|
+
window.statusPermissaoSobreposicao = api.statusPermissaoSobreposicao;
|
|
149
|
+
window.solicitarPermissaoSobreposicao = api.solicitarPermissaoSobreposicao;
|
|
150
|
+
window.abrirConfiguracaoSobreposicao = api.abrirConfiguracaoSobreposicao;
|
|
151
|
+
window.iniciarIconeFlutuante = api.iniciarIconeFlutuante;
|
|
152
|
+
window.pararIconeFlutuante = api.pararIconeFlutuante;
|
|
113
153
|
window.obterNotificacaoInicial = api.obterNotificacaoInicial;
|
|
114
154
|
window.aoClicarNotificacao = api.aoClicarNotificacao;
|
|
115
155
|
|