xonecode 0.1.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.
Files changed (187) hide show
  1. package/README.md +167 -0
  2. package/dist/agent/authEnDisco.js +56 -0
  3. package/dist/agent/authEnDisco.js.map +1 -0
  4. package/dist/agent/configEnDisco.js +109 -0
  5. package/dist/agent/configEnDisco.js.map +1 -0
  6. package/dist/agent/crearProyecto.js +34 -0
  7. package/dist/agent/crearProyecto.js.map +1 -0
  8. package/dist/agent/entorno.js +124 -0
  9. package/dist/agent/entorno.js.map +1 -0
  10. package/dist/agent/guionizado.js +53 -0
  11. package/dist/agent/guionizado.js.map +1 -0
  12. package/dist/agent/instantanea.js +129 -0
  13. package/dist/agent/instantanea.js.map +1 -0
  14. package/dist/agent/interrupts.js +83 -0
  15. package/dist/agent/interrupts.js.map +1 -0
  16. package/dist/agent/mensajes.js +24 -0
  17. package/dist/agent/mensajes.js.map +1 -0
  18. package/dist/agent/modelos.js +42 -0
  19. package/dist/agent/modelos.js.map +1 -0
  20. package/dist/agent/normalizar.js +20 -0
  21. package/dist/agent/normalizar.js.map +1 -0
  22. package/dist/agent/perfiles.js +103 -0
  23. package/dist/agent/perfiles.js.map +1 -0
  24. package/dist/agent/proyecto.js +107 -0
  25. package/dist/agent/proyecto.js.map +1 -0
  26. package/dist/agent/puente.js +142 -0
  27. package/dist/agent/puente.js.map +1 -0
  28. package/dist/agent/resumenDeTool.js +48 -0
  29. package/dist/agent/resumenDeTool.js.map +1 -0
  30. package/dist/agent/skills.js +65 -0
  31. package/dist/agent/skills.js.map +1 -0
  32. package/dist/agent/textoDeTool.js +113 -0
  33. package/dist/agent/textoDeTool.js.map +1 -0
  34. package/dist/agent/turnoReal.js +173 -0
  35. package/dist/agent/turnoReal.js.map +1 -0
  36. package/dist/agent/verificador.js +65 -0
  37. package/dist/agent/verificador.js.map +1 -0
  38. package/dist/agent/xoneAgent.js +106 -0
  39. package/dist/agent/xoneAgent.js.map +1 -0
  40. package/dist/bin.js +9 -0
  41. package/dist/bin.js.map +1 -0
  42. package/dist/cli/aprobar.js +82 -0
  43. package/dist/cli/aprobar.js.map +1 -0
  44. package/dist/cli/config.js +133 -0
  45. package/dist/cli/config.js.map +1 -0
  46. package/dist/cli/consola.js +346 -0
  47. package/dist/cli/consola.js.map +1 -0
  48. package/dist/cli/describe.js +53 -0
  49. package/dist/cli/describe.js.map +1 -0
  50. package/dist/cli/doctor.js +45 -0
  51. package/dist/cli/doctor.js.map +1 -0
  52. package/dist/cli/main.js +520 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/markdown.js +90 -0
  55. package/dist/cli/markdown.js.map +1 -0
  56. package/dist/cli/run.js +164 -0
  57. package/dist/cli/run.js.map +1 -0
  58. package/dist/cli/spinner.js +89 -0
  59. package/dist/cli/spinner.js.map +1 -0
  60. package/dist/cli/stdio.js +193 -0
  61. package/dist/cli/stdio.js.map +1 -0
  62. package/dist/cli/tema.js +40 -0
  63. package/dist/cli/tema.js.map +1 -0
  64. package/dist/cli/verify.js +62 -0
  65. package/dist/cli/verify.js.map +1 -0
  66. package/dist/core/bitacora.js +30 -0
  67. package/dist/core/bitacora.js.map +1 -0
  68. package/dist/core/config.js +236 -0
  69. package/dist/core/config.js.map +1 -0
  70. package/dist/core/contextos.js +56 -0
  71. package/dist/core/contextos.js.map +1 -0
  72. package/dist/core/deps.js +51 -0
  73. package/dist/core/deps.js.map +1 -0
  74. package/dist/core/diff.js +79 -0
  75. package/dist/core/diff.js.map +1 -0
  76. package/dist/core/esqueleto.js +366 -0
  77. package/dist/core/esqueleto.js.map +1 -0
  78. package/dist/core/events.js +2 -0
  79. package/dist/core/events.js.map +1 -0
  80. package/dist/core/modelos.js +85 -0
  81. package/dist/core/modelos.js.map +1 -0
  82. package/dist/core/notify.js +106 -0
  83. package/dist/core/notify.js.map +1 -0
  84. package/dist/core/ports.js +114 -0
  85. package/dist/core/ports.js.map +1 -0
  86. package/dist/core/turno.js +127 -0
  87. package/dist/core/turno.js.map +1 -0
  88. package/dist/vendor/hitl.js +103 -0
  89. package/dist/vendor/hitl.js.map +1 -0
  90. package/dist/vendor/skillLoaders/catalog.js +74 -0
  91. package/dist/vendor/skillLoaders/catalog.js.map +1 -0
  92. package/dist/vendor/tokenTracking.js +58 -0
  93. package/dist/vendor/tokenTracking.js.map +1 -0
  94. package/package.json +41 -0
  95. package/skills/xone-debugging/SKILL.md +52 -0
  96. package/skills/xone-debugging/references/faq.md +561 -0
  97. package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
  98. package/skills/xone-development/SKILL.md +105 -0
  99. package/skills/xone-development/references/anti-patrones.md +94 -0
  100. package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
  101. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
  102. package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
  103. package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
  104. package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
  105. package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
  106. package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
  107. package/skills/xone-development/references/datos/appdata.md +611 -0
  108. package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
  109. package/skills/xone-development/references/datos/http.md +366 -0
  110. package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
  111. package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
  112. package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
  113. package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
  114. package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
  115. package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
  116. package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
  117. package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
  118. package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
  119. package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
  120. package/skills/xone-development/references/indice-completo.md +77 -0
  121. package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
  122. package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
  123. package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
  124. package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
  125. package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
  126. package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
  127. package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
  128. package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
  129. package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
  130. package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
  131. package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
  132. package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
  133. package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
  134. package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
  135. package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
  136. package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
  137. package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
  138. package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
  139. package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
  140. package/skills/xone-development/references/tipos-de-prop.md +28 -0
  141. package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
  142. package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
  143. package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
  144. package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
  145. package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
  146. package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
  147. package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
  148. package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
  149. package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
  150. package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
  151. package/skills/xone-development/references/xml-ui/mapas.md +685 -0
  152. package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
  153. package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
  154. package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
  155. package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
  156. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
  157. package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
  158. package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
  159. package/skills/xone-plan-builder/SKILL.md +183 -0
  160. package/skills/xone-plan-builder/agents/openai.yaml +5 -0
  161. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
  162. package/skills/xone-project-generator/SKILL.md +111 -0
  163. package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
  164. package/skills/xone-project-generator/references/colecciones-base.md +16 -0
  165. package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
  166. package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
  167. package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
  168. package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
  169. package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
  170. package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
  171. package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
  172. package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
  173. package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
  174. package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
  175. package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
  176. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
  177. package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
  178. package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
  179. package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
  180. package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
  181. package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
  182. package/skills/xone-review/SKILL.md +189 -0
  183. package/skills/xone-spec-builder/SKILL.md +235 -0
  184. package/skills/xone-spec-builder/agents/openai.yaml +5 -0
  185. package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
  186. package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
  187. package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
