Skip to content

Commit

Permalink
Adds an app demonstrating CDSContentProvider usage
Browse files Browse the repository at this point in the history
  • Loading branch information
hufman committed Aug 24, 2021
1 parent e4e4f60 commit bb72a9f
Show file tree
Hide file tree
Showing 48 changed files with 1,725 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
33 changes: 33 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.4.32"
ext.androidx_lifecycle_extensions_version = '2.2.0'
ext.android_plugin_version = '2.3.0-alpha2'


repositories {
google()
jcenter()
maven {
url 'https://www.jitpack.io'
}
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.3"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
1 change: 1 addition & 0 deletions cds_gauges/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
11 changes: 11 additions & 0 deletions cds_gauges/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# CDS Gauges

This app loads some CDS data points over the CDS Content Provider and displays them in some gauge widgets.

This is intended to demonstrate the ease of querying the CDS Content Provider and to use data binding to show the result in the UI.

The magic happens in MainModel:
- CDSLiveData is used to conveniently load data from the CDS Content Provider as a JsonObject
- Some LiveData helpers are used to map from JsonObject to various numbers and unit labels
- The CDSVehicleUnits object is parsed from the car to know what units the driver has chosen in the car
- This CDSVehicleUnits is combined with the car's raw data to scale units appropriately
56 changes: 56 additions & 0 deletions cds_gauges/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}

android {
compileSdkVersion 29

defaultConfig {
applicationId "me.hufman.idriveconnectaddons.cdsgauge"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures {
dataBinding true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.fragment:fragment-ktx:1.3.6'
implementation "androidx.lifecycle:lifecycle-extensions:$androidx_lifecycle_extensions_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.material:material:1.4.0'
implementation "com.google.code.gson:gson:2.8.6"
implementation 'com.github.anastr:speedviewlib:1.5.51'
// implementation 'com.github.Pygmalion69:Gauge:1.5.2'
implementation project(path: ':lib')
kapt "com.android.databinding:compiler:$android_plugin_version"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
21 changes: 21 additions & 0 deletions cds_gauges/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package me.hufman.idriveconnectaddons.cdsgauge

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("me.hufman.idriveconnectaddons.cdsgauge", appContext.packageName)
}
}
30 changes: 30 additions & 0 deletions cds_gauges/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.hufman.idriveconnectaddons.cdsgauge">

<uses-permission android:name="bimmergestalt.permission.CDS_normal" />
<uses-permission android:name="bimmergestalt.permission.CDS_personal" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.CDSGauges">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!-- Become discoverable in the Addons tab -->
<service android:name=".MainService">
<intent-filter>
<action android:name="bimmergestalt.cardata.service" />
</intent-filter>
</service>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package me.hufman.idriveconnectaddons.cdsgauge

import android.content.Context
import androidx.databinding.BindingAdapter
import com.github.anastr.speedviewlib.Gauge

object DataBindingHelpers {
// Dynamic text
@JvmStatic
@BindingAdapter("sv_unit")
fun setUnit(view: Gauge, value: Context.() -> String) {
view.unit = view.context.run(value)
}
@JvmStatic
@BindingAdapter("sv_speed")
fun setSpeed(view: Gauge, value: Double) {
view.speedTo(value.toFloat(), 500)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.hufman.idriveconnectaddons.cdsgauge

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import me.hufman.idriveconnectaddons.cdsgauge.databinding.MainBinding

class MainActivity : AppCompatActivity() {
val viewModel by viewModels<MainModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = MainBinding.inflate(layoutInflater)
binding.lifecycleOwner = this
binding.data = viewModel
setContentView(binding.root)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package me.hufman.idriveconnectaddons.cdsgauge

import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import com.google.gson.JsonObject
import me.hufman.idriveconnectaddons.lib.CDS
import me.hufman.idriveconnectaddons.lib.CDSLiveData
import me.hufman.idriveconnectaddons.lib.CDSVehicleUnits
import me.hufman.idriveconnectaddons.lib.GsonNullable.tryAsDouble
import me.hufman.idriveconnectaddons.lib.GsonNullable.tryAsInt
import me.hufman.idriveconnectaddons.lib.GsonNullable.tryAsJsonObject
import me.hufman.idriveconnectaddons.lib.GsonNullable.tryAsJsonPrimitive
import me.hufman.idriveconnectaddons.lib.GsonNullable.tryAsString
import me.hufman.idriveconnectaddons.lib.LiveDataHelpers.combine
import me.hufman.idriveconnectaddons.lib.LiveDataHelpers.map

class MainModel(app: Application): AndroidViewModel(app) {
val units: LiveData<CDSVehicleUnits> = CDSLiveData(app, CDS.VEHICLE.UNITS).map(CDSVehicleUnits.UNKNOWN) {
CDSVehicleUnits.fromCdsProperty(it)
}

val unitsDistanceLabel: LiveData<Context.() -> String> = units.map({"km"}) {
when (it.distanceUnits) {
CDSVehicleUnits.Distance.Kilometers -> {{ "km" }}
CDSVehicleUnits.Distance.Miles -> {{ "mi" }}
}
}
val unitsSpeedLabel: LiveData<Context.() -> String> = units.map({"kmph"}) {
when (it.distanceUnits) {
CDSVehicleUnits.Distance.Kilometers -> {{ "kmph" }}
CDSVehicleUnits.Distance.Miles -> {{ "mph" }}
}
}

val vin: LiveData<String> = CDSLiveData(app, CDS.VEHICLE.VIN).map("") {
it.tryAsJsonPrimitive("VIN")?.tryAsString
}
val speed: LiveData<Double> = CDSLiveData(app, CDS.DRIVING.SPEEDACTUAL).map(0.0) {
it.tryAsJsonPrimitive("speedActual")?.tryAsInt
}.combine(units) { value, units ->
units.distanceUnits.fromCarUnit(value)
}
val torque: LiveData<Double> = CDSLiveData(app, CDS.ENGINE.TORQUE).map(0.0) {
it.tryAsJsonPrimitive("torque")?.tryAsDouble
}

val temp: LiveData<JsonObject> = CDSLiveData(app, CDS.ENGINE.TEMPERATURE)
val engineTemp = temp.map(0.0) {
it.tryAsJsonObject("temperature")?.tryAsJsonPrimitive("engine")?.tryAsDouble
}
val oilTemp = temp.map(0.0) {
it.tryAsJsonObject("temperature")?.tryAsJsonPrimitive("oil")?.tryAsDouble
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.hufman.idriveconnectaddons.cdsgauge

import android.app.Service
import android.content.Intent
import android.os.IBinder

/**
* Needs a service intent to be discoverable in the Addons UI
*/
class MainService: Service() {
override fun onBind(p0: Intent?): IBinder? {
return null
}
}
30 changes: 30 additions & 0 deletions cds_gauges/src/main/res/drawable-v24/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
Loading

0 comments on commit bb72a9f

Please sign in to comment.