@craft-native/android 0.0.89 → 0.0.91
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 +103 -93
- package/package.json +4 -2
- package/templates/CraftBridge.kt.template +1951 -1193
- package/templates/CraftHealthConnect.kt.template +45 -6
- package/templates/CraftHealthConnectStub.kt.template +7 -1
- package/templates/CraftNative.kt.template +2231 -0
- package/templates/LocationRecordingService.kt.template +34 -9
- package/templates/MainActivity.kt.template +25 -2
- package/templates/proguard-rules.pro.template +4 -1
- package/templates/test-bridges.html +10 -33
- package/templates/CraftBridgeExtensions.kt.template +0 -383
- package/templates/CraftWidgetProvider.kt.template +0 -246
package/README.md
CHANGED
|
@@ -50,14 +50,14 @@ Build native Android apps with web technologies using Craft.
|
|
|
50
50
|
|
|
51
51
|
- **Device Info** - Device model, OS version, screen info
|
|
52
52
|
- **Network Status** - Connection type monitoring (WiFi/Cellular)
|
|
53
|
-
- **
|
|
53
|
+
- **Capability Reporting** - Unsupported app badges are reported honestly
|
|
54
54
|
- **App State** - Foreground/background detection
|
|
55
55
|
- **Flashlight** - Camera flash control
|
|
56
56
|
- **Open URL** - External browser launch
|
|
57
57
|
- **Vibration Pattern** - Custom vibration sequences
|
|
58
58
|
- **App Review** - Google Play In-App Review prompt
|
|
59
59
|
- **Screen Capture** - Take screenshots programmatically
|
|
60
|
-
- **Health/Fitness** -
|
|
60
|
+
- **Health/Fitness** - Health Connect integration
|
|
61
61
|
|
|
62
62
|
## Installation
|
|
63
63
|
|
|
@@ -83,7 +83,7 @@ Replace `app/src/main/assets/index.html` with your web app, or point to a dev se
|
|
|
83
83
|
```bash
|
|
84
84
|
craft android build --html-path ../dist/index.html
|
|
85
85
|
# or
|
|
86
|
-
craft android build --dev-server http://
|
|
86
|
+
craft android build --dev-server http://10.0.2.2:3456
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
### 3. Open in Android Studio
|
|
@@ -120,27 +120,32 @@ Edit `craft.config.json` in your Android project:
|
|
|
120
120
|
"enablePushNotifications": false,
|
|
121
121
|
"enableSecureStorage": true,
|
|
122
122
|
"enableGeolocation": true,
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"enableVideoRecording": true,
|
|
133
|
-
"enableMotionSensors": true,
|
|
134
|
-
"enableLocalDatabase": true,
|
|
135
|
-
"enableBluetooth": true,
|
|
136
|
-
"enableNFC": true,
|
|
137
|
-
"enableFitness": false,
|
|
138
|
-
"enableScreenCapture": true,
|
|
139
|
-
"minSdk": 24,
|
|
140
|
-
"targetSdk": 34
|
|
123
|
+
"enableBackgroundLocation": false,
|
|
124
|
+
"enableHealthConnect": false,
|
|
125
|
+
"enableKeepAwake": true,
|
|
126
|
+
"enableDeepLinks": true,
|
|
127
|
+
"urlSchemes": ["myapp"],
|
|
128
|
+
"trustedOrigins": ["https://app.example.com"],
|
|
129
|
+
"minSdk": 26,
|
|
130
|
+
"compileSdk": 36,
|
|
131
|
+
"targetSdk": 35
|
|
141
132
|
}
|
|
142
133
|
```
|
|
143
134
|
|
|
135
|
+
Only the fields shown above are generator options. Enabling background location
|
|
136
|
+
also enables foreground geolocation. Push notifications require a regular
|
|
137
|
+
`googleServicesFile` whose JSON contains a client matching the generated
|
|
138
|
+
Android package. Deep links require at least one valid URI scheme; scheme names
|
|
139
|
+
are normalized to lowercase.
|
|
140
|
+
Health Connect normalizes `minSdk` to at least 26 and `compileSdk` to at least 36.
|
|
141
|
+
A custom `appIconPath` must be a regular PNG, WebP, JPG, or GIF file; its supported
|
|
142
|
+
extension is preserved in the generated drawable resource.
|
|
143
|
+
|
|
144
|
+
Remote app and trusted-origin URLs must use HTTPS. Local development may use
|
|
145
|
+
HTTP with `localhost`, `127.0.0.1`, or the Android emulator host `10.0.2.2`.
|
|
146
|
+
Origins are normalized before they are stored, and a configured development
|
|
147
|
+
server is trusted automatically.
|
|
148
|
+
|
|
144
149
|
## JavaScript Bridge
|
|
145
150
|
|
|
146
151
|
Once Craft is initialized, the `window.craft` object is available:
|
|
@@ -215,18 +220,19 @@ await window.craft.db.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name
|
|
|
215
220
|
await window.craft.db.execute('INSERT INTO users (name) VALUES (?)', ['Alice']);
|
|
216
221
|
const users = await window.craft.db.query('SELECT * FROM users');
|
|
217
222
|
|
|
218
|
-
// Bluetooth LE Scanning
|
|
219
|
-
|
|
223
|
+
// Bluetooth LE Scanning. Rejects when the device has no adapter, Bluetooth is
|
|
224
|
+
// switched off, permission is denied, or the platform scanner cannot start.
|
|
225
|
+
await window.craft.bluetooth.startScan();
|
|
220
226
|
window.addEventListener('craftBluetoothDevice', (e) => {
|
|
221
227
|
console.log(e.detail.name, e.detail.address, e.detail.rssi);
|
|
222
228
|
});
|
|
223
|
-
window.craft.
|
|
229
|
+
window.craft.bluetooth.stopScan();
|
|
224
230
|
|
|
225
231
|
// NFC Tag Reading
|
|
226
232
|
const nfcData = await window.craft.scanNFC();
|
|
227
233
|
console.log(nfcData); // Tag content
|
|
228
234
|
|
|
229
|
-
// Health/Fitness (
|
|
235
|
+
// Health/Fitness (Health Connect)
|
|
230
236
|
await window.craft.requestFitnessAuthorization();
|
|
231
237
|
const steps = await window.craft.getFitnessData('steps', startDate, endDate);
|
|
232
238
|
|
|
@@ -270,9 +276,10 @@ const text = await window.craft.clipboard.read();
|
|
|
270
276
|
const device = window.craft.getDeviceInfo();
|
|
271
277
|
console.log(device.model, device.manufacturer, device.systemVersion);
|
|
272
278
|
|
|
273
|
-
// App
|
|
274
|
-
window.craft.
|
|
275
|
-
window.craft.
|
|
279
|
+
// App badges have no portable Android API, so this is always false.
|
|
280
|
+
if (window.craft.capabilities.appBadge) {
|
|
281
|
+
window.craft.setBadge(5);
|
|
282
|
+
}
|
|
276
283
|
|
|
277
284
|
// Network Status
|
|
278
285
|
const network = window.craft.getNetworkStatus();
|
|
@@ -369,15 +376,17 @@ window.craft.unlockOrientation(); // Allow all orientations
|
|
|
369
376
|
|
|
370
377
|
// ==================== Medium Value Bridges ====================
|
|
371
378
|
|
|
372
|
-
// Background Tasks
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
379
|
+
// Background Tasks are not implemented on Android. These methods reject
|
|
380
|
+
// instead of reporting that work was scheduled when no worker can run.
|
|
381
|
+
try {
|
|
382
|
+
await window.craft.backgroundTask.schedule('sync-data', {
|
|
383
|
+
delay: 900,
|
|
384
|
+
requiresNetwork: true,
|
|
385
|
+
requiresCharging: false
|
|
386
|
+
});
|
|
387
|
+
} catch (error) {
|
|
388
|
+
console.error(error);
|
|
389
|
+
}
|
|
381
390
|
|
|
382
391
|
// PDF Viewer (opens in external PDF app)
|
|
383
392
|
await window.craft.openPDF('https://example.com/document.pdf');
|
|
@@ -453,16 +462,10 @@ await window.craft.widget.reload();
|
|
|
453
462
|
|
|
454
463
|
// ==================== Google Assistant (App Actions) ====================
|
|
455
464
|
|
|
456
|
-
//
|
|
457
|
-
//
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
// Remove a voice action
|
|
461
|
-
await window.craft.siri.remove('open*app');
|
|
462
|
-
|
|
463
|
-
// Listen for voice assistant invocations
|
|
464
|
-
window.craft.siri.onInvoke((detail) => {
|
|
465
|
-
console.log('Voice action:', detail.action);
|
|
465
|
+
// App Actions are declared statically in app/src/main/res/xml/shortcuts.xml.
|
|
466
|
+
// Listen for incoming Google Assistant intents forwarded by the bridge.
|
|
467
|
+
window.addEventListener('craftVoiceAction', (event) => {
|
|
468
|
+
console.log('Voice action:', event.detail.action);
|
|
466
469
|
});
|
|
467
470
|
|
|
468
471
|
// ==================== Wear OS Connectivity ====================
|
|
@@ -516,54 +519,58 @@ Options:
|
|
|
516
519
|
|
|
517
520
|
- Android Studio with Android SDK
|
|
518
521
|
- JDK 17+
|
|
519
|
-
- Gradle 8.
|
|
522
|
+
- Gradle 8.11.1 (the generator creates a wrapper pinned to this version)
|
|
520
523
|
- ADB (for device deployment)
|
|
521
524
|
|
|
522
525
|
## Permissions
|
|
523
526
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
527
|
+
The generator adds manifest permissions from enabled capabilities:
|
|
528
|
+
|
|
529
|
+
| Option | Android permissions |
|
|
530
|
+
| --- | --- |
|
|
531
|
+
| `enableSpeechRecognition` | `RECORD_AUDIO` |
|
|
532
|
+
| `enableCamera` | `CAMERA` |
|
|
533
|
+
| `enableHaptics` | `VIBRATE` |
|
|
534
|
+
| `enableBiometric` | `USE_BIOMETRIC` |
|
|
535
|
+
| `enableGeolocation` | `ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION` |
|
|
536
|
+
| `enableBackgroundLocation` | foreground location plus `ACCESS_BACKGROUND_LOCATION` and foreground-service permissions |
|
|
537
|
+
| `enablePushNotifications` | `POST_NOTIFICATIONS` |
|
|
538
|
+
| `enableKeepAwake` | `WAKE_LOCK` |
|
|
539
|
+
| `enableHealthConnect` | the configured Health Connect read/write permissions |
|
|
540
|
+
|
|
541
|
+
Use `permissions.check('location')` and `permissions.request('location')` from
|
|
542
|
+
`craft-native/mobile` for runtime authorization. Android precise and
|
|
543
|
+
approximate access both count as a granted foreground location permission;
|
|
544
|
+
foreground fixes, watches, and recording accept either grant, with accuracy
|
|
545
|
+
controlled by Android. Obtaining a fix is still a separate operation. See the
|
|
546
|
+
[Permissions API](../../docs/api/mobile/permissions.md) for status semantics.
|
|
547
|
+
|
|
548
|
+
## Promise Lifecycle and Concurrency
|
|
549
|
+
|
|
550
|
+
Promise-based bridge calls have one active request slot per native callback
|
|
551
|
+
channel. A second request on the same channel rejects immediately with an
|
|
552
|
+
`already in progress` error, without replacing the first request's callbacks.
|
|
553
|
+
Calls on different channels can run concurrently. Some related methods share a
|
|
554
|
+
channel—for example, shortcut mutations serialize with other shortcut
|
|
555
|
+
mutations—so callers should await one before starting the next.
|
|
556
|
+
|
|
557
|
+
Native success, error, cancellation, and timeout callbacks settle a request at
|
|
558
|
+
most once. Synchronous JavaScript-interface failures are converted to Promise
|
|
559
|
+
rejections. Permission requests use request IDs and a 30-second timeout, while
|
|
560
|
+
one-shot location requests use a 15-second timeout. Destroying the bridge
|
|
561
|
+
rejects all pending work and any new request, while callbacks queued by the old
|
|
562
|
+
Activity lifecycle are ignored. Reinjecting the bridge rejects old work and
|
|
563
|
+
opens a fresh runtime.
|
|
564
|
+
|
|
565
|
+
## Template Validation
|
|
566
|
+
|
|
567
|
+
Android projects generated with the default and capability-heavy configurations
|
|
568
|
+
are assembled in CI, and their Kotlin permission tests are run. Contributors
|
|
569
|
+
with JDK 17, Android SDK 36, and Gradle 8.11.1 installed can run the same check:
|
|
533
570
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
<!-- Biometric -->
|
|
539
|
-
<uses-permission android:name="android.permission.USE*BIOMETRIC" />
|
|
540
|
-
|
|
541
|
-
<!-- Vibration -->
|
|
542
|
-
<uses-permission android:name="android.permission.VIBRATE" />
|
|
543
|
-
|
|
544
|
-
<!-- NFC -->
|
|
545
|
-
<uses-permission android:name="android.permission.NFC" />
|
|
546
|
-
<uses-feature android:name="android.hardware.nfc" android:required="false" />
|
|
547
|
-
|
|
548
|
-
<!-- Bluetooth -->
|
|
549
|
-
<uses-permission android:name="android.permission.BLUETOOTH" />
|
|
550
|
-
<uses-permission android:name="android.permission.BLUETOOTH*ADMIN" />
|
|
551
|
-
<uses-permission android:name="android.permission.BLUETOOTH*SCAN" />
|
|
552
|
-
<uses-permission android:name="android.permission.BLUETOOTH*CONNECT" />
|
|
553
|
-
|
|
554
|
-
<!-- Fitness (Google Fit) -->
|
|
555
|
-
<uses-permission android:name="android.permission.ACTIVITY*RECOGNITION" />
|
|
556
|
-
|
|
557
|
-
<!-- Contacts -->
|
|
558
|
-
<uses-permission android:name="android.permission.READ*CONTACTS" />
|
|
559
|
-
<uses-permission android:name="android.permission.WRITE*CONTACTS" />
|
|
560
|
-
|
|
561
|
-
<!-- Calendar -->
|
|
562
|
-
<uses-permission android:name="android.permission.READ*CALENDAR" />
|
|
563
|
-
<uses-permission android:name="android.permission.WRITE*CALENDAR" />
|
|
564
|
-
|
|
565
|
-
<!-- Notifications (Android 13+) -->
|
|
566
|
-
<uses-permission android:name="android.permission.POST*NOTIFICATIONS" />
|
|
571
|
+
```bash
|
|
572
|
+
cd packages/android
|
|
573
|
+
bun run test:templates
|
|
567
574
|
```
|
|
568
575
|
|
|
569
576
|
## Development Mode
|
|
@@ -574,14 +581,16 @@ For hot-reload during development:
|
|
|
574
581
|
# Terminal 1: Start your dev server
|
|
575
582
|
bun run dev # e.g., http://localhost:3456
|
|
576
583
|
|
|
577
|
-
# Terminal 2: Build
|
|
578
|
-
craft android build --dev-server http://
|
|
584
|
+
# Terminal 2: Build for an Android emulator
|
|
585
|
+
craft android build --dev-server http://10.0.2.2:3456
|
|
579
586
|
|
|
580
587
|
# Open in Android Studio and run on device
|
|
581
588
|
craft android open
|
|
582
589
|
```
|
|
583
590
|
|
|
584
|
-
The
|
|
591
|
+
The emulator resolves `10.0.2.2` to the host machine. For a physical device,
|
|
592
|
+
use an HTTPS development endpoint. The app will load from that server instead
|
|
593
|
+
of bundled HTML.
|
|
585
594
|
|
|
586
595
|
## Publishing
|
|
587
596
|
|
|
@@ -597,6 +606,7 @@ This will:
|
|
|
597
606
|
2. Output path for manual upload to Play Console
|
|
598
607
|
|
|
599
608
|
For automated uploads, integrate with fastlane:
|
|
609
|
+
|
|
600
610
|
```bash
|
|
601
611
|
fastlane supply --aab ./android/app/build/outputs/bundle/release/app-release.aab
|
|
602
612
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@craft-native/android",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.91",
|
|
4
4
|
"homepage": "https://github.com/craft-native/craft/tree/main/packages/android#readme",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "bun build.ts"
|
|
22
|
+
"build": "bun build.ts",
|
|
23
|
+
"test": "bun test",
|
|
24
|
+
"test:templates": "bun scripts/compile-templates.ts"
|
|
23
25
|
},
|
|
24
26
|
"files": [
|
|
25
27
|
"dist",
|