@@ -0,0 +1,583 @@
1
+ # XOne — Objetos de dispositivo y hardware
2
+
3
+ > Fuente: `xone/v2/xone-help-docs/topics/03d-js-createobject.md` §8.1–§8.11, §8.12–§8.15. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
4
+
5
+ Contenido: §8.1 FileManager · §8.2 XOnePDF · §8.3 XOnePrinter · §8.4 BarcodeGenerator · §8.5 Datawedge · §8.6 XOneNFC · §8.7 XOneOCR · §8.8 BluetoothSerialPort · §8.9 WifiManager · §8.10 Animation · §8.11 deviceInfo · §8.12 GpsTools · §8.13 OAuth2 · §8.14 WebSocket · §8.15 fingerprintManager
6
+
7
+ ---
8
+
9
+ ### 8.1 FileManager - Gestión de Archivos
10
+
11
+ Manejo completo de ficheros y directorios: lectura/escritura, listado, copia/movimiento, compresión, descarga/subida HTTP, caché de la app y watchers de cambios.
12
+
13
+ ```javascript
14
+ let fm = new FileManager(); // o createObject("FileManager")
15
+ ```
16
+
17
+ #### Lectura y escritura
18
+
19
+ ```javascript
20
+ let contenido = fm.readFile("datos.json"); // UTF-8 por defecto
21
+ let raw = fm.readFile("archivo.bin", "ISO-8859-1"); // Encoding opcional (2º param)
22
+
23
+ fm.saveFile("notas.txt", "Contenido"); // Crea / sobreescribe
24
+ fm.saveFile("notas.txt", "Más texto", true); // 3er param: append
25
+ fm.saveFile("datos.txt", "texto", false, "ISO-8859-1"); // 4º param: encoding (default UTF-8)
26
+ // saveFile acepta también byte[] como segundo argumento
27
+ ```
28
+
29
+ #### Existencia y metadatos
30
+
31
+ `fileExists` / `directoryExists` siguen convención C: retornan **0 si existe**, **-1 si no**.
32
+
33
+ ```javascript
34
+ if (fm.fileExists("documento.pdf") === 0) { /* existe */ }
35
+ if (fm.directoryExists("cache/") === 0) { /* existe */ }
36
+
37
+ let bVacio = fm.isDirectoryEmpty("cache/");
38
+ let dFecha = fm.getLastModifiedDate("documento.pdf"); // Date
39
+
40
+ // Bytes (fichero) o tamaño agregado del árbol (directorio)
41
+ let nBytes = fm.getSize("documento.pdf");
42
+
43
+ // Metadatos completos en un solo objeto
44
+ let info = fm.getFileInfo("documento.pdf");
45
+ // info.size, info.creationDate (ms; 0 en Android < 8), info.modificationDate (ms)
46
+ // info.isHidden, info.canRead, info.canExecute, info.canWrite
47
+ ```
48
+
49
+ #### Listar contenido
50
+
51
+ ```javascript
52
+ let aFiles = fm.listFiles("descargas/"); // Array de paths absolutos
53
+ let aDirs = fm.listDirectories("descargas/"); // Sólo subdirectorios
54
+
55
+ // listFiles con filtros (orderBy: "date_desc" o "name"; fechas en dd/MM/yyyy)
56
+ let aPdfs = fm.listFiles({
57
+ source : "descargas/",
58
+ fileTypes: ["pdf", "doc"], // extensiones a aceptar
59
+ orderBy : "date_desc", // "date_desc" | "name" | ""
60
+ dateFrom : "01/01/2026",
61
+ dateTo : "31/12/2026"
62
+ });
63
+ ```
64
+
65
+ #### Copiar, mover, renombrar, borrar
66
+
67
+ Todos retornan **0 si OK**, **-1 si fallo**.
68
+
69
+ ```javascript
70
+ fm.copy("origen.txt", "destino.txt");
71
+ fm.move("viejo.txt", "nuevo.txt");
72
+ fm.rename("archivo.txt", "renombrado.txt");
73
+ fm.delete("temporal.txt");
74
+ fm.delete("a.txt", "b.txt", "c.txt"); // delete acepta varios paths (se procesa hasta el primer fallo)
75
+ ```
76
+
77
+ #### Directorios
78
+
79
+ ```javascript
80
+ let nResult = fm.createDirectory("nuevo/subdir");
81
+ // 0 = creado, 1 = ya existe como directorio, 2 = existe como fichero, -1 = error
82
+ fm.deleteDirectory("temp/"); // recursivo, 0 OK / -1 fallo
83
+ ```
84
+
85
+ #### Compresión (zip / unzip)
86
+
87
+ ```javascript
88
+ fm.zip("documento.pdf"); // -> "documento.pdf.zip" (mismo path)
89
+ fm.zip("documento.pdf", "comprimido.zip");
90
+ fm.zip("carpeta/", "carpeta.zip"); // Zip recursivo del directorio
91
+
92
+ // zipAll: comprimir varios ficheros/arrays en un solo zip
93
+ fm.zipAll("paquete.zip", "a.txt", "b.txt", ["c.txt", "d.txt"]);
94
+
95
+ // zipAll con objeto (permite password)
96
+ fm.zipAll({
97
+ targetZip: "cifrado.zip",
98
+ password : "secreto",
99
+ files : ["a.txt", "b.txt"]
100
+ });
101
+
102
+ fm.unzip("paquete.zip"); // Al directorio padre del zip
103
+ fm.unzip("paquete.zip", "destino/");
104
+ fm.unzip("cifrado.zip", "destino/", "secreto"); // 3er param: password
105
+ ```
106
+
107
+ #### Conversiones (base64, checksum)
108
+
109
+ ```javascript
110
+ let sBase64 = fm.toBase64("imagen.jpg");
111
+ fm.toFile(sBase64, "imagen_copia.jpg");
112
+
113
+ // Tipos: "crc32" (default), "adler32", "sha1", "sha2", "sha256", "sha512"
114
+ let sCrc = fm.getChecksum("archivo.bin"); // CRC32
115
+ let sSha = fm.getChecksum("archivo.bin", "sha256");
116
+ let sUrl = fm.getChecksum("archivo.bin", "sha256", true); // 3er param urlSafe: Base64 URL-safe
117
+ ```
118
+
119
+ #### Descarga y subida HTTP
120
+
121
+ `download` tiene dos formas:
122
+
123
+ ```javascript
124
+ // Forma síncrona (legacy): bloquea, retorna 0 OK / -1 fallo
125
+ let nResult = fm.download("https://ejemplo.com/archivo.pdf", "archivo.pdf");
126
+ if (nResult === 0) { ui.openFile("archivo.pdf"); }
127
+
128
+ // Forma asíncrona con objeto: retorna Future, callbacks en JS
129
+ let future = fm.download({
130
+ source : "https://ejemplo.com/archivo.pdf",
131
+ target : "archivo.pdf",
132
+ method : "GET", // "GET" o "POST"
133
+ headers : { "X-Api-Key": "xxx" },
134
+ parameters: { id: "123" }, // Body JSON
135
+ unzip : false, // Descomprimir automáticamente al terminar
136
+ resumeEnabled : false, // Reanudar descargas parciales
137
+ allowUnsafeCertificates: false,
138
+ onSuccess : function(sPath) { ui.openFile(sPath); },
139
+ onProgress: function(nPercent) { /* 0-100 */ },
140
+ onError : function(nStatus, sMessage) { /* fallo */ }
141
+ });
142
+
143
+ // Subir fichero (multipart/form-data, versión 2 por defecto)
144
+ let sRespuesta = fm.uploadFile({
145
+ url : "https://ejemplo.com/upload",
146
+ file : "notas.txt",
147
+ version : 2, // 1 = legacy, 2 = moderno (default)
148
+ headers : { Authorization: "Bearer xxx" },
149
+ parameters: { VERSIONAPP: "1.0" },
150
+ allowUnsafeCertificates: false,
151
+ onSuccess : function(sResponse) { /* OK */ },
152
+ onProgress: function(nPercent) { /* 0-100 */ },
153
+ onError : function(nStatus, sMsg) { /* fallo */ }
154
+ });
155
+ ```
156
+
157
+ #### Bases de datos SQLite
158
+
159
+ ```javascript
160
+ // Cierra conexión abierta, descarga el .db remoto y lo reemplaza atómicamente
161
+ fm.downloadDatabase("https://ejemplo.com/datos.db");
162
+
163
+ // Borra .db + .db-wal + .db-shm; cierra conexión abierta si la hay
164
+ fm.deleteDatabase("temporal.db");
165
+ ```
166
+
167
+ #### Apertura con la app del sistema
168
+
169
+ ```javascript
170
+ fm.openFile("documento.pdf"); // Lanza ACTION_VIEW con MIME detectado
171
+ fm.openFile("https://ejemplo.com/manual.pdf"); // URL: descarga a caché y abre
172
+ // APK: bloqueado en builds de Play Store; permitido en standalone
173
+ ```
174
+
175
+ #### Rutas internas de la app
176
+
177
+ Estas rutas son de **almacenamiento privado** del proceso Android, distintas del path de la app XOne (`appData.getAppPath()`).
178
+
179
+ ```javascript
180
+ let sRoot = fm.getRootDirectory(); // /data/data/<package>/ (datos privados)
181
+ let sCache = fm.getCacheDirectory(); // ".../cache"
182
+ let sCodeCache = fm.getCodeCacheDirectory(); // ".../code_cache" (dex compilados)
183
+
184
+ // Limpiar caché (uno de los dos parámetros es obligatorio)
185
+ fm.clearCache({ maxSize: 50 * 1024 * 1024 }); // Si supera 50 MB -> vacía entero
186
+ fm.clearCache({ maxSize: 0 }); // Vacía siempre
187
+ fm.clearCache({ olderThan: new Date(2026, 0, 1) }); // Borra ficheros anteriores a la fecha
188
+ ```
189
+
190
+ #### Watchers de cambios en directorio
191
+
192
+ Notifica cuando se crean, modifican o borran ficheros/subdirectorios en un directorio.
193
+
194
+ ```javascript
195
+ fm.addOnDirectoryChangedListener("descargas/", function(sEvent, sPath) {
196
+ // sEvent: "create" | "delete" | "deleteSelf" | "modify"
197
+ // | "movedFrom" | "movedTo" | "moveSelf"
198
+ // | "folderCreated" | "folderDeleted"
199
+ // sPath: nombre del fichero/subdir afectado (no incluye el directorio observado)
200
+ ui.showToast(sEvent + ": " + sPath);
201
+ });
202
+
203
+ fm.removeOnDirectoryChangedListener("descargas/"); // Detener observación
204
+ ```
205
+
206
+ ### 8.2 XOnePDF - Generación de PDF
207
+
208
+ ```javascript
209
+ var pdf = new XOnePDF();
210
+ pdf.create("mi_documento.pdf");
211
+ pdf.permissions("print");
212
+ pdf.setEncryption("", "1234", "128bits");
213
+ pdf.open();
214
+
215
+ // Configurar fuente
216
+ pdf.setFont("helvetica");
217
+ pdf.setFontSize(12);
218
+ pdf.setFontStyle("bold");
219
+ pdf.setFontColor("#000000");
220
+
221
+ // Agregar contenido
222
+ pdf.addText("Titulo del documento");
223
+ pdf.newLine();
224
+ pdf.addTextLine("Línea de texto completa");
225
+
226
+ // Tabla de 3 columnas
227
+ pdf.createTable(3);
228
+ pdf.setTableWidth(100);
229
+ pdf.setTableCellWidths(33, 33, 33);
230
+ pdf.setCellBorder("all");
231
+ pdf.setAlignment("center");
232
+ pdf.addCellText("Columna 1", "#EEEEEE");
233
+ pdf.addCellText("Columna 2", "#EEEEEE");
234
+ pdf.addCellText("Columna 3", "#EEEEEE");
235
+ pdf.addTable();
236
+
237
+ // Imagen
238
+ pdf.addImageSetXY("logo.png", 0, 0, 150, 75);
239
+
240
+ pdf.newPage();
241
+ pdf.close();
242
+ pdf.launchPDF();
243
+ ```
244
+
245
+ **Extraer el texto de un PDF existente** (p. ej. para leerlo o procesarlo). `extractText(rutaPdf)` devuelve el texto plano; `extractTextToFile(rutaPdf, rutaTxt)` lo vuelca a un `.txt` en UTF-8 y devuelve su ruta. Solo extraen la capa de texto: un PDF escaneado (imágenes sin texto) devuelve vacío, no hacen OCR. Son síncronos.
246
+
247
+ ```javascript
248
+ var pdf = new XOnePDF();
249
+ var texto = pdf.extractText("documento.pdf"); // a variable
250
+ var rutaTxt = pdf.extractTextToFile("documento.pdf", "documento.txt"); // a fichero .txt (UTF-8)
251
+ ```
252
+
253
+ ### 8.3 XOnePrinter - Impresion Bluetooth
254
+
255
+ ```javascript
256
+ var mPrinter = new XOnePrinter();
257
+ mPrinter.setDriver("zebra");
258
+ mPrinter.setDelay(0);
259
+ mPrinter.useStoredPrinter();
260
+ mPrinter.connect();
261
+ mPrinter.setMaxCharacterWidth(45);
262
+ mPrinter.printImage("logo.png", 600, 300, "center", 0);
263
+ mPrinter.printLineCentered("Texto centrado");
264
+ mPrinter.printLineCentered("---------------------------");
265
+ mPrinter.disconnect();
266
+ ```
267
+
268
+ ### 8.4 BarcodeGenerator - Generación de Códigos
269
+
270
+ ```javascript
271
+ var generator = new BarcodeGenerator();
272
+ generator.setType("qrcode"); // code128, code39, ean13, qrcode, datamatrix, etc.
273
+ generator.setResolution(640, 480);
274
+ generator.setDestinationFile("qrcode.png");
275
+ generator.generate("Contenido del código");
276
+ ui.openFile("qrcode.png");
277
+
278
+ // Forma rápida
279
+ var sFile = new BarcodeGenerator().generate("texto");
280
+ ui.openFile(sFile);
281
+ ```
282
+
283
+ **Tipos soportados:** `codabar`, `code128`, `code39`, `code93`, `datamatrix`, `qrcode`, `upca`, `upce`, `ean13`, `ean8`, `pdf417`
284
+
285
+ ### 8.5 Datawedge (scanner hardware Symbol/Zebra)
286
+
287
+ Para scanners Symbol/Zebra (terminales TC, MC, PDA industriales) que usan el servicio DataWedge, hay que definir un perfil que redirija los escaneos a la aplicación XOne via intent broadcast.
288
+
289
+ ```javascript
290
+ function addDataWedgeProfile() {
291
+ let sDeviceOs = appData.getGlobalMacro("##DEVICE_OS##");
292
+ if (sDeviceOs != "android") return;
293
+
294
+ let mainBundle = new Bundle();
295
+ mainBundle.PROFILE_NAME = "XOne";
296
+ mainBundle.PROFILE_ENABLED = "true";
297
+ mainBundle.CONFIG_MODE = "CREATE_IF_NOT_EXIST";
298
+ mainBundle.RESET_CONFIG = "true";
299
+
300
+ let appBundle = new Bundle();
301
+ appBundle.PACKAGE_NAME = systemSettings.getPackageName();
302
+ appBundle.ACTIVITY_LIST = ["*"];
303
+ mainBundle.APP_LIST = [appBundle];
304
+
305
+ let pluginConfig = new Bundle();
306
+ pluginConfig.PLUGIN_NAME = "BDF";
307
+ pluginConfig.RESET_CONFIG = "true";
308
+ pluginConfig.OUTPUT_PLUGIN_NAME = "KEYSTROKE";
309
+
310
+ let paramBundle = new Bundle();
311
+ paramBundle.bdf_enabled = "true";
312
+ paramBundle.bdf_send_enter = "true";
313
+ pluginConfig.PARAM_LIST = paramBundle;
314
+ mainBundle.PLUGIN_CONFIG = pluginConfig;
315
+
316
+ let intent = new AndroidIntent();
317
+ intent.setAction("com.symbol.datawedge.api.ACTION");
318
+ intent.putBundleExtra("com.symbol.datawedge.api.SET_CONFIG", mainBundle);
319
+ intent.sendBroadcast();
320
+ }
321
+ ```
322
+
323
+ **Configuración manual en el dispositivo** (cuando `addDataWedgeProfile` no es suficiente):
324
+
325
+ 1. Abrir la aplicación DataWedge del terminal.
326
+ 2. Deshabilitar o borrar todos los perfiles existentes.
327
+ 3. Crear un perfil nuevo.
328
+ 4. En **Associated apps**, asociar `com.xone.framework.EditView` y `com.xone.framework.EditViewBGCOOR`.
329
+ 5. Deshabilitar **SimulScan Input**.
330
+ 6. Deshabilitar **Keystroke Output**.
331
+ 7. Habilitar **Intent Output** con:
332
+ - Intent action: `com.symbol.datawedge.DWDEMO`
333
+ - Intent category: `Android.intent.category.DEFAULT`
334
+ - Intent delivery: **Broadcast intent**
335
+
336
+ ### 8.6 XOneNFC - Lectura/Escritura NFC
337
+
338
+ ```javascript
339
+ var nfc = new XOneNFC();
340
+
341
+ // Lectura DNI electrónico
342
+ nfc.enableDnieReader({
343
+ readProfileData: true,
344
+ readUserImage: true,
345
+ canNumber: "123456789",
346
+ onDnieRead: function(result) {
347
+ var nombre = result.getName();
348
+ var apellido = result.getSurname();
349
+ var dni = result.getDniNumber();
350
+ var foto = result.getUserImage(appData.getFilesPath() + "foto.png");
351
+ },
352
+ onDnieReadError: function(sError) {
353
+ ui.showToast("Error NFC: " + sError);
354
+ }
355
+ });
356
+
357
+ // Escritura/Lectura NDEF
358
+ nfc.writeNdefMessageAsync("Texto para NFC", function(result) {
359
+ ui.showToast("Escrito correctamente");
360
+ });
361
+ nfc.readNdefMessageAsync(function(result) {
362
+ ui.showToast("Leido: " + result);
363
+ });
364
+ ```
365
+
366
+ ### 8.7 XOneOCR - Reconocimiento Optico de Caracteres
367
+
368
+ ```javascript
369
+ var ocr = new XOneOCR();
370
+ var matricula = ocr.scanLicensePlate("foto_coche.jpg");
371
+ // OCR genérico de texto: ocr.scanText(...) NO está implementado actualmente (lanza UnsupportedOperationException).
372
+ // Usar scanLicensePlate() para matrículas o startScan({regex, onResult}) para validación por patrones.
373
+ ```
374
+
375
+ ### 8.8 BluetoothSerialPort - Comunicación Bluetooth Serial
376
+
377
+ Disponible como singleton global `bluetoothSerial`:
378
+
379
+ ```javascript
380
+ var lstDevices = bluetoothSerial.getDiscoverableBluetoothDevices();
381
+ var device = null;
382
+ for (var i = 0; i < lstDevices.length; i++) {
383
+ if (lstDevices[i].getDeviceName() == "mi_dispositivo") {
384
+ device = lstDevices[i];
385
+ break;
386
+ }
387
+ }
388
+ if (device) {
389
+ bluetoothSerial.connect(device.getMacAddress());
390
+ bluetoothSerial.write("datos a enviar");
391
+ var respuesta = bluetoothSerial.read(256);
392
+ bluetoothSerial.disconnect();
393
+ }
394
+ ```
395
+
396
+ ### 8.9 WifiManager - Gestion WiFi
397
+
398
+ ```javascript
399
+ var wm = new WifiManager(); // o createObject("WifiManager")
400
+
401
+ var wifiActivo = wm.isWifiAdapterEnabled();
402
+ var mac = wm.getAdapterMacAddress();
403
+ var info = wm.getActiveWifiInfo();
404
+ wm.connect("MiRed");
405
+ wm.disconnect();
406
+ wm.scanAvailableNetworks(function(redes) {
407
+ // Procesar redes disponibles
408
+ });
409
+ ```
410
+
411
+ ### 8.10 Animation - Animaciones Programaticas
412
+
413
+ `Animation` usa una **API fluida encadenada**. El target es el **nombre del prop como string**, no el objeto control. Se instancia con `new Animation()`.
414
+
415
+ ```javascript
416
+ // API fluida: encadenar metodos sobre el nombre del prop
417
+ new Animation()
418
+ .setTarget("MAP_BOTON") // Nombre del prop (string), no el control
419
+ .setDuration(300) // Duracion en milisegundos
420
+ .setRelativeX(100) // Mover 100p a la derecha
421
+ .setRelativeY(-50) // Mover 50p hacia arriba
422
+ .setInterpolation("BounceInterpolator");
423
+
424
+ // Con callback al terminar
425
+ new Animation()
426
+ .setTarget("MAP_BOTON")
427
+ .setDuration(500)
428
+ .setAlpha(0)
429
+ .setEndCallback(function() {
430
+ ui.showToast("Animacion completada");
431
+ });
432
+
433
+ // Metodos disponibles
434
+ new Animation().setTarget("MAP_CTRL").setDuration(300)
435
+ .setAlpha(0.5)
436
+ .setX(500) // Posicion X absoluta (setY por separado)
437
+ .setY(300) // Posicion Y absoluta
438
+ .setRelativeX(100)
439
+ .setRelativeY(100)
440
+ .setZ(5)
441
+ .setRelativeZ(10)
442
+ .setScaleX(2.0)
443
+ .setScaleY(0.5)
444
+ .setRelativeScaleX(1.5)
445
+ .setRelativeScaleY(1.5)
446
+ .setWidth(400)
447
+ .setHeight(200)
448
+ .setRotation(180)
449
+ .setRelativeRotation(45)
450
+ .setBackgroundColor("#FF0000")
451
+ .setCircularReveal(0, 0, true) // (centerX, centerY, bReveal): true=mostrar, false=ocultar
452
+ .setRepeatCount(2)
453
+ .setRepeatMode(2) // 1 = restart, 2 = reverse (espera int, NO string)
454
+ .setStartCallback(function() {})
455
+ .setEndCallback(function() {})
456
+ .cancel() // Cancela la animación en curso
457
+ .stop(true); // stop requiere 1 boolean (true = completa la animación antes de cancelar)
458
+
459
+ // Interpolaciones disponibles:
460
+ // AccelerateDecelerateInterpolator (por defecto)
461
+ // BounceInterpolator, LinearInterpolator
462
+ // OvershootInterpolator, AccelerateInterpolator, AnticipateInterpolator
463
+ new Animation().setTarget("MAP_CTRL").setDuration(300)
464
+ .setRelativeX(200)
465
+ .setInterpolation("BounceInterpolator");
466
+ ```
467
+
468
+ ### 8.11 deviceInfo - Información del Dispositivo
469
+
470
+ `deviceInfo` es un **singleton global** — no requiere instanciacion con `new DeviceInfo()`. Accesible directamente como `deviceInfo`.
471
+
472
+ ```javascript
473
+ // Bateria
474
+ let nPorcentaje = deviceInfo.getBatteryLevelPercentage(); // 0-100
475
+ let nNivel = deviceInfo.getBatteryLevel(); // valor raw
476
+ let nNivelMax = deviceInfo.getBatteryMaxLevel(); // valor máximo raw
477
+ let nTemperatura = deviceInfo.getBatteryTemperature(); // decimas de grado -> / 10 para Celsius
478
+ let nVoltaje = deviceInfo.getBatteryVoltage(); // milivoltios
479
+
480
+ // Red movil
481
+ let nSenal = deviceInfo.getMobileNetworkSignalStrength(); // dBm (sin typo)
482
+ let sTipoRed = deviceInfo.getConnectedMobileNetworkType(); // "LTE", "HSPA", etc.
483
+ let sEstadoRed = deviceInfo.getMobileNetworkState(); // "connected", etc.
484
+
485
+ // Trafico de red
486
+ let nBytesRx = deviceInfo.getRxBytes();
487
+ let nBytesTx = deviceInfo.getTxBytes();
488
+ ```
489
+
490
+ > **Atención**: El método se llama `getMobileNetworkSignalStrength()` (sin typo). La documentación antigua lo listaba incorrectamente como `getMobileNetworkSignalStrengh`.
491
+
492
+ ### 8.12 GpsTools - Herramientas GPS
493
+
494
+ ```javascript
495
+ var gps = new GpsTools();
496
+
497
+ // Distancia entre dos puntos (en metros)
498
+ var metros = gps.distanceTo([
499
+ { latitude: 38.8685452, longitude: -6.8170906 },
500
+ { latitude: 40.4167747, longitude: -3.70379019 }
501
+ ]);
502
+
503
+ // Geocodificacion inversa
504
+ var result = gps.getAddressFromPosition("38.8862106, -7.0040345");
505
+
506
+ // Verificar si un punto esta dentro de un poligono
507
+ var bDentro = gps.containsLocation(
508
+ "40.3633442, -1.0893794",
509
+ ["38.8685452, -6.8170906", "40.4167747, -3.70379019", "41.3850632, 2.1734035"]
510
+ );
511
+
512
+ // Ultima posicion conocida
513
+ var location = gps.getLastKnownLocation();
514
+ ```
515
+
516
+ ### 8.13 OAuth2 - Autenticación OAuth2
517
+
518
+ (Documentado en detalle en 03c §6.)
519
+
520
+ ```javascript
521
+ new OAuth2().withOptions({
522
+ authority: "https://auth.servidor.com/identity",
523
+ clientID: "mi_client_id",
524
+ clientSecret: "mi_secret",
525
+ scope: "openid profile",
526
+ responseType: "code id_token",
527
+ persistenceKey: "oauth_key",
528
+ redirectUri: "com.miapp.oauth:/callback"
529
+ }).authenticate({
530
+ onSuccess: function(result) { /* token en result.access_token */ },
531
+ onError: function(err) { ui.showToast("Error: " + err); }
532
+ });
533
+ ```
534
+
535
+ ### 8.14 WebSocket - WebSocket de XOne
536
+
537
+ ```javascript
538
+ var request = {
539
+ url: "wss://miservidor.com/ws",
540
+ onOpen: function() {
541
+ console.log("WebSocket conectado");
542
+ },
543
+ onMessage: function(sData) {
544
+ var datos = JSON.parse(sData);
545
+ procesarMensaje(datos);
546
+ },
547
+ onError: function(error) {
548
+ console.log("Error WS: " + error);
549
+ },
550
+ onClose: function() {
551
+ console.log("WebSocket cerrado");
552
+ }
553
+ };
554
+
555
+ var ws = new WebSocket(request);
556
+ ws.send(JSON.stringify({ tipo: "saludo", mensaje: "hola" }));
557
+ ws.close();
558
+ ```
559
+
560
+ ### 8.15 fingerprintManager - Gestor de Huellas (Singleton Global)
561
+
562
+ Objeto global que **no requiere** `createObject()`. Accesible directamente como `fingerprintManager`:
563
+
564
+ ```javascript
565
+ fingerprintManager.setCallback({
566
+ onSuccess: function(result) {
567
+ var sPublicKey = result.getPublicKey();
568
+ ui.showToast("Huella verificada");
569
+ },
570
+ onFailure: function(nError, sErrorMessage) {
571
+ ui.showToast("Error: " + sErrorMessage);
572
+ }
573
+ });
574
+ fingerprintManager.listen();
575
+
576
+ // Detener escucha
577
+ fingerprintManager.stopListening();
578
+
579
+ // Abrir configuración de huellas
580
+ fingerprintManager.launchFingerprintSettings(); // Android
581
+ fingerprintManager.launch(); // iOS
582
+ ```
583
+