Browse Source

Migrate to androidx & add ActivityRecognition

androidx-act-recog
sipp11 5 years ago
parent
commit
bacb8b9110
  1. 2
      .idea/misc.xml
  2. 43
      app/build.gradle
  3. 14
      app/src/androidTest/java/co/zzyzx/sensorlogger/DatabaseTest.kt
  4. 9
      app/src/androidTest/java/co/zzyzx/sensorlogger/ExampleInstrumentedTest.kt
  5. 38
      app/src/main/AndroidManifest.xml
  6. 44
      app/src/main/java/co/zzyzx/sensorlogger/EndlessService.kt
  7. 7
      app/src/main/java/co/zzyzx/sensorlogger/MainActivity.kt
  8. 8
      app/src/main/java/co/zzyzx/sensorlogger/db/Database.kt
  9. 4
      app/src/main/java/co/zzyzx/sensorlogger/db/dao.kt
  10. 8
      app/src/main/java/co/zzyzx/sensorlogger/db/entity.kt

2
.idea/misc.xml

@ -5,7 +5,7 @@
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

43
app/build.gradle

@ -12,7 +12,11 @@ android {
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
}
buildTypes {
release {
@ -20,29 +24,44 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
// Gradle automatically adds 'android.test.runner' as a dependency.
// useLibrary 'android.test.runner'
// useLibrary 'android.test.base'
// useLibrary 'android.test.mock'
//
// testOptions {
// execution 'ANDROIDX_TEST_ORCHESTRATOR'
// }
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'androidx.appcompat:appcompat:1.1.0'
// implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.github.kittinunf.fuel:fuel:2.1.0'
implementation 'com.github.kittinunf.fuel:fuel-android:2.1.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0-M2'
// Room dependencies
// implementation 'androidx.room:room-runtime:2.0.0'
// kapt 'androidx.room:room-compiler:2.0.0'
implementation 'android.arch.persistence.room:runtime:1.1.1'
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
kapt 'android.arch.persistence.room:compiler:1.1.1'
implementation 'androidx.room:room-runtime:2.1.0'
kapt 'androidx.room:room-compiler:2.1.0'
// activity recognition
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.opencsv:opencsv:4.0'
// implementation 'android.arch.lifecycle:excompile 'com.opencsv:opencsv:4.0'tensions:1.1.1'
// kapt 'android.arch.lifecycle:compiler:1.1.1'
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// Core library
androidTestImplementation 'androidx.test:core:1.2.0'
// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
// Assertions
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
}

14
app/src/androidTest/java/co/zzyzx/sensorlogger/DatabaseTest.kt

@ -1,9 +1,9 @@
package co.zzyzx.sensorlogger
import android.arch.persistence.room.Room
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import androidx.room.Room
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import co.zzyzx.sensorlogger.db.AppDatabase
import co.zzyzx.sensorlogger.db.Record
import co.zzyzx.sensorlogger.db.RecordDao
@ -23,7 +23,7 @@ class DatabaseTest {
@Before
fun createDb() {
val appContext = InstrumentationRegistry.getTargetContext()
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
db = Room.inMemoryDatabaseBuilder(appContext, AppDatabase::class.java)
.allowMainThreadQueries()
.build()
@ -41,9 +41,7 @@ class DatabaseTest {
data = "123,23232"
)
)
for (rec in records) {
recordDao.insertAll(rec)
}
recordDao.insert(*records.toTypedArray())
}
@After
@ -61,7 +59,7 @@ class DatabaseTest {
sensor = "gps",
data = "333,32322"
)
recordDao.insertAll(rec)
recordDao.insert(rec)
val byName = recordDao.findBySensor("gps")
assertEquals(byName.data, rec.data)
assertEquals(byName.timestamp, rec.timestamp)

9
app/src/androidTest/java/co/zzyzx/sensorlogger/ExampleInstrumentedTest.kt

@ -1,13 +1,12 @@
package co.zzyzx.sensorlogger
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
@ -18,7 +17,7 @@ class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("co.zzyzx.sensorlogger", appContext.packageName)
}
}

38
app/src/main/AndroidManifest.xml

@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="co.zzyzx.sensorlogger">
package="co.zzyzx.sensorlogger">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
@ -20,21 +22,37 @@
<service
android:name=".EndlessService"
android:enabled="true"
android:exported="false">
</service>
android:exported="false"></service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:enabled="true" android:name=".StartReceiver">
<receiver
android:name=".StartReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- You don't need to include android:required="false" if your app's
minSdkVersion is 28 or higher. -->
<uses-library
android:name="android.test.runner"
android:required="false" />
<!-- For both of these declarations, you don't need to include
android:required="false" if your app's minSdkVersion is 28
or higher. -->
<uses-library
android:name="android.test.base"
android:required="false" />
<uses-library
android:name="android.test.mock"
android:required="false" />
</application>

44
app/src/main/java/co/zzyzx/sensorlogger/EndlessService.kt

@ -21,6 +21,7 @@ import android.widget.Toast
import co.zzyzx.sensorlogger.db.Record
import co.zzyzx.sensorlogger.db.RecordRepository
import com.github.kittinunf.fuel.Fuel
import com.google.android.gms.location.*
import java.text.SimpleDateFormat
import java.time.Instant
import java.util.*
@ -39,6 +40,7 @@ class EndlessService : Service(), SensorEventListener, LocationListener {
private val notificationChannelId = "ENDLESS SERVICE CHANNEL"
private val notificationId = 1011
private lateinit var mActivityRecognitionClient: ActivityRecognitionClient
private lateinit var mSensorManager: SensorManager
private lateinit var mAccelerometer: Sensor
private lateinit var mGyroscope: Sensor
@ -78,10 +80,8 @@ class EndlessService : Service(), SensorEventListener, LocationListener {
"with a null intent. It has been probably restarted by the system."
)
}
mSensorManager.registerListener(this, mAccelerometer, SENSOR_DELAY)
mSensorManager.registerListener(this, mGyroscope, SENSOR_DELAY)
// by returning this we make sure the service is restarted if the system kills the service
return START_STICKY
}
@ -100,6 +100,7 @@ class EndlessService : Service(), SensorEventListener, LocationListener {
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
setupActivityRecognitionUpdates()
if (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
@ -119,6 +120,45 @@ class EndlessService : Service(), SensorEventListener, LocationListener {
}
}
private fun setupActivityRecognitionUpdates() {
// ActivityRecognition
val transitions = mutableListOf<ActivityTransition>()
transitions +=
ActivityTransition.Builder()
.setActivityType(DetectedActivity.IN_VEHICLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build()
transitions +=
ActivityTransition.Builder()
.setActivityType(DetectedActivity.IN_VEHICLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build()
transitions +=
ActivityTransition.Builder()
.setActivityType(DetectedActivity.ON_BICYCLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build()
transitions +=
ActivityTransition.Builder()
.setActivityType(DetectedActivity.ON_BICYCLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build()
transitions +=
ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build()
transitions +=
ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build()
val request = ActivityTransitionRequest(transitions)
mActivityRecognitionClient = ActivityRecognition.getClient(applicationContext)
mActivityRecognitionClient.requestActivityTransitionUpdates(request, null)
}
override fun onDestroy() {
super.onDestroy()
mSensorManager.unregisterListener(this)

7
app/src/main/java/co/zzyzx/sensorlogger/MainActivity.kt

@ -10,11 +10,12 @@ import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import co.zzyzx.sensorlogger.db.RecordRepository
import com.opencsv.CSVWriter
import kotlinx.android.synthetic.main.activity_main.*

8
app/src/main/java/co/zzyzx/sensorlogger/db/Database.kt

@ -1,15 +1,15 @@
package co.zzyzx.sensorlogger.db
import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.time.Instant
@Database(entities = arrayOf(Record::class), version = 1, exportSchema = false)
@Database(entities = [Record::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun recordDao(): RecordDao
}

4
app/src/main/java/co/zzyzx/sensorlogger/db/dao.kt

@ -1,7 +1,7 @@
package co.zzyzx.sensorlogger.db
import android.arch.lifecycle.LiveData
import android.arch.persistence.room.*
import androidx.lifecycle.LiveData
import androidx.room.*
@Dao

8
app/src/main/java/co/zzyzx/sensorlogger/db/entity.kt

@ -1,9 +1,9 @@
package co.zzyzx.sensorlogger.db
import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.Index
import android.arch.persistence.room.PrimaryKey
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(indices = [(Index(value = ["timestamp", "sensor"], unique = true))])

Loading…
Cancel
Save