@iternio/react-native-auto-play 0.1.18 → 0.2.0-alpha.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 +152 -8
- package/android/build.gradle +15 -1
- package/android/gradle.properties +1 -1
- package/android/src/{main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoTelemetryObserver.kt → auto/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidTelemetryObserver.kt} +31 -76
- package/android/src/automotive/AndroidManifest.xml +91 -0
- package/android/src/automotive/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidTelemetryObserver.kt +191 -0
- package/android/src/main/AndroidManifest.xml +0 -10
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoScreen.kt +3 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoTelemetryHolder.kt +97 -19
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidAutoTelemetry.kt +39 -3
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridSignInTemplate.kt +22 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/TelemetryObserver.kt +56 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VirtualRenderer.kt +15 -10
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/AutomotivePermissionRequestTemplate.kt +103 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/GridTemplate.kt +0 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt +8 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/SignInTemplate.kt +159 -0
- package/ios/extensions/CarPlayExtensions.swift +4 -2
- package/ios/extensions/NitroImageExtensions.swift +4 -4
- package/ios/hybrid/HybridAutoPlay.swift +31 -42
- package/ios/hybrid/HybridCluster.swift +4 -2
- package/ios/hybrid/HybridGridTemplate.swift +11 -11
- package/ios/hybrid/HybridInformationTemplate.swift +12 -13
- package/ios/hybrid/HybridListTemplate.swift +12 -13
- package/ios/hybrid/HybridMapTemplate.swift +13 -16
- package/ios/hybrid/HybridMessageTemplate.swift +7 -4
- package/ios/hybrid/HybridSearchTemplate.swift +12 -13
- package/ios/scenes/AutoPlayInterfaceController.swift +41 -13
- package/ios/scenes/AutoPlayScene.swift +2 -1
- package/ios/scenes/AutoPlaySceneViewController.swift +8 -2
- package/ios/scenes/DashboardSceneDelegate.swift +15 -7
- package/ios/scenes/HeadUnitSceneDelegate.swift +7 -5
- package/ios/scenes/WindowApplicationSceneDelegate.swift +1 -1
- package/ios/templates/AutoPlayTemplate.swift +23 -15
- package/ios/templates/GridTemplate.swift +23 -16
- package/ios/templates/InformationTemplate.swift +12 -11
- package/ios/templates/ListTemplate.swift +11 -11
- package/ios/templates/MapTemplate.swift +44 -42
- package/ios/templates/MessageTemplate.swift +8 -12
- package/ios/templates/Parser.swift +2 -1
- package/ios/templates/SearchTemplate.swift +19 -17
- package/ios/templates/TemplateStore.swift +17 -9
- package/ios/utils/RootModule.swift +19 -12
- package/ios/utils/SymbolFont.swift +2 -1
- package/ios/utils/ViewUtils.swift +2 -2
- package/lib/hooks/useAndroidAutoTelemetry.d.ts +22 -4
- package/lib/hooks/useAndroidAutoTelemetry.js +52 -24
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/specs/AndroidAutoTelemetry.nitro.d.ts +14 -1
- package/lib/types/Telemetry.d.ts +27 -0
- package/lib/types/Telemetry.js +7 -0
- package/nitro.json +3 -0
- package/nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake +3 -0
- package/nitrogen/generated/android/ReactNativeAutoPlayOnLoad.cpp +12 -2
- package/nitrogen/generated/android/c++/JBooleanTelemetryItem.hpp +61 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_Telemetry_.hpp +87 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +10 -10
- package/nitrogen/generated/android/c++/JHybridAndroidAutoTelemetrySpec.cpp +41 -5
- package/nitrogen/generated/android/c++/JHybridAndroidAutoTelemetrySpec.hpp +2 -1
- package/nitrogen/generated/android/c++/JHybridSignInTemplateSpec.cpp +133 -0
- package/nitrogen/generated/android/c++/JHybridSignInTemplateSpec.hpp +66 -0
- package/nitrogen/generated/android/c++/JInputSignIn.hpp +103 -0
- package/nitrogen/generated/android/c++/JKeyboardType.hpp +65 -0
- package/nitrogen/generated/android/c++/JPermissionRequestResult.hpp +98 -0
- package/nitrogen/generated/android/c++/JPinSignIn.hpp +63 -0
- package/nitrogen/generated/android/c++/JQrSignIn.hpp +63 -0
- package/nitrogen/generated/android/c++/JSignInMethods.hpp +65 -0
- package/nitrogen/generated/android/c++/JSignInTemplateConfig.hpp +217 -0
- package/nitrogen/generated/android/c++/JTelemetry.hpp +25 -3
- package/nitrogen/generated/android/c++/JTextInputType.hpp +59 -0
- package/nitrogen/generated/android/c++/JVariant_QrSignIn_PinSignIn_InputSignIn.cpp +30 -0
- package/nitrogen/generated/android/c++/JVariant_QrSignIn_PinSignIn_InputSignIn.hpp +99 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/AssetImage.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/AutoText.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/BooleanTelemetryItem.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Distance.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/DurationWithTimeZone.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/{Func_void_std__optional_Telemetry__std__optional_std__string_.kt → Func_void_std__optional_Telemetry_.kt} +14 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__string.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GlyphImage.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridTemplateConfig.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidAutoTelemetrySpec.kt +7 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridSignInTemplateSpec.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ImageLane.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/InformationTemplateConfig.kt +10 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/InputSignIn.kt +63 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/KeyboardType.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/LaneGuidance.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ListTemplateConfig.kt +10 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Location.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/MapTemplateConfig.kt +18 -18
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/MessageTemplateConfig.kt +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NavigationAlertAction.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroAction.kt +7 -7
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroAttributedString.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroAttributedStringImage.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroBaseMapTemplateConfig.kt +10 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroColor.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroGridButton.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroLoadingManeuver.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroMapButton.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroMessageManeuver.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroNavigationAlert.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroRoutingManeuver.kt +13 -13
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroRow.kt +7 -7
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroSection.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NumericTelemetryItem.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/PermissionRequestResult.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/PinSignIn.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Point.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/PreferredImageLane.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/QrSignIn.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/RouteChoice.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/SafeAreaInsets.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/SearchTemplateConfig.kt +10 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/SignInMethods.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/SignInTemplateConfig.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/StringTelemetryItem.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Telemetry.kt +24 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TextInputType.kt +21 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TravelEstimates.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TripConfig.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TripPoint.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TripPreviewTextConfiguration.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TripSelectorCallback.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/TripsConfig.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Variant_QrSignIn_PinSignIn_InputSignIn.kt +72 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/VehicleTelemetryItem.kt +4 -4
- package/nitrogen/generated/shared/c++/BooleanTelemetryItem.hpp +79 -0
- package/nitrogen/generated/shared/c++/HybridAndroidAutoTelemetrySpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridAndroidAutoTelemetrySpec.hpp +7 -1
- package/nitrogen/generated/shared/c++/HybridSignInTemplateSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridSignInTemplateSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/InputSignIn.hpp +113 -0
- package/nitrogen/generated/shared/c++/KeyboardType.hpp +64 -0
- package/nitrogen/generated/shared/c++/PermissionRequestResult.hpp +80 -0
- package/nitrogen/generated/shared/c++/PinSignIn.hpp +81 -0
- package/nitrogen/generated/shared/c++/QrSignIn.hpp +81 -0
- package/nitrogen/generated/shared/c++/SignInMethods.hpp +64 -0
- package/nitrogen/generated/shared/c++/SignInTemplateConfig.hpp +138 -0
- package/nitrogen/generated/shared/c++/Telemetry.hpp +25 -2
- package/nitrogen/generated/shared/c++/TextInputType.hpp +62 -0
- package/package.json +3 -2
- package/src/hooks/useAndroidAutoTelemetry.ts +80 -27
- package/src/index.ts +2 -0
- package/src/specs/AndroidAutoTelemetry.nitro.ts +19 -1
- package/src/specs/SignInTemplate.nitro.ts +10 -0
- package/src/templates/SignInTemplate.ts +117 -0
- package/src/types/SignInMethod.ts +41 -0
- package/src/types/Telemetry.ts +29 -0
- package/lib/hooks/useIsAutoPlayFocused.d.ts +0 -7
- package/lib/hooks/useIsAutoPlayFocused.js +0 -20
- package/lib/hybrid.d.ts +0 -2
- package/lib/hybrid.js +0 -2
- package/lib/specs/AutomotivePermissionRequestTemplate.d.ts +0 -11
- package/lib/specs/AutomotivePermissionRequestTemplate.js +0 -1
- package/lib/specs/AutomotivePermissionRequestTemplate.nitro.d.ts +0 -11
- package/lib/specs/AutomotivePermissionRequestTemplate.nitro.js +0 -1
- package/lib/templates/AutomotivePermissionRequestTemplate.d.ts +0 -23
- package/lib/templates/AutomotivePermissionRequestTemplate.js +0 -18
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_Telemetry__std__optional_std__string_.hpp +0 -85
package/README.md
CHANGED
|
@@ -220,6 +220,84 @@ You can customize certain behaviors of the library on Android Auto by setting pr
|
|
|
220
220
|
```
|
|
221
221
|
The default values are `1000` for the delay and `500` for the duration.
|
|
222
222
|
|
|
223
|
+
### Android Automotive
|
|
224
|
+
|
|
225
|
+
This library also supports Android Automotive. To enable Android Automotive support, you need to configure a few properties in your Android project.
|
|
226
|
+
|
|
227
|
+
- **`minSdkVersion`**: The minimum API level for Android Automotive is 29. You must set `minSdkVersion` to at least `29`. For Android Auto, the minimum is `24`.
|
|
228
|
+
|
|
229
|
+
- **`isAutomotiveApp` flag**: You need to inform the library if this is an Automotive app by setting the `isAutomotiveApp` property to `true`. For Android Auto, it should be `false`.
|
|
230
|
+
|
|
231
|
+
You can set these properties directly in your `android/gradle.properties` file:
|
|
232
|
+
```properties
|
|
233
|
+
# For Android Automotive
|
|
234
|
+
minSdkVersion=29
|
|
235
|
+
isAutomotiveApp=true
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Alternatively, if you need to support different build variants (e.g., for both Android Auto and Android Automotive from the same codebase), using `react-native-config` is the recommended approach.
|
|
239
|
+
|
|
240
|
+
1. Install `react-native-config`:
|
|
241
|
+
```bash
|
|
242
|
+
yarn add react-native-config
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
2. Create different `.env` files for your variants. Create a default `.env` for Android Auto:
|
|
246
|
+
```
|
|
247
|
+
# .env (for Android Auto)
|
|
248
|
+
isAutomotiveApp=false
|
|
249
|
+
minSdkVersion=24
|
|
250
|
+
```
|
|
251
|
+
And an `.env.automotive` for Android Automotive:
|
|
252
|
+
```
|
|
253
|
+
# .env.automotive
|
|
254
|
+
minSdkVersion=29
|
|
255
|
+
isAutomotiveApp=true
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
3. In your `android/app/build.gradle`, apply the configuration from `react-native-config` based on your build flavors.
|
|
259
|
+
```groovy
|
|
260
|
+
// android/app/build.gradle
|
|
261
|
+
|
|
262
|
+
project.ext.envConfigFiles = [
|
|
263
|
+
automotive: ".env.automotive",
|
|
264
|
+
// other flavors...
|
|
265
|
+
]
|
|
266
|
+
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
|
267
|
+
|
|
268
|
+
if (project.ext.has("env")) {
|
|
269
|
+
rootProject.ext.minSdkVersion = project.ext.env.minSdkVersion
|
|
270
|
+
rootProject.ext.isAutomotiveApp = project.ext.env.isAutomotiveApp
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
Adjust to the build variants your app provides. Check the example app for details.
|
|
274
|
+
|
|
275
|
+
This approach allows you to dynamically set the required flags based on your build variant, which is demonstrated in the example app.
|
|
276
|
+
|
|
277
|
+
#### App launch on Android Automotive
|
|
278
|
+
|
|
279
|
+
Android Automotive requires you to remove your app activity since it invokes the libraries Android Auto service in a different way. Not doing so will bring up 2 app icons on the Android Automotive launcher.
|
|
280
|
+
To get rid of your default activity, do an automotive specific build variant and add this AndroidManifest.xml for that variant.
|
|
281
|
+
```xml
|
|
282
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
283
|
+
xmlns:tools="http://schemas.android.com/tools">
|
|
284
|
+
|
|
285
|
+
<application>
|
|
286
|
+
<activity
|
|
287
|
+
android:name=".MainActivity"
|
|
288
|
+
tools:node="remove" /> <!-- remove main activity -->
|
|
289
|
+
</application>
|
|
290
|
+
|
|
291
|
+
</manifest>
|
|
292
|
+
```
|
|
293
|
+
For details check the example app and its build variants.
|
|
294
|
+
|
|
295
|
+
#### A Note on Android Studio
|
|
296
|
+
|
|
297
|
+
When using build variants, Android Studio may not be aware of the selected variant during a Gradle sync. This can cause the IDE to show the incorrect implementation of native classes like `AndroidTelemetryObserver` (e.g., it might show the Android Auto version instead of the Automotive version).
|
|
298
|
+
|
|
299
|
+
To work around this and allow for debugging or enhancing the Android Automotive-specific implementation, you can temporarily set the automotive flags in your `gradle.properties` file or your default `.env` file before running a Gradle sync.
|
|
300
|
+
|
|
223
301
|
## Icons
|
|
224
302
|
The library is using [Material Symbols](https://fonts.google.com/icons) for iconography. The font is bundled with the library, so no extra setup is required. You can use these icons on both Android Auto and CarPlay.
|
|
225
303
|
|
|
@@ -431,13 +509,39 @@ Below is a concise overview of the most important props per template. Optional p
|
|
|
431
509
|
| `headerActions` | `HeaderActionsAndroid<MessageTemplate>` | ❌ | Android-only header actions. |
|
|
432
510
|
| `mapConfig` | `BaseMapTemplateConfig<MessageTemplate>` | ❌ | Android map-with-content layout. |
|
|
433
511
|
|
|
512
|
+
#### SignInTemplateConfig (Android-only)
|
|
513
|
+
|
|
514
|
+
| Prop | Type | Required | Notes |
|
|
515
|
+
| --- | --- | --- | --- |
|
|
516
|
+
| `signInMethod` | `SignInMethod` | ✅ | The sign-in method configuration. Can be QRSignIn, PinSignIn, InputSignIn. |
|
|
517
|
+
| `title` | `string` | ❌ | Header title. |
|
|
518
|
+
| `additionalText` | `string` | ❌ | Additional descriptive text. |
|
|
519
|
+
| `instructions` | `string` | ❌ | Sign-in Instructions text. |
|
|
520
|
+
| `actions` | `ActionButton<SignInTemplate>[]` | ❌ | Up to 2 buttons. |
|
|
521
|
+
| `headerActions` | `SignInHeaderActions<SignInTemplate>` | ❌ | Header actions. See **Header Actions** below. |
|
|
522
|
+
|
|
523
|
+
**SignInMethod**
|
|
524
|
+
|
|
525
|
+
| Method | Type | Notes |
|
|
526
|
+
| --- | --- | --- |
|
|
527
|
+
| QR | `QrSignIn` | QR Code sign in |
|
|
528
|
+
| PIN | `PinSignIn` | PIN Code sign in (1–12 characters) |
|
|
529
|
+
| Input | `InputSignIn` | Text sign in, for example mail/username and password |
|
|
530
|
+
|
|
531
|
+
For InputSignIn the keyboard and input fields can be configured with following properties:
|
|
532
|
+
|
|
533
|
+
**KeyboardType enum:** `DEFAULT`, `EMAIL`, `PHONE`, `NUMBER`
|
|
534
|
+
|
|
535
|
+
**TextInputType enum:** `PASSWORD`, `DEFAULT`
|
|
536
|
+
|
|
537
|
+
|
|
434
538
|
### Header Actions (Important)
|
|
435
539
|
|
|
436
540
|
On Android, header actions may be omitted, although this is not recommended. If `headerActions` is `undefined`, the system automatically renders the app icon in the header. Because Android Auto enforces monochrome icons, this can result in a poor-looking button.
|
|
437
541
|
|
|
438
542
|
**Use these rules to avoid crashes:**
|
|
439
543
|
|
|
440
|
-
1. **For List/Grid/Information/Search/Message templates on Android**, always pass the structured object format (alignment is implicit via `startHeaderAction`/`endHeaderActions`):
|
|
544
|
+
1. **For List/Grid/Information/Search/Message/SignIn templates on Android**, always pass the structured object format (alignment is implicit via `startHeaderAction`/`endHeaderActions`):
|
|
441
545
|
|
|
442
546
|
```ts
|
|
443
547
|
const headerActions: HeaderActions<MyTemplate> = {
|
|
@@ -657,20 +761,39 @@ new ListTemplate({
|
|
|
657
761
|
- `useVoiceInput()`: Access voice input functionality - Android Auto only.
|
|
658
762
|
- `useSafeAreaInsets()`: Get safe area insets for any root component.
|
|
659
763
|
- `useFocusedEffect()`: A useEffect alternative that executes when the specified component is visible to the user - use any of the `AutoPlayModules` enum or a cluster uuid to sepcify the component the effect should listen for.
|
|
660
|
-
- `useAndroidAutoTelemetry()`: Access to car telemetry data on Android Auto.
|
|
764
|
+
- `useAndroidAutoTelemetry()`: Access to car telemetry data on Android Auto and Android Automotive.
|
|
661
765
|
```tsx
|
|
662
766
|
import {
|
|
663
767
|
useAndroidAutoTelemetry,
|
|
664
768
|
AndroidAutoTelemetryPermissions,
|
|
769
|
+
AndroidAutomotiveTelemetryPermissions,
|
|
665
770
|
} from '@iternio/react-native-auto-play';
|
|
771
|
+
import Config from 'react-native-config';
|
|
666
772
|
|
|
667
773
|
const MyComponent = () => {
|
|
668
774
|
const { telemetry, permissionsGranted, error } = useAndroidAutoTelemetry({
|
|
669
|
-
requiredPermissions:
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
775
|
+
requiredPermissions:
|
|
776
|
+
Config.isAutomotiveApp === 'true'
|
|
777
|
+
? [
|
|
778
|
+
AndroidAutomotiveTelemetryPermissions.Info,
|
|
779
|
+
AndroidAutomotiveTelemetryPermissions.Speed,
|
|
780
|
+
AndroidAutomotiveTelemetryPermissions.Energy,
|
|
781
|
+
AndroidAutomotiveTelemetryPermissions.ExteriorEnvironment,
|
|
782
|
+
AndroidAutomotiveTelemetryPermissions.EnergyPorts,
|
|
783
|
+
]
|
|
784
|
+
: [
|
|
785
|
+
AndroidAutoTelemetryPermissions.Speed,
|
|
786
|
+
AndroidAutoTelemetryPermissions.Energy,
|
|
787
|
+
AndroidAutoTelemetryPermissions.Odometer,
|
|
788
|
+
],
|
|
789
|
+
automotivePermissionRequest:
|
|
790
|
+
Config.isAutomotiveApp === 'true'
|
|
791
|
+
? {
|
|
792
|
+
cancelButtonText: 'Cancel',
|
|
793
|
+
grantButtonText: 'Grant',
|
|
794
|
+
message: 'Grant permission for vehicle telemetry access.',
|
|
795
|
+
}
|
|
796
|
+
: undefined,
|
|
674
797
|
});
|
|
675
798
|
|
|
676
799
|
if (!permissionsGranted) {
|
|
@@ -688,6 +811,14 @@ new ListTemplate({
|
|
|
688
811
|
<Text>Battery Level: {telemetry?.batteryLevel?.value}%</Text>
|
|
689
812
|
<Text>Range: {telemetry?.range?.value} km</Text>
|
|
690
813
|
<Text>Odometer: {telemetry?.odometer?.value} km</Text>
|
|
814
|
+
<Text>Selected Gear: {telemetry?.selectedGear?.value}</Text>
|
|
815
|
+
<Text>Outside Temperature: {telemetry?.envOutsideTemperature?.value}°C</Text>
|
|
816
|
+
<Text>EV Charge Port Connected: {String(telemetry?.evChargePortConnected?.value)}</Text>
|
|
817
|
+
<Text>EV Battery Charge Rate: {telemetry?.evBatteryInstantaneousChargeRate?.value} kW</Text>
|
|
818
|
+
<Text>Parking Brake On: {String(telemetry?.parkingBrakeOn?.value)}</Text>
|
|
819
|
+
<Text>Vehicle Name: {telemetry?.vehicle?.name?.value}</Text>
|
|
820
|
+
<Text>Vehicle Manufacturer: {telemetry?.vehicle?.manufacturer?.value}</Text>
|
|
821
|
+
<Text>Vehicle Year: {telemetry?.vehicle?.year?.value}</Text>
|
|
691
822
|
</View>
|
|
692
823
|
);
|
|
693
824
|
}
|
|
@@ -699,6 +830,15 @@ new ListTemplate({
|
|
|
699
830
|
- `range`: Range in km.
|
|
700
831
|
- `odometer`: Odometer in km.
|
|
701
832
|
- `vehicle`: Vehicle information (model name, model year, manufacturer).
|
|
833
|
+
- `selectedGear`: The currently selected gear, one of the `VehicleGear` enum:
|
|
834
|
+
- Neutral = 1
|
|
835
|
+
- Reverse = 2
|
|
836
|
+
- Park = 4
|
|
837
|
+
- Drive = 8
|
|
838
|
+
- `envOutsideTemperature`: The outside temperature in °C.
|
|
839
|
+
- `evChargePortConnected`: Whether the EV charge port is connected.
|
|
840
|
+
- `evBatteryInstantaneousChargeRate`: The instantaneous charge rate of the EV battery in kW.
|
|
841
|
+
- `parkingBrakeOn`: Whether the parking brake is on.
|
|
702
842
|
|
|
703
843
|
|
|
704
844
|
### Scenes
|
|
@@ -735,7 +875,7 @@ CarPlayDashboard.setButtons([
|
|
|
735
875
|
|
|
736
876
|
### iOS
|
|
737
877
|
|
|
738
|
-
- **Broken exceptions with `react-native-skia`**: When using `react-native-skia` up to version `2.4.
|
|
878
|
+
- **Broken exceptions with `react-native-skia`**: When using `react-native-skia` up to version `2.4.14`, exceptions on iOS are not reported correctly. This is fixed in newer versions of `react-native-skia`. For more details, see this [pull request](https://github.com/Shopify/react-native-skia/pull/3595) and [issue](https://github.com/Shopify/react-native-skia/issues/3635).
|
|
739
879
|
- **AppState on iOS**: The `AppState` module from React Native does not work correctly on iOS because this library uses scenes, which are not supported by the stock `AppState` module. This library provides a custom state listener that works for both Android and iOS. Use `HybridAutoPlay.addListenerRenderState` instead of `AppState`.
|
|
740
880
|
- **Timers stop on screen lock**: iOS stops all timers when the device's main screen is turned off. To ensure timers continue to run (which is often necessary for background tasks related to autoplay), a patch for `react-native` is required. A patch is included in the root `patches/` directory and can be applied using `patch-package`.
|
|
741
881
|
- **expo-splash-screen stuck on iOS**: The `expo-splash-screen` module is broken on iOS because it does not support scenes, which are used by this library. This can cause the splash screen to be stuck on either the mobile device or on CarPlay. To fix this, a patch for `expo-splash-screen` is included in the root `patches/` directory and can be applied using `patch-package`. After applying the patch, you can hide the splash screen for a specific scene by passing the module name to the `hide` or `hideAsync` function. The module name can be one of the values from the `AutoPlayModules` enum or the UUID of a cluster screen.
|
|
@@ -749,6 +889,10 @@ CarPlayDashboard.setButtons([
|
|
|
749
889
|
// Hide the splash screen for the CarPlay screen
|
|
750
890
|
hideAsync(AutoPlayModules.AutoPlayRoot);
|
|
751
891
|
```
|
|
892
|
+
### Android
|
|
893
|
+
- **Broken exceptions with `react-native`** up to version 0.79
|
|
894
|
+
When using react-native before 0.80.0 exceptions are broken and are reported as `Unknown runtime_error` or similar.
|
|
895
|
+
See [this issue](https://github.com/mrousavy/nitro/issues/382) for details.
|
|
752
896
|
|
|
753
897
|
## Contributing
|
|
754
898
|
|
package/android/build.gradle
CHANGED
|
@@ -124,8 +124,20 @@ android {
|
|
|
124
124
|
"${project.buildDir}/generated/source/codegen/java"
|
|
125
125
|
]
|
|
126
126
|
}
|
|
127
|
+
|
|
128
|
+
if (getExtOrDefault("isAutomotiveApp") == "true") {
|
|
129
|
+
java.srcDirs += 'src/automotive/java'
|
|
130
|
+
manifest.srcFile 'src/automotive/AndroidManifest.xml'
|
|
131
|
+
} else {
|
|
132
|
+
java.srcDirs += 'src/auto/java'
|
|
133
|
+
manifest.srcFile 'src/main/AndroidManifest.xml'
|
|
134
|
+
}
|
|
127
135
|
}
|
|
128
136
|
}
|
|
137
|
+
|
|
138
|
+
if (getExtOrDefault("isAutomotiveApp") == "true") {
|
|
139
|
+
useLibrary 'android.car'
|
|
140
|
+
}
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
repositories {
|
|
@@ -133,7 +145,6 @@ repositories {
|
|
|
133
145
|
google()
|
|
134
146
|
}
|
|
135
147
|
|
|
136
|
-
|
|
137
148
|
dependencies {
|
|
138
149
|
// For < 0.71, this will be from the local maven repo
|
|
139
150
|
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
@@ -151,5 +162,8 @@ dependencies {
|
|
|
151
162
|
println("☎️ Enjoy your nitro powered Android Auto app!")
|
|
152
163
|
implementation "androidx.car.app:app-projected:1.7.0"
|
|
153
164
|
}
|
|
165
|
+
|
|
166
|
+
implementation 'com.google.android.gms:play-services-base:18.3.0'
|
|
167
|
+
implementation 'com.google.android.gms:play-services-auth:21.0.0'
|
|
154
168
|
}
|
|
155
169
|
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
package com.margelo.nitro.swe.iternio.reactnativeautoplay
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import android.os.Handler
|
|
5
|
-
import android.os.Looper
|
|
6
|
-
import android.util.Log
|
|
7
3
|
import androidx.car.app.CarContext
|
|
8
4
|
import androidx.car.app.hardware.CarHardwareManager
|
|
9
5
|
import androidx.car.app.hardware.common.CarValue
|
|
@@ -15,23 +11,27 @@ import androidx.car.app.hardware.info.Speed
|
|
|
15
11
|
import androidx.car.app.versioning.CarAppApiLevels
|
|
16
12
|
import androidx.core.content.ContextCompat
|
|
17
13
|
|
|
18
|
-
object
|
|
19
|
-
private var telemetryCallbacks: MutableList<(telemetry: Telemetry?, error: String?) -> Unit> =
|
|
20
|
-
ArrayList();
|
|
21
|
-
|
|
22
|
-
private var isRunning = false
|
|
14
|
+
object AndroidTelemetryObserver : TelemetryObserver() {
|
|
23
15
|
private var carContext: CarContext? = null
|
|
24
16
|
|
|
25
|
-
private val
|
|
26
|
-
|
|
17
|
+
private val mModelListener = OnCarDataAvailableListener<Model> { model ->
|
|
18
|
+
val name = if (model.name.status == CarValue.STATUS_SUCCESS) {
|
|
19
|
+
model.name.value
|
|
20
|
+
} else null
|
|
21
|
+
|
|
22
|
+
val manufacturer = if (model.manufacturer.status == CarValue.STATUS_SUCCESS) {
|
|
23
|
+
model.manufacturer.value
|
|
24
|
+
} else null
|
|
25
|
+
|
|
26
|
+
val year = if (model.year.status == CarValue.STATUS_SUCCESS) {
|
|
27
|
+
model.year.value
|
|
28
|
+
} else null
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
telemetryHolder.updateVehicle(it)
|
|
30
|
+
telemetryHolder.updateVehicle(name, manufacturer, year)
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
tlm?.let {
|
|
32
|
+
telemetryHolder.toTelemetry()?.let {
|
|
33
33
|
telemetryCallbacks.forEach { callback ->
|
|
34
|
-
callback(
|
|
34
|
+
callback(it)
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -70,51 +70,13 @@ object AndroidAutoTelemetryObserver {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (tlm != null) {
|
|
78
|
-
telemetryCallbacks.forEach { callback ->
|
|
79
|
-
callback(tlm, null)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
handler.postDelayed(this, BuildConfig.TELEMETRY_UPDATE_INTERVAL)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
fun addListener(callback: (Telemetry?, String?) -> Unit): () -> Unit {
|
|
88
|
-
telemetryCallbacks.add(callback)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// start is called every time a new listener is registered, so the single shot values are still requested and returned immediately
|
|
92
|
-
try {
|
|
93
|
-
startTelemetryObserver()
|
|
94
|
-
} catch (err: Exception) {
|
|
95
|
-
callback(null, err.message)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
telemetryCallbacks.remove(callback)
|
|
101
|
-
if (telemetryCallbacks.isEmpty()) {
|
|
102
|
-
stopTelemetryObserver()
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
fun startTelemetryObserver(
|
|
109
|
-
) {
|
|
110
|
-
val carContext =
|
|
111
|
-
AndroidAutoSession.Companion.getCarContext(AndroidAutoSession.Companion.ROOT_SESSION)
|
|
112
|
-
?: throw IllegalArgumentException(
|
|
113
|
-
"Car context not available, failed to start telemetry"
|
|
114
|
-
)
|
|
73
|
+
override fun startTelemetryObserver(): Boolean {
|
|
74
|
+
val carContext = AndroidAutoSession.getRootContext() ?: throw IllegalArgumentException(
|
|
75
|
+
"Car context not available, failed to start telemetry"
|
|
76
|
+
)
|
|
115
77
|
|
|
116
78
|
|
|
117
|
-
|
|
79
|
+
AndroidTelemetryObserver.carContext = carContext
|
|
118
80
|
if (carContext.carAppApiLevel < CarAppApiLevels.LEVEL_3) {
|
|
119
81
|
throw UnsupportedOperationException("Telemetry not supported for this API level ${carContext.carAppApiLevel}")
|
|
120
82
|
}
|
|
@@ -133,13 +95,10 @@ object AndroidAutoTelemetryObserver {
|
|
|
133
95
|
} catch (_: NullPointerException) {
|
|
134
96
|
}
|
|
135
97
|
|
|
136
|
-
if (
|
|
137
|
-
// we stop here to not re-register multiple listeners
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
"Telemetry observer is already running"
|
|
141
|
-
)
|
|
142
|
-
return
|
|
98
|
+
if (isObserverRunning) {
|
|
99
|
+
// we stop here to not re-register multiple listeners
|
|
100
|
+
// only the single shot values can be requested multiple times by registering another tlm listener on RN side
|
|
101
|
+
return false
|
|
143
102
|
}
|
|
144
103
|
|
|
145
104
|
try {
|
|
@@ -160,19 +119,17 @@ object AndroidAutoTelemetryObserver {
|
|
|
160
119
|
} catch (_: NullPointerException) {
|
|
161
120
|
}
|
|
162
121
|
|
|
163
|
-
handler.post(emitter)
|
|
164
|
-
|
|
165
|
-
isRunning = true
|
|
166
122
|
|
|
167
|
-
|
|
123
|
+
isObserverRunning = true
|
|
124
|
+
return true
|
|
168
125
|
}
|
|
169
126
|
|
|
170
|
-
fun stopTelemetryObserver() {
|
|
171
|
-
if (!
|
|
127
|
+
override fun stopTelemetryObserver() {
|
|
128
|
+
if (!isObserverRunning) {
|
|
172
129
|
return
|
|
173
130
|
}
|
|
174
131
|
|
|
175
|
-
|
|
132
|
+
isObserverRunning = false
|
|
176
133
|
|
|
177
134
|
carContext?.let {
|
|
178
135
|
val carHardwareManager = it.getCarService(
|
|
@@ -195,7 +152,5 @@ object AndroidAutoTelemetryObserver {
|
|
|
195
152
|
} catch (_: SecurityException) {
|
|
196
153
|
}
|
|
197
154
|
}
|
|
198
|
-
|
|
199
|
-
handler.removeCallbacks(emitter)
|
|
200
155
|
}
|
|
201
|
-
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
|
|
3
|
+
<uses-feature
|
|
4
|
+
android:name="android.hardware.type.automotive"
|
|
5
|
+
android:required="true" />
|
|
6
|
+
|
|
7
|
+
<uses-feature
|
|
8
|
+
android:name="android.software.car.templates_host"
|
|
9
|
+
android:required="true" />
|
|
10
|
+
|
|
11
|
+
<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES" />
|
|
12
|
+
<uses-permission android:name="androidx.car.app.MAP_TEMPLATES" />
|
|
13
|
+
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
|
|
14
|
+
|
|
15
|
+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
16
|
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
17
|
+
|
|
18
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
19
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
|
20
|
+
|
|
21
|
+
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
<!-- Android Automotive specific permissions -->
|
|
25
|
+
<uses-permission android:name="android.car.permission.CAR_ENERGY" />
|
|
26
|
+
<uses-permission android:name="android.car.permission.CAR_ENERGY_PORTS" />
|
|
27
|
+
<uses-permission android:name="android.car.permission.CAR_EXTERIOR_ENVIRONMENT" />
|
|
28
|
+
<uses-permission android:name="android.car.permission.CAR_IDENTIFICATION" />
|
|
29
|
+
<uses-permission android:name="android.car.permission.CAR_INFO" />
|
|
30
|
+
<uses-permission android:name="android.car.permission.CAR_POWERTRAIN" />
|
|
31
|
+
<uses-permission android:name="android.car.permission.CAR_SPEED" />
|
|
32
|
+
|
|
33
|
+
<application>
|
|
34
|
+
<activity
|
|
35
|
+
android:name="androidx.car.app.activity.CarAppActivity"
|
|
36
|
+
android:exported="true"
|
|
37
|
+
android:launchMode="singleTask"
|
|
38
|
+
android:theme="@android:style/Theme.DeviceDefault.NoActionBar">
|
|
39
|
+
|
|
40
|
+
<intent-filter>
|
|
41
|
+
<action android:name="android.intent.action.MAIN" />
|
|
42
|
+
|
|
43
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
44
|
+
<category android:name="android.intent.category.APP_MAPS" />
|
|
45
|
+
</intent-filter>
|
|
46
|
+
|
|
47
|
+
<intent-filter>
|
|
48
|
+
<action android:name="androidx.car.app.action.NAVIGATE" />
|
|
49
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
50
|
+
<data android:scheme="geo" />
|
|
51
|
+
</intent-filter>
|
|
52
|
+
|
|
53
|
+
<meta-data
|
|
54
|
+
android:name="distractionOptimized"
|
|
55
|
+
android:value="true" />
|
|
56
|
+
|
|
57
|
+
</activity>
|
|
58
|
+
|
|
59
|
+
<service
|
|
60
|
+
android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.AndroidAutoService"
|
|
61
|
+
android:exported="true"
|
|
62
|
+
android:foregroundServiceType="location">
|
|
63
|
+
<intent-filter>
|
|
64
|
+
<action android:name="androidx.car.app.CarAppService" />
|
|
65
|
+
|
|
66
|
+
<category android:name="androidx.car.app.category.NAVIGATION" />
|
|
67
|
+
<category android:name="androidx.car.app.category.FEATURE_CLUSTER" />
|
|
68
|
+
</intent-filter>
|
|
69
|
+
<intent-filter>
|
|
70
|
+
<action android:name="androidx.car.app.action.NAVIGATE" />
|
|
71
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
72
|
+
<data android:scheme="geo" />
|
|
73
|
+
</intent-filter>
|
|
74
|
+
</service>
|
|
75
|
+
|
|
76
|
+
<service android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.HeadlessTaskService" />
|
|
77
|
+
|
|
78
|
+
<provider
|
|
79
|
+
android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.ActivityRenderStateProvider"
|
|
80
|
+
android:authorities="${applicationId}.ActivityRenderStateProvider"
|
|
81
|
+
android:exported="false" />
|
|
82
|
+
|
|
83
|
+
<meta-data
|
|
84
|
+
android:name="com.android.automotive"
|
|
85
|
+
android:resource="@xml/automotive_app_desc" />
|
|
86
|
+
<meta-data
|
|
87
|
+
android:name="androidx.car.app.minCarApiLevel"
|
|
88
|
+
android:value="1" />
|
|
89
|
+
</application>
|
|
90
|
+
|
|
91
|
+
</manifest>
|