diff --git a/.gitignore b/.gitignore index 7eca435..d5d8a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,13 @@ # Android Studio +*.iml .gradle /local.properties /.idea -/.idea/workspace.xml -.DS_Store -/build - -#built application files -*.apk -*.ap_ - -# files for the dex VM -*.dex - -# Java class files -*.class -# generated files -bin/ -gen/ - -# Local configuration file (sdk path, etc) -local.properties - -# Windows thumbnail db -Thumbs.db - -# OSX files .DS_Store +/build +/captures -# Eclipse project files -.classpath -.project +# Other +bintray.properties diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..2996d53 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..707ee6e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..499fe8b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2c79c4c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,32 @@ +language: android +sudo: required +jdk: oraclejdk8 + +env: + global: + - ANDROID_API_LEVEL=29 + - ANDROID_BUILD_TOOLS_VERSION=29.0.2 + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + +android: + components: + - tools + - platform-tools + - build-tools-$ANDROID_BUILD_TOOLS_VERSION + - android-$ANDROID_API_LEVEL + - extra-google-google_play_services + +licenses: + - android-sdk-preview-license-.+ + - android-sdk-license-.+ + +script: + - ./gradlew build check diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a82b3c..b216645 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,39 @@ # Changelog -### 0.2.0 - - Added support for Bluetooth sensor module. - - DataInterface method getDataInString() has been renamed to getDataInCSV() - - SKDataInterface has been renamed to SKSensorData - - Added getSensorModuleType() to SKSensorData - - Added SK prefix to all source files - - Added support for Android Studio 1.3 - - Updated Build Tools version to 22.0.1 +### 0.5.0 (??, 2019) +- Added Documentation using javadoc generator (thanks to Susan Crayne @crayne) +- Added support for Permissions (Android 6.0 or greater) +- Added support for Sensor Configuration +- Added support for Air Pressure sensor +- Added support for Humidity sensor +- Added support for Beacon Proximity (iBeacon™, Eddystone™ and AltBeacon) with the help of the Android Beacon Library (thanks Radius Networks) +- Added support for Notification sensor +- Added csvHeaderForSensor method to get the headers of the CSV data format +- Added missing SKMicrophoneData object +- Added support for Exceptions (SKExceptions) +- Added support for JSON data format (thanks to Mo, Fan Vincent @mofanv) +- Added support for Android Studio 3.5 +- Added support for Android 10 SDK +- Added support for maven distribution (jCenter and Maven Central) +- Renamed Activity sensor to Motion Activity +- Renamed Audio sensor to Microphone +- Renamed Air Pressure sensor to Barometer +- Renamed Battery sensor to BatteryStatus +- Renamed SKSensorDataListener to SKSensorDataHandler +- Renamed all sensor modules into sensors +- Updated deprecated code for Location and Motion Activity sensors +- Updated SensingKit-Android API (thanks to Ming-Jiun Huang @U3D3) +- Updated Google Play Services to 17.0.0 +- Migrated to AndroidX (moved from old Android Support Classes) -### 0.1.0 - - Initial Release +### 0.2.0 (July 30, 2015) +- Added support for Bluetooth sensor +- DataInterface method getDataInString() has been renamed to getDataInCSV() +- SKDataInterface has been renamed to SKSensorData +- Added getSensorModuleType() to SKSensorData +- Added SK prefix to all source files +- Added support for Android Studio 1.3 +- Updated Build Tools version to 22.0.1 + +### 0.1.0 (July 13, 2015) +- Initial Release \ No newline at end of file diff --git a/README.md b/README.md index 9867015..6656d72 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # SensingKit-Android Library +[![Build Status](https://travis-ci.com/SensingKit/SensingKit-Android.svg?branch=develop)](https://travis-ci.com/SensingKit/SensingKit-Android) -An Android library that provides Continuous Sensing functionality to your applications. For more information, please refer to the [project website](http://www.sensingkit.org). +An Android library that provides Continuous Sensing functionality to your applications. For more information, please refer to the [project website](https://www.sensingkit.org). ## Supported Sensors -The following sensor modules are currently supported in SensingKit-Android, (listed in [SKSensorModuleType](SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleType.java) enum): +The following sensor modules are currently supported in SensingKit-Android, (listed in [SKSensorType](SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorType.java) enum): - Accelerometer - Gravity @@ -18,12 +19,16 @@ The following sensor modules are currently supported in SensingKit-Android, (lis - Step Counter - Light - Location -- Activity -- Battery +- Motion Activity +- Battery Status - Screen Status -- Audio Recorder +- Microphone - Audio Level - Bluetooth +- Beacon Proximity +- Humidity +- Barometer +- Notification ## Configuring the Library @@ -33,9 +38,9 @@ The following sensor modules are currently supported in SensingKit-Android, (lis ./gradlew build ``` -- Create an app/libs directory inside your project and copy the generated SensingKitLib/build/outputs/aar/SensingKitLib-release.aar (or the equivalent debug) file there. +- Create an `app/libs` directory inside your project and copy the generated `SensingKitLib/build/outputs/aar/SensingKitLib-release.aar` (or the equivalent debug) file there. -- Edit your app/build.gradle file and add a flatDir entry as shown bellow: +- Edit your app/build.gradle file and add a flatDir entry as shown below: ``` repositories { @@ -47,74 +52,178 @@ repositories { ``` -- In the same app/build.gradle file, add SensingKitLib as a dependency as shown below: +- In the same `app/build.gradle` file, add SensingKit as a dependency as shown below: ``` dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'org.sensingkit:SensingKitLib-release@aar' - compile 'com.android.support:appcompat-v7:22.2.1’ - compile 'com.google.android.gms:play-services-location:7.5.0' + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'org.sensingkit:SensingKitLib-release@aar' + implementation 'com.google.android.gms:play-services-location:16.0.0' } ``` ## How to Use this Library -- Import and init SensingKit into your Activity class as shown bellow: +Import and init SensingKit as shown below: ```java -import org.sensingkit.sensingkitlib.SensingKitLib; +import org.sensingkit.sensingkitlib.*; +import org.sensingkit.sensingkitlib.data.*; -SensingKitLibInterface mSensingKitLib = SensingKitLib.getSensingKitLib(this); +public class MainActivity extends AppCompatActivity { + + SensingKitLibInterface mSensingKit; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // init SensingKit + mSensingKit = SensingKitLib.sharedSensingKitLib(this); + } +} +``` + + +Check if a sensor is available in the device: + +```java +if (mSensingKit.isSensorAvailable(SKSensorType.LIGHT)) { + // You can access the sensor +} ``` -- Register a sensor module (e.g. a Light sensor) as shown bellow: +Register a sensor (e.g. a Light sensor) as shown below: ```java -mSensingKitLib.registerSensorModule(SKSensorModuleType.LIGHT); +mSensingKit.registerSensor(SKSensorType.LIGHT); ``` -- Subscribe a sensor data listener: +Subscribe a sensor data listener: ```java -mSensingKitLib.subscribeSensorDataListener(SKSensorModuleType.LIGHT, new SKSensorDataListener() { +mSensingKit.subscribeSensorDataHandler(SKSensorType.LIGHT, new SKSensorDataHandler() { @Override - public void onDataReceived(final SKSensorModuleType moduleType, final SKSensorData sensorData) { + public void onDataReceived(final SKSensorType moduleType, final SKSensorData sensorData) { System.out.println(sensorData.getDataInCSV()); // Print data in CSV format } }); ``` -- You can cast the data object into the actual sensor data object in order to access all the sensor data properties: - +You can cast the data object into the actual sensor data object in order to access all the sensor data properties: + ```java SKLightData lightData = (SKLightData)sensorData; ``` +You can Start and Stop the Continuous Sensing using the following commands: + +```java +// Start +mSensingKit.startContinuousSensingWithSensor(SKSensorType.LIGHT); + +// Stop +mSensingKit.stopContinuousSensingWithSensor(SKSensorType.LIGHT); +``` + +For a complete description of our API, please refer to the [project website](https://www.sensingkit.org). + + +## Required Permissions + +Depending on the used sensor and its configuration, some additional permissions are required to be granted by the user. SensingKit automates this process by providing the following APIs: + +```java +boolean isPermissionGrantedForSensor(final SKSensorType sensorType) throws SKException; + +void requestPermissionForSensor(final SKSensorType sensorType, final @NonNull Activity activity) throws SKException; + +void requestPermissionForAllRegisteredSensors(final @NonNull Activity activity); +``` -- You can Start and Stop the Continuous Sensing using the following commands: +For example, in order to request permission to access the Location sensor: ```java -mSensingKitLib.startContinuousSensingWithSensor(SKSensorModuleType.LIGHT); -mSensingKitLib.stopContinuousSensingWithSensor(SKSensorModuleType.LIGHT); +if (!isPermissionGrantedForSensor(SKSensorType.LOCATION) { + requestPermissionForSensor(SKSensorType.LOCATION, this); +} +``` + +You will also need to add a `` element in your app manifest, as a child of the top-level `` element: + +```xml + + + + + + + ... + + ``` +The permissions required by the following SensingKit sensors are: + +### Location +- `android.permission.ACCESS_FINE_LOCATION` + + +### Motion Activity + +- `com.google.android.gms.permission.ACTIVITY_RECOGNITION` + + +### Microphone + +- `android.permission.RECORD_AUDIO` + + +### Audio Level + +- `android.permission.RECORD_AUDIO` + + +### Bluetooth + +- `android.permission.BLUETOOTH` +- `android.permission.BLUETOOTH_ADMIN` + + +### Beacon Proximity + +- `android.permission.ACCESS_FINE_LOCATION` + + +For more information about Android's App Permissions, please visit: https://developer.android.com/training/permissions/requesting. + + +## Special Permissions + +Some sensors (i.e. only the Notification sensor at this moment) require some special actions from the user to acquire permision to access it. The user needs to visit the phone's `Settings > Advanced > App Permissions > Special app access` and grant the special access to the app (i.e. `Notification access` in the case of the Notification sensor). + +This long proccess can be simplified by sending the user directly to that screen, using the following call: + +```java +startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); +``` -For a complete description of our API, please refer to the [project website](http://www.sensingkit.org). ## License ``` -Copyright (c) 2014. Queen Mary University of London -Kleomenis Katevas, k.katevas@qmul.ac.uk. +Copyright (c) 2014. Kleomenis Katevas +Kleomenis Katevas, k.katevas@imperial.ac.uk. This file is part of SensingKit-Android library. -For more information, please visit http://www.sensingkit.org. +For more information, please visit https://www.sensingkit.org. SensingKit-Android is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/SensingKit-Android.iml b/SensingKit-Android.iml index ad820ac..7def764 100644 --- a/SensingKit-Android.iml +++ b/SensingKit-Android.iml @@ -1,5 +1,5 @@ - + @@ -8,7 +8,7 @@ - + diff --git a/SensingKitLib/SensingKitLib.iml b/SensingKitLib/SensingKitLib.iml index 2a23a7d..fa89366 100644 --- a/SensingKitLib/SensingKitLib.iml +++ b/SensingKitLib/SensingKitLib.iml @@ -1,104 +1,127 @@ - + - - - + + + - - + + - - - - - + + + + + - - - + + + + - + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SensingKitLib/build.gradle b/SensingKitLib/build.gradle index 1fa6fc9..eac3073 100644 --- a/SensingKitLib/build.gradle +++ b/SensingKitLib/build.gradle @@ -1,14 +1,13 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 22 - buildToolsVersion "22.0.1" + compileSdkVersion 29 defaultConfig { minSdkVersion 16 - targetSdkVersion 22 - versionCode 1 - versionName "0.2.0" + targetSdkVersion 29 + versionCode 5 + versionName "0.5.0" } buildTypes { release { @@ -16,9 +15,18 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + lintOptions { + abortOnError false + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.google.android.gms:play-services-location:7.5.0' + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.annotation:annotation:1.1.0' + implementation 'org.altbeacon:android-beacon-library:2.16.3' + implementation 'com.google.android.gms:play-services-location:17.0.0' } diff --git a/SensingKitLib/src/main/AndroidManifest.xml b/SensingKitLib/src/main/AndroidManifest.xml index ae0251e..0a197a7 100644 --- a/SensingKitLib/src/main/AndroidManifest.xml +++ b/SensingKitLib/src/main/AndroidManifest.xml @@ -1,14 +1,22 @@ - - - + + - + + + + + + + diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKException.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKException.java index 8afa1b5..e8d8ecb 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKException.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKException.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,24 +21,42 @@ package org.sensingkit.sensingkitlib; +import androidx.annotation.NonNull; + public class SKException extends Exception { private final SKExceptionErrorCode errorCode; private final String TAG; - public SKException(String TAG, String message, SKExceptionErrorCode errorCode) { + /** + * + * @param TAG Class TAG that this exception was invoked from. + * @param message Error message + * @param errorCode Error code + */ + public SKException(final @NonNull String TAG, final @NonNull String message, final SKExceptionErrorCode errorCode) { super(message); this.TAG = TAG; this.errorCode = errorCode; } + /** + * Get the error code + * + * @return The error code + */ @SuppressWarnings("unused") public SKExceptionErrorCode getErrorCode() { return this.errorCode; } + /** + * Get the Class TAG that this exception was invoked from. + * + * @return Class TAG + */ @SuppressWarnings("unused") - public String getTAG() { + public @NonNull String getTAG() { return this.TAG; } } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKExceptionErrorCode.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKExceptionErrorCode.java index b34a1bd..df01ac2 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKExceptionErrorCode.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKExceptionErrorCode.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -22,5 +22,87 @@ package org.sensingkit.sensingkitlib; public enum SKExceptionErrorCode { - UNKNOWN_ERROR + + /** + * Unknown error. + */ + UNKNOWN_ERROR, + + + // Sensor Availability + + /** + * Sensor is not available. + */ + SENSOR_NOT_AVAILABLE, + + + // Sensor Registration + + /** + * Sensor is already registered. + */ + SENSOR_ALREADY_REGISTERED, + + /** + * Sensor is not registered. + */ + SENSOR_NOT_REGISTERED, + + /** + * Sensor could not be initialized. + */ + SENSOR_ERROR, + + + // Sensor Sensing + + /** + * Sensor is currently sensing. + */ + SENSOR_CURRENTLY_SENSING, + + /** + * Sensor is currently not sensing. + */ + SENSOR_CURRENTLY_NOT_SENSING, + + + // Sensor Data Handlers + + /** + * Sensor Data Handler is already registered. + */ + DATA_HANDLER_ALREADY_REGISTERED, + + /** + * Sensor Data Handler is not registered + */ + DATA_HANDLER_NOT_REGISTERED, + + + // Sensor Configuration + + /** + * Configuration is not compatible with the registered sensor. + */ + CONFIGURATION_NOT_VALID, + + + // Permissions + + /** + * Permission is missing from the manifest file + */ + PERMISSION_MISSING, + + /** + * File writer does not have access to write in the this path + */ + FILE_WRITER_PERMISSION_DENIED, + + /** + * File already exists + */ + FILE_ALREADY_EXISTS } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorDataListener.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorDataHandler.java similarity index 57% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorDataListener.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorDataHandler.java index 5126a60..688e5e8 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorDataListener.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorDataHandler.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,10 +21,18 @@ package org.sensingkit.sensingkitlib; -import org.sensingkit.sensingkitlib.data.SKSensorData; +import androidx.annotation.NonNull; -public interface SKSensorDataListener { +import org.sensingkit.sensingkitlib.data.SKSensorData; - void onDataReceived(final SKSensorModuleType moduleType, final SKSensorData sensorData); +public interface SKSensorDataHandler { + /** + * Data handler to be invoked when new sensor data is available. You can cast the sensorData object + * into the actual sensor data (e.g. SKAccelerometerData), based on the reported sensorType. + *
+ * parameter sensorType The type of the sensor producing the SKSensorData object.
+ * parameter sensorData The new sensor data produced by the SKSensorType sensor. + */ + void onDataReceived(final SKSensorType sensorType, final @NonNull SKSensorData sensorData); } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorManager.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorManager.java new file mode 100644 index 0000000..2d12150 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorManager.java @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib; + +import android.app.Activity; +import android.content.Context; +import android.os.Build; +import androidx.annotation.NonNull; +import android.util.Log; +import android.util.SparseArray; + +import org.sensingkit.sensingkitlib.sensors.*; +import org.sensingkit.sensingkitlib.configuration.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@SuppressWarnings({"StaticFieldLeak"}) +class SKSensorManager { + + @SuppressWarnings("unused") + private static final String TAG = SKSensorManager.class.getSimpleName(); + + private static SKSensorManager sSensorManager; + + private final Context mApplicationContext; + private final SparseArray mSensors; + + static SKSensorManager getSensorManager(final @NonNull Context context) { + + if (sSensorManager == null) { + sSensorManager = new SKSensorManager(context); + } + + return sSensorManager; + } + + private SKSensorManager(final @NonNull Context context) { + + mApplicationContext = context; + + // Init Sensor Array + mSensors = new SparseArray<>(SKSensorType.getLength()); + } + + /** + * Initializes and registers a sensor into the library with a default sensor configuration. + * + * @param sensorType The type of the sensor that will be initialized and registered in the library. + * @param configuration TODO + */ + void registerSensor(final SKSensorType sensorType, SKConfiguration configuration) throws SKException { + + Log.i(TAG, "Register sensor: " + sensorType.getName() + "."); + + if (!SKSensorUtilities.isSensorAvailable(sensorType, mApplicationContext)) { + throw new SKException(TAG, "Sensor is not available in the device.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + if (isSensorRegistered(sensorType)) { + throw new SKException(TAG, "Sensor is already registered.", SKExceptionErrorCode.SENSOR_ALREADY_REGISTERED); + } + + // If configuration was not provided, get the Default + if (configuration == null) { + configuration = SKSensorManager.defaultConfigurationForSensor(sensorType); + } // if configuration is provided, check the type + else if (!configuration.isValidForSensor(sensorType)) { + throw new SKException(TAG, "Configuration is not compatible with the registered sensor.", SKExceptionErrorCode.CONFIGURATION_NOT_VALID); + } + + // Register the Sensor + int sensorIndex = sensorType.ordinal(); + SKAbstractSensor sensor = createSensor(sensorType, configuration); + mSensors.put(sensorIndex, sensor); + } + + /** + * Deregisters a sensor from the library. Sensor should not be actively sensing when this method is called. All previously subscribed blocks will also be unsubscribed. + * + * @param sensorType The type of the sensor that will be deregistered. + */ + void deregisterSensor(final SKSensorType sensorType) throws SKException { + + Log.i(TAG, "Deregister sensor: " + sensorType.getName() + "."); + + if (!isSensorRegistered(sensorType)) { + throw new SKException(TAG, "Sensor is not registered.", SKExceptionErrorCode.SENSOR_NOT_REGISTERED); + } + + if (isSensorSensing(sensorType)) { + throw new SKException(TAG, "Sensor is currently sensing.", SKExceptionErrorCode.SENSOR_CURRENTLY_SENSING); + } + + // Clear all Callbacks from that sensor + getSensor(sensorType).unsubscribeAllSensorDataHandlers(); + + // Deregister the Sensor + getSensor(sensorType).sensorDeregistered(); + int sensorIndex = sensorType.ordinal(); + mSensors.delete(sensorIndex); + } + + void setConfiguration(SKConfiguration configuration, final SKSensorType sensorType) throws SKException { + + if (!SKSensorUtilities.isSensorAvailable(sensorType, mApplicationContext)) { + throw new SKException(TAG, "Sensor is not available in the device.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + // If configuration was not provided, get the Default + if (configuration == null) { + configuration = SKSensorManager.defaultConfigurationForSensor(sensorType); + } // if configuration is provided, check the type + else if (!configuration.isValidForSensor(sensorType)) { + throw new SKException(TAG, "Configuration is not compatible with the registered sensor.", SKExceptionErrorCode.CONFIGURATION_NOT_VALID); + } + + // Get Sensor + SKSensor sensor = getSensor(sensorType); + + // Set the configuration + sensor.setConfiguration(configuration); + } + + SKConfiguration getConfiguration(final SKSensorType sensorType) throws SKException { + + if (!SKSensorUtilities.isSensorAvailable(sensorType, mApplicationContext)) { + throw new SKException(TAG, "Sensor is not available in the device.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + // Get Sensor + SKSensor sensor = getSensor(sensorType); + + // return the configuration + return sensor.getConfiguration(); + } + + private @NonNull String[] filterPermissions(final String[] permissions) { + + if (permissions == null || permissions.length == 0) { + return new String[]{}; + } + + // List that holds all permissions + List permissionsList = new ArrayList<>(); + + for (String permission : permissions) { + + if (!SKUtilities.isPermissionGranted(permission, mApplicationContext)) { + permissionsList.add(permission); + } + } + + return permissionsList.toArray(new String[0]); + } + + boolean isPermissionGrantedForSensor(final SKSensorType sensorType) throws SKException { + + SKSensor sensor = getSensor(sensorType); + String[] permissions = sensor.getRequiredPermissions(); + + // if null, no permission is required + if (permissions == null || permissions.length == 0) { + return true; + } + else { + // Only keep permissions that are not granted + String[] filteredPermissions = filterPermissions(permissions); + return(filteredPermissions.length == 0); + } + } + + void requestPermissionForSensor(final SKSensorType sensorType, final @NonNull Activity activity) throws SKException { + + SKSensor sensor = getSensor(sensorType); + String[] permissions = sensor.getRequiredPermissions(); + + // Only keep permissions that are not granted + String[] filteredPermissions = filterPermissions(permissions); + + // request permissions + SKUtilities.requestPermissions(activity, filteredPermissions); + } + + // TODO documentation + void requestPermissionForAllRegisteredSensors(final @NonNull Activity activity) { + + // List that holds all permissions + List permissionsList = new ArrayList<>(); + + for (int i = 0; i < SKSensorType.getLength(); i++) { + + SKSensor sensor = mSensors.get(i); + if (sensor != null) { + + String[] permissions = sensor.getRequiredPermissions(); + + // Only keep permissions that are not granted + String[] filteredPermissions = filterPermissions(permissions); + + // Add to the list + permissionsList.addAll(Arrays.asList(filteredPermissions)); + } + } + + // request permissions + if (permissionsList.size() > 0) { + + // convert list to array + String[] permissions = permissionsList.toArray(new String[0]); + + // request permissions + SKUtilities.requestPermissions(activity, permissions); + } + } + + boolean isSensorAvailable(final SKSensorType sensorType) { + return SKSensorUtilities.isSensorAvailable(sensorType, mApplicationContext); + } + + /** + * A Boolean value that indicates whether the sensor is registered. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is registered or FALSE if it is not. + */ + boolean isSensorRegistered(final SKSensorType sensorType) { + + int sensorIndex = sensorType.ordinal(); + return (mSensors.get(sensorIndex) != null); + } + + /** + * A Boolean value that indicates whether the sensor is currently sensing. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is currently sensing or FALSE if it is not. + */ + boolean isSensorSensing(final SKSensorType sensorType) throws SKException { + + if (!isSensorRegistered(sensorType)) { + throw new SKException(TAG, "Sensor is not registered.", SKExceptionErrorCode.SENSOR_NOT_REGISTERED); + } + + return getSensor(sensorType).isSensing(); + } + + private SKAbstractSensor getSensor(final SKSensorType sensorType) throws SKException { + + if (!isSensorRegistered(sensorType)) { + throw new SKException(TAG, "Sensor is not registered.", SKExceptionErrorCode.SENSOR_NOT_REGISTERED); + } + + int sensorIndex = sensorType.ordinal(); + return mSensors.get(sensorIndex); + } + + private SKAbstractSensor createSensor(final SKSensorType sensorType, final SKConfiguration configuration) throws SKException { + + SKAbstractSensor sensor; + + switch (sensorType) { + + case ACCELEROMETER: + sensor = new SKAccelerometer(mApplicationContext, (SKAccelerometerConfiguration)configuration); + break; + + case GRAVITY: + sensor = new SKGravity(mApplicationContext, (SKGravityConfiguration)configuration); + break; + + case LINEAR_ACCELERATION: + sensor = new SKLinearAcceleration(mApplicationContext, (SKLinearAccelerationConfiguration)configuration); + break; + + case GYROSCOPE: + sensor = new SKGyroscope(mApplicationContext, (SKGyroscopeConfiguration)configuration); + break; + + case ROTATION: + sensor = new SKRotation(mApplicationContext, (SKRotationConfiguration)configuration); + break; + + case MAGNETOMETER: + sensor = new SKMagnetometer(mApplicationContext, (SKMagnetometerConfiguration)configuration); + break; + + case AMBIENT_TEMPERATURE: + sensor = new SKAmbientTemperature(mApplicationContext, (SKAmbientTemperatureConfiguration)configuration); + break; + + case STEP_DETECTOR: + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { + throw new SKException(TAG, "STEP_DETECTOR requires Android KitKat (19) or greater.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + sensor = new SKStepDetector(mApplicationContext, (SKStepDetectorConfiguration)configuration); + break; + + case STEP_COUNTER: + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { + throw new SKException(TAG, "STEP_COUNTER requires Android KitKat (19) or greater.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + sensor = new SKStepCounter(mApplicationContext, (SKStepCounterConfiguration)configuration); + break; + + case LIGHT: + sensor = new SKLight(mApplicationContext, (SKLightConfiguration)configuration); + break; + + case LOCATION: + sensor = new SKLocation(mApplicationContext, (SKLocationConfiguration)configuration); + break; + + case MOTION_ACTIVITY: + sensor = new SKMotionActivity(mApplicationContext, (SKMotionActivityConfiguration)configuration); + break; + + case BATTERY_STATUS: + sensor = new SKBatteryStatus(mApplicationContext, (SKBatteryStatusConfiguration)configuration); + break; + + case SCREEN_STATUS: + sensor = new SKScreenStatus(mApplicationContext, (SKScreenStatusConfiguration)configuration); + break; + + case MICROPHONE: + sensor = new SKMicrophone(mApplicationContext, (SKMicrophoneConfiguration)configuration); + break; + + case AUDIO_LEVEL: + sensor = new SKAudioLevel(mApplicationContext, (SKAudioLevelConfiguration)configuration); + break; + + case BLUETOOTH: + sensor = new SKBluetooth(mApplicationContext, (SKBluetoothConfiguration)configuration); + break; + + case BEACON_PROXIMITY: + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { + throw new SKException(TAG, "BEACON_PROXIMITY requires Android Jelly Bean (18) or greater.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + sensor = new SKBeaconProximity(mApplicationContext, (SKBeaconProximityConfiguration)configuration); + break; + + case HUMIDITY: + sensor = new SKHumidity(mApplicationContext, (SKHumidityConfiguration)configuration); + break; + + case BAROMETER: + sensor = new SKBarometer(mApplicationContext, (SKBarometerConfiguration)configuration); + break; + + case NOTIFICATION: + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { + throw new SKException(TAG, "NOTIFICATION requires Android Jelly Bean (18) or greater.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + sensor = new SKNotification(mApplicationContext, (SKNotificationConfiguration)configuration); + break; + + // Don't forget the break; here + + default: + throw new RuntimeException("createSensor case for Sensor '" + sensorType.getName() + "' is missing."); + } + + return sensor; + } + + private static SKConfiguration defaultConfigurationForSensor(final SKSensorType sensorType) { + + SKConfiguration configuration; + + switch (sensorType) { + + case ACCELEROMETER: + configuration = new SKAccelerometerConfiguration(); + break; + + case GRAVITY: + configuration = new SKGravityConfiguration(); + break; + + case LINEAR_ACCELERATION: + configuration = new SKLinearAccelerationConfiguration(); + break; + + case GYROSCOPE: + configuration = new SKGyroscopeConfiguration(); + break; + + case ROTATION: + configuration = new SKRotationConfiguration(); + break; + + case MAGNETOMETER: + configuration = new SKMagnetometerConfiguration(); + break; + + case AMBIENT_TEMPERATURE: + configuration = new SKAmbientTemperatureConfiguration(); + break; + + case STEP_DETECTOR: + configuration = new SKStepDetectorConfiguration(); + break; + + case STEP_COUNTER: + configuration = new SKStepCounterConfiguration(); + break; + + case LIGHT: + configuration = new SKLightConfiguration(); + break; + + case LOCATION: + configuration = new SKLocationConfiguration(); + break; + + case MOTION_ACTIVITY: + configuration = new SKMotionActivityConfiguration(); + break; + + case BATTERY_STATUS: + configuration = new SKBatteryStatusConfiguration(); + break; + + case SCREEN_STATUS: + configuration = new SKScreenStatusConfiguration(); + break; + + case MICROPHONE: + configuration = new SKMicrophoneConfiguration(); + break; + + case AUDIO_LEVEL: + configuration = new SKAudioLevelConfiguration(); + break; + + case BLUETOOTH: + configuration = new SKBluetoothConfiguration(); + break; + + case BEACON_PROXIMITY: + configuration = new SKBeaconProximityConfiguration(); + break; + + case HUMIDITY: + configuration = new SKHumidityConfiguration(); + break; + + case BAROMETER: + configuration = new SKBarometerConfiguration(); + break; + + case NOTIFICATION: + configuration = new SKNotificationConfiguration(); + break; + + // Don't forget the break; here + + default: + throw new RuntimeException("Default configuration for Sensor '" + sensorType.getName() + "' is missing."); + } + + return configuration; + } + + void subscribeSensorDataHandler(final SKSensorType sensorType, final SKSensorDataHandler dataHandler) throws SKException { + + Log.i(TAG, "Subscribe to sensor: " + sensorType.getName() + "."); + + getSensor(sensorType).subscribeSensorDataHandler(dataHandler); + } + + void unsubscribeSensorDataHandler(final SKSensorType sensorType, final SKSensorDataHandler dataHandler) throws SKException { + + Log.i(TAG, "Unsubscribe from sensor: " + sensorType.getName() + "."); + + getSensor(sensorType).unsubscribeSensorDataHandler(dataHandler); + } + + void unsubscribeAllSensorDataHandlers(final SKSensorType sensorType) throws SKException { + + Log.i(TAG, "Unsubscribe from all sensors."); + + getSensor(sensorType).unsubscribeAllSensorDataHandlers(); + } + + /** + * Starts continuous sensing with the specified sensor. + * + * @param sensorType The type of the sensor that will be started. + */ + void startContinuousSensingWithSensor(final SKSensorType sensorType) throws SKException { + + Log.i(TAG, "Start sensing with sensor: " + sensorType.getName() + "."); + + if (isSensorSensing(sensorType)) { + throw new SKException(TAG, "Sensor [" + sensorType.getName() + "] is already sensing.", SKExceptionErrorCode.SENSOR_CURRENTLY_SENSING); + } + + // Request WakeLock + if (getSensor(sensorType).getConfiguration().getRequestWakeLock()) { + SKWakeLockManager.getInstance(mApplicationContext).acquireWakeLock(); + } + + // Start Sensing + getSensor(sensorType).startSensing(); + } + + /** + * Stops continuous sensing with the specified sensor. + * + * @param sensorType The type of the sensor that will be stopped. + */ + void stopContinuousSensingWithSensor(final SKSensorType sensorType) throws SKException { + + Log.i(TAG, "Stop sensing with sensor: " + sensorType.getName() + "."); + + if (!isSensorSensing(sensorType)) { + throw new SKException(TAG, "Sensor [" + sensorType.getName() + "] is already not sensing.", SKExceptionErrorCode.SENSOR_CURRENTLY_NOT_SENSING); + } + + SKSensor sensor = getSensor(sensorType); + + // Stop Sensing + sensor.stopSensing(); + + // Release WakeLock + if (getSensor(sensorType).getConfiguration().getRequestWakeLock()) { + SKWakeLockManager.getInstance(mApplicationContext).releaseWakeLock(); + } + } + + /** + * Starts continuous sensing with all registered sensors. + */ + void startContinuousSensingWithAllRegisteredSensors() throws SKException { + + for (int i = 0; i < SKSensorType.getLength(); i++){ + if(mSensors.get(i) != null){ + Log.i(TAG, "Start sensing with sensor: " + mSensors.get(i).getSensorName() + "."); + + if (isSensorSensing(mSensors.get(i).getSensorType())) { + throw new SKException(TAG, "Sensor [" + mSensors.get(i).getSensorName() + "] is already sensing.", SKExceptionErrorCode.SENSOR_CURRENTLY_SENSING); + } + + // Start Sensing + mSensors.get(i).startSensing(); + } + } + } + + /** + * Stops continuous sensing with all registered sensors. + */ + void stopContinuousSensingWithAllRegisteredSensors() throws SKException { + for (int i = 0; i < SKSensorType.getLength(); i++) { + if (mSensors.get(i) != null) { + Log.i(TAG, "Stop sensing with sensor: " + mSensors.get(i).getSensorName() + "."); + + if (!isSensorSensing(mSensors.get(i).getSensorType())) { + throw new SKException(TAG, "Sensor [" + mSensors.get(i).getSensorName() + "] is already not sensing.", SKExceptionErrorCode.SENSOR_CURRENTLY_NOT_SENSING); + } + + // Stop Sensing + mSensors.get(i).stopSensing(); + } + } + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleManager.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleManager.java deleted file mode 100644 index fb0aeb8..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleManager.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib; - -import android.content.Context; -import android.util.Log; -import android.util.SparseArray; - -import org.sensingkit.sensingkitlib.data.SKSensorData; -import org.sensingkit.sensingkitlib.modules.*; - -public class SKSensorModuleManager { - - @SuppressWarnings("unused") - private static final String TAG = "SKSensorModuleManager"; - - private static final int TOTAL_SENSOR_MODULES = 17; - - private static SKSensorModuleManager sSensorModuleManager; - private final Context mApplicationContext; - - private final SparseArray mSensors; - - public static SKSensorModuleManager getSensorManager(final Context context) throws SKException { - - if (context == null) { - throw new SKException(TAG, "Context cannot be null.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - if (sSensorModuleManager == null) { - sSensorModuleManager = new SKSensorModuleManager(context); - } - - return sSensorModuleManager; - } - - private SKSensorModuleManager(final Context context) throws SKException { - - mApplicationContext = context; - - // Init Sensor Array - mSensors = new SparseArray<>(TOTAL_SENSOR_MODULES); - } - - public void registerSensorModule(SKSensorModuleType moduleType) throws SKException { - - Log.i(TAG, "Register sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - if (isSensorModuleRegistered(moduleType)) { - throw new SKException(TAG, "SensorModule is already registered.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - // Register the SensorModule - int sensorIndex = moduleType.ordinal(); - SKAbstractSensorModule sensorModule = createSensorModule(moduleType); - mSensors.put(sensorIndex, sensorModule); - } - - public void deregisterSensorModule(SKSensorModuleType moduleType) throws SKException { - - Log.i(TAG, "Deregister sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - if (!isSensorModuleRegistered(moduleType)) { - throw new SKException(TAG, "SensorModule is not registered.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - if (isSensorModuleSensing(moduleType)) { - throw new SKException(TAG, "SensorModule is currently sensing.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - // Clear all Callbacks from that sensor - getSensorModule(moduleType).unsubscribeAllSensorDataListeners(); - - // Deregister the SensorModule - int sensorIndex = moduleType.ordinal(); - mSensors.delete(sensorIndex); - } - - public boolean isSensorModuleRegistered(SKSensorModuleType moduleType) throws SKException { - - int sensorIndex = moduleType.ordinal(); - return (mSensors.get(sensorIndex) != null); - } - - public boolean isSensorModuleSensing(SKSensorModuleType moduleType) throws SKException { - - if (!isSensorModuleRegistered(moduleType)) { - throw new SKException(TAG, "SensorModule is not registered.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - return getSensorModule(moduleType).isSensing(); - } - - protected SKAbstractSensorModule getSensorModule(SKSensorModuleType moduleType) throws SKException { - - if (!isSensorModuleRegistered(moduleType)) { - throw new SKException(TAG, "SensorModule is not registered.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - int sensorIndex = moduleType.ordinal(); - return mSensors.get(sensorIndex); - } - - protected SKAbstractSensorModule createSensorModule(SKSensorModuleType moduleType) throws SKException { - - SKAbstractSensorModule sensorModule; - - switch (moduleType) { - - case ACCELEROMETER: - sensorModule = new SKAccelerometer(mApplicationContext); - break; - - case GRAVITY: - sensorModule = new SKGravity(mApplicationContext); - break; - - case LINEAR_ACCELERATION: - sensorModule = new SKLinearAcceleration(mApplicationContext); - break; - - case GYROSCOPE: - sensorModule = new SKGyroscope(mApplicationContext); - break; - - case ROTATION: - sensorModule = new SKRotation(mApplicationContext); - break; - - case MAGNETOMETER: - sensorModule = new SKMagnetometer(mApplicationContext); - break; - - case AMBIENT_TEMPERATURE: - sensorModule = new SKAmbientTemperature(mApplicationContext); - break; - - case STEP_DETECTOR: - sensorModule = new SKStepDetector(mApplicationContext); - break; - - case STEP_COUNTER: - sensorModule = new SKStepCounter(mApplicationContext); - break; - - case LIGHT: - sensorModule = new SKLight(mApplicationContext); - break; - - case LOCATION: - sensorModule = new SKLocation(mApplicationContext); - break; - - case ACTIVITY: - sensorModule = new SKActivity(mApplicationContext); - break; - - case BATTERY: - sensorModule = new SKBattery(mApplicationContext); - break; - - case SCREEN_STATUS: - sensorModule = new SKScreenStatus(mApplicationContext); - break; - - case AUDIO_RECORDER: - sensorModule = new SKAudioRecorder(mApplicationContext); - break; - - case AUDIO_LEVEL: - sensorModule = new SKAudioLevel(mApplicationContext); - break; - - case BLUETOOTH: - sensorModule = new SKBluetooth(mApplicationContext); - break; - - // Don't forget the break; here - - default: - throw new SKException(TAG, "Unknown SensorModule", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - return sensorModule; - } - - public SKSensorData getDataFromSensor(SKSensorModuleType moduleType) throws SKException { - - Log.i(TAG, "Get data from sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - throw new SKException(TAG, "This feature is not supported just yet!", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - public void subscribeSensorDataListener(SKSensorModuleType moduleType, SKSensorDataListener dataListener) throws SKException { - - Log.i(TAG, "Subscribe to sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - getSensorModule(moduleType).subscribeSensorDataListener(dataListener); - } - - public void unsubscribeSensorDataListener(SKSensorModuleType moduleType, SKSensorDataListener dataListener) throws SKException { - - Log.i(TAG, "Unsubscribe from sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - getSensorModule(moduleType).unsubscribeSensorDataListener(dataListener); - } - - public void unsubscribeAllSensorDataListeners(SKSensorModuleType moduleType) throws SKException { - - Log.i(TAG, "Unsubscribe from all sensors."); - - getSensorModule(moduleType).unsubscribeAllSensorDataListeners(); - } - - public void startContinuousSensingWithSensor(SKSensorModuleType moduleType) throws SKException { - - Log.i(TAG, "Start sensing with sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - if (isSensorModuleSensing(moduleType)) { - throw new SKException(TAG, "SensorModule is already sensing.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - // Start Sensing - getSensorModule(moduleType).startSensing(); - } - - public void stopContinuousSensingWithSensor(SKSensorModuleType moduleType) throws SKException { - - Log.i(TAG, "Stop sensing with sensor: " + SKSensorModuleUtilities.getSensorModuleInString(moduleType) + "."); - - if (!isSensorModuleSensing(moduleType)) { - throw new SKException(TAG, "SensorModule is already not sensing.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - SKSensorModuleInterface sensorModule = getSensorModule(moduleType); - - // Stop Sensing - sensorModule.stopSensing(); - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorType.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorType.java new file mode 100644 index 0000000..74c7291 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorType.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib; + +import androidx.annotation.NonNull; + +/** + * These constants indicate the type of the sensor. + */ +public enum SKSensorType { + /** + * Measures the device acceleration changes in three-dimensional space. You can use this data to detect both the current orientation of the device (relative to the ground) and any instantaneous changes to that orientation. + */ + ACCELEROMETER ("Accelerometer", "Accelerometer"), + + /** + * Measures the force of gravity in m/s2 that is applied to a device on all three physical axes (x, y, z). + */ + GRAVITY ("Gravity", "Gravity"), + + /** + * Measures the acceleration force in m/s2 that is applied to a device on all three physical axes (x, y, and z), excluding the force of gravity. + */ + LINEAR_ACCELERATION ("Linear Acceleration", "LinearAcceleration"), + + /** + * Measures the device's rate of rotation around each of the three spatial axes. + */ + GYROSCOPE ("Gyroscope", "Gyroscope"), + + /** + * Measures the orientation of a device by providing the three elements of the device's rotation vector. + */ + ROTATION ("Rotation", "Rotation"), + + /** + * Measures the ambient geomagnetic field for all three physical axes (x, y, z) in microtesla. + */ + MAGNETOMETER ("Magnetometer", "Magnetometer"), + + /** + * Room temperature in degrees Celcius. + */ + AMBIENT_TEMPERATURE ("Ambient Temperature", "AmbientTemperature"), + + /** + * Returns 1.0 each time a step is taken + */ + STEP_DETECTOR ("Step Detector", "StepDetector"), + + /** + * Number of steps taken by the user since the last reboot while activated. + */ + STEP_COUNTER ("Step Counter", "StepCounter"), + + /** + * Measures the ambient light level (illumination) in lux. + */ + LIGHT ("Light", "Light"), + + /** + * Location sensor determines the current location of the device using a combination of Cellular, Wi-Fi, Bluetooth and GPS sensors. It provides 2D geographical coordinate information (latitude, longitude), as well as the altitude of the device. + */ + LOCATION ("Location", "Location"), + + /** + * Motion Activity sensor uses an embedded motion co-processor that senses the user's activity classified as Stationary, Walking, Running, Automotive or Cycling. + * Assume that Activity is the same as Motion Activity + */ + MOTION_ACTIVITY ("Motion Activity", "MotionActivity"), + + /** + * Battery Status sensor listens to changes in the battery charge state (Charging, Full, Unplugged) as well as in the battery charge level (with 1% precision). + */ + BATTERY_STATUS("Battery Status", "BatteryStatus"), + + /** + * Senses the status of the screen (On / Off). + */ + SCREEN_STATUS ("Screen Status", "ScreenStatus"), + + /** + * Microphone sensor can be used to record audio from the environment by converting sound into electrical signal. + * Assume that Microphone is the same as AUDIO RECORDER + */ + MICROPHONE ("Microphone", "Microphone"), + + /** + * Maximum level of the audio signal in a buffer. + */ + AUDIO_LEVEL ("Audio Level", "AudioLevel"), + + /** + * Scans for other Bluetooth Classic devices around. + */ + BLUETOOTH ("Bluetooth", "Bluetooth"), + + /** + * Beacon Proximity sensor estimates the proximity of the current device with other iBeacon™, AltBeacon or Eddystone™ beacons in range. + */ + BEACON_PROXIMITY ("Beacon Proximity", "BeaconProximity"), + + /** + * Relative ambient air humidity in percent. + */ + HUMIDITY ("Humidity", "Humidity"), + + /** + * Atmospheric pressure in hPa (millibar). + */ + BAROMETER ("Barometer", "Barometer"), + + /** + * Notifications received in the device. + */ + NOTIFICATION ("Notification", "Notification"); + + private final static int length = SKSensorType.values().length; + + private final String name; + private final String nonspacedName; + + SKSensorType(final @NonNull String name, final @NonNull String nonspacedName) { + this.name = name; + this.nonspacedName = nonspacedName; + } + + /** + * + * @return Total number of sensors supported by SensingKit-Android + */ + @SuppressWarnings("unused") + public static int getLength() { + return SKSensorType.length; + } + + /** + * + * @return The sensor's name + */ + @SuppressWarnings("unused") + public @NonNull String getName() { + return this.name; + } + + /** + * + * @return A monospaced version of the sensor's name + */ + @SuppressWarnings("unused") + public @NonNull String getNonspacedName() { + return this.nonspacedName; + } + + /** + * + * @return The sensor's name + */ + @NonNull + @Override + public String toString() { + return this.getName(); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKUtilities.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKUtilities.java index 3aa2e50..71520b8 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKUtilities.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKUtilities.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,29 +21,56 @@ package org.sensingkit.sensingkitlib; +import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; +import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; -public final class SKUtilities { +@SuppressWarnings("WeakerAccess") +final class SKUtilities { @SuppressWarnings("unused") - private static final String TAG = "SKUtilities"; + private static final String TAG = SKUtilities.class.getSimpleName(); - public static boolean checkPermission(Context context, String permission) throws SKException { + /** + * Check whether a given permission has been granted + * + * @param context Android Context + * + * @param permission Android permission + * + * @return 1 if permission is granted; 0 if it is not + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + static boolean isPermissionGranted(final @NonNull String permission, final @NonNull Context context) { - if (context == null) { - throw new SKException(TAG, "Context cannot be null.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - int res = context.checkCallingOrSelfPermission(permission); + int res = ContextCompat.checkSelfPermission(context, permission); return (res == PackageManager.PERMISSION_GRANTED); } - public static long getCurrentTimeMillis() { + static void requestPermissions(final @NonNull Activity activity, final @NonNull String[] permissions) { + ActivityCompat.requestPermissions(activity, permissions, 0); + } + + /** + * Get the current time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * + * @return the current time in milliseconds + */ + static long getCurrentTimeMillis() { return System.currentTimeMillis(); } - public static long getNanoTime() { + /** + * Get the current time in nanoseconds (the current value of the running Java Virtual Machine's high-resolution time source) + * + * @return the current time in nanoseconds + + */ + static long getNanoTime() { return System.nanoTime(); } + } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKWakeLockManager.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKWakeLockManager.java new file mode 100644 index 0000000..0c83f3a --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKWakeLockManager.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.PowerManager; +import androidx.annotation.NonNull; + +public class SKWakeLockManager { + + @SuppressWarnings("unused") + private static final String TAG = SKWakeLockManager.class.getSimpleName(); + private static SKWakeLockManager sWakeLockManager = null; + + public static SKWakeLockManager getInstance(final @NonNull Context context) throws SKException { + + if (sWakeLockManager == null) { + sWakeLockManager = new SKWakeLockManager(context); + } + return sWakeLockManager; + } + + private SKWakeLockManager(final @NonNull Context context) throws SKException { + + if (!SKUtilities.isPermissionGranted(Manifest.permission.WAKE_LOCK, context)) { + throw new SKException(TAG, "Permission WAKE_LOCK is missing.", SKExceptionErrorCode.PERMISSION_MISSING); + } + + PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (powerManager == null) { + throw new SKException(TAG, "Could not access the system service: POWER_SERVICE.", SKExceptionErrorCode.UNKNOWN_ERROR); + } + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SensingKit:WakeLock"); + mLocksCounter = 0; + } + + private PowerManager.WakeLock mWakeLock; + private int mLocksCounter; + +// public boolean isWakeLockActive() { +// return mWakeLock.isHeld(); +// } + + @SuppressLint("WakelockTimeout") + public void acquireWakeLock() { + + mLocksCounter++; + mWakeLock.acquire(); + } + + public void releaseWakeLock() { + + if (mLocksCounter == 0) { + throw new RuntimeException("WakeLock calls are imbalanced: (mLocksCounter == 0)"); + } + + mWakeLock.release(); + mLocksCounter--; + } + + @Override + public @NonNull String toString() { + return "mLocksCounter: " + mLocksCounter; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLib.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLib.java index 82d4d2e..540f124 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLib.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLib.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,30 +21,28 @@ package org.sensingkit.sensingkitlib; +import android.app.Activity; import android.content.Context; -import android.os.PowerManager; - -import org.sensingkit.sensingkitlib.data.SKSensorData; +import androidx.annotation.NonNull; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.sensors.SKSensorUtilities; +@SuppressWarnings({"StaticFieldLeak"}) public class SensingKitLib implements SensingKitLibInterface { @SuppressWarnings("unused") - private static final String TAG = "SensingKitLib"; - + private static final String TAG = SensingKitLib.class.getSimpleName(); private static SensingKitLib sSensingKitLib; + private final SKSensorManager mSensorManager; - private final Context mApplicationContext; - private PowerManager.WakeLock mWakeLock; - - private SKSensorModuleManager mSensorModuleManager; - + /** + * + * @param context + * @return + */ @SuppressWarnings("unused") - public static SensingKitLibInterface getSensingKitLib(final Context context) throws SKException { - - if (context == null) { - throw new SKException(TAG, "Context cannot be null", SKExceptionErrorCode.UNKNOWN_ERROR); - } + public static SensingKitLibInterface sharedSensingKitLib(final @NonNull Context context) { if (sSensingKitLib == null) { sSensingKitLib = new SensingKitLib(context); @@ -53,92 +51,226 @@ public static SensingKitLibInterface getSensingKitLib(final Context context) thr return sSensingKitLib; } - private SensingKitLib(final Context context) throws SKException { - mApplicationContext = context; - mSensorModuleManager = SKSensorModuleManager.getSensorManager(context); + /** + * + * @param context + */ + private SensingKitLib(final @NonNull Context context) { + mSensorManager = SKSensorManager.getSensorManager(context); } + /** + * A Boolean value that indicates whether the sensor is available on the device. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is available on the device, or FALSE if it is not. + */ @Override - public void registerSensorModule(SKSensorModuleType moduleType) throws SKException { - mSensorModuleManager.registerSensorModule(moduleType); + public boolean isSensorAvailable(final SKSensorType sensorType) { + return mSensorManager.isSensorAvailable(sensorType); } + /** + * A Boolean value that indicates whether the sensor is registered. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is registered or FALSE if it is not. + */ @Override - public void deregisterSensorModule(SKSensorModuleType moduleType) throws SKException { - mSensorModuleManager.deregisterSensorModule(moduleType); + public boolean isSensorRegistered(final SKSensorType sensorType) { + return mSensorManager.isSensorRegistered(sensorType); } + /** + * A Boolean value that indicates whether the sensor is currently sensing. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is currently sensing or FALSE if it is not. + */ @Override - public boolean isSensorModuleRegistered(SKSensorModuleType moduleType) throws SKException { - return mSensorModuleManager.isSensorModuleRegistered(moduleType); + public boolean isSensorSensing(final SKSensorType sensorType) throws SKException { + return mSensorManager.isSensorSensing(sensorType); } + /** + * Initializes and registers a sensor into the library with a default sensor configuration. + * + * @param sensorType The type of the sensor that will be initialized and registered in the library. + */ @Override - public SKSensorData getDataFromSensor(SKSensorModuleType moduleType) throws SKException { - return mSensorModuleManager.getDataFromSensor(moduleType); + public void registerSensor(final SKSensorType sensorType) throws SKException { + registerSensor(sensorType, null); } @Override - public void subscribeSensorDataListener(SKSensorModuleType moduleType, SKSensorDataListener dataListener) throws SKException { - mSensorModuleManager.subscribeSensorDataListener(moduleType, dataListener); + public void registerSensor(final SKSensorType sensorType, final SKConfiguration configuration) throws SKException { + mSensorManager.registerSensor(sensorType, configuration); } + /** + * Deregisters a sensor from the library. Sensor should not be actively sensing when this method is called. All previously subscribed blocks will also be unsubscribed. + * + * @param sensorType The type of the sensor that will be deregistered. + */ @Override - public void unsubscribeSensorDataListener(SKSensorModuleType moduleType, SKSensorDataListener dataListener) throws SKException { - mSensorModuleManager.unsubscribeSensorDataListener(moduleType, dataListener); + public void deregisterSensor(final SKSensorType sensorType) throws SKException { + mSensorManager.deregisterSensor(sensorType); } + /** + * + * @param configuration A configuration object that conforms to SKConfiguration. If no configuration is specified, it will default to a pre-determined sensor configuration. + * @param sensorType The type of the sensor that will be configured. + * @throws SKException + */ @Override - public void unsubscribeAllSensorDataListeners(SKSensorModuleType moduleType) throws SKException { - mSensorModuleManager.unsubscribeAllSensorDataListeners(moduleType); + public void setConfiguration(final SKConfiguration configuration, final SKSensorType sensorType) throws SKException { + mSensorManager.setConfiguration(configuration, sensorType); } + /** + * + * @param sensorType The type of the sensor. + * @return + * @throws SKException + */ @Override - public void startContinuousSensingWithSensor(SKSensorModuleType moduleType) throws SKException { - mSensorModuleManager.startContinuousSensingWithSensor(moduleType); + public @NonNull SKConfiguration getConfiguration(final SKSensorType sensorType) throws SKException { + return mSensorManager.getConfiguration(sensorType); } + /** + * Subscribes for sensor updates using a specified data handler. + * + * @param sensorType The type of the sensor that the data handler will be subscribed to. + * @param dataHandler A data handler that is invoked with each update to handle new sensor data. The block must conform to the SKSensorDataHandler type. + */ @Override - public void stopContinuousSensingWithSensor(SKSensorModuleType moduleType) throws SKException { - mSensorModuleManager.stopContinuousSensingWithSensor(moduleType); + public void subscribeSensorDataHandler(final SKSensorType sensorType, final @NonNull SKSensorDataHandler dataHandler) throws SKException { + mSensorManager.subscribeSensorDataHandler(sensorType, dataHandler); } + /** + * Unsubscribes a data handler. + * + * @param sensorType The type of the sensor for which the event listener will be unsubscribed. + * @param dataHandler The data handler to be unsubscribed. + */ @Override - public boolean isSensorModuleSensing(SKSensorModuleType moduleType) throws SKException { - return mSensorModuleManager.isSensorModuleSensing(moduleType); + public void unsubscribeSensorDataHandler(final SKSensorType sensorType, final @NonNull SKSensorDataHandler dataHandler) throws SKException { + mSensorManager.unsubscribeSensorDataHandler(sensorType, dataHandler); } + /** + * Unsubscribes all data handlers. + * + * @param sensorType The type of the sensor for which the data handlers will be unsubscribed. + */ @Override - public long getCurrentTimeMillis() { - return SKUtilities.getCurrentTimeMillis(); + public void unsubscribeAllSensorDataHandlers(final SKSensorType sensorType) throws SKException { + mSensorManager.unsubscribeAllSensorDataHandlers(sensorType); } + /** + * A string with a CSV formatted header that describes the data of the particular sensor. This method is useful in combination with the toString() or csvString() instance method of an SKSensorData object. + * + * @param sensorType The type of the sensor for which the CSV Header will be returned. + * + * @return A String with the CSV header. + */ @Override - public long getNanoTime() { - return SKUtilities.getNanoTime(); + public @NonNull String csvHeaderForSensor(final SKSensorType sensorType) { + return SKSensorUtilities.csvHeaderForSensor(sensorType); } - //region Wake Lock methods + /** + * + * @param sensorType + * @return + * @throws SKException + */ + @Override + public boolean isPermissionGrantedForSensor(final SKSensorType sensorType) throws SKException { + return mSensorManager.isPermissionGrantedForSensor(sensorType); + } - private void acquireWakeLock() { - if ((mWakeLock == null) || (!mWakeLock.isHeld())) { - PowerManager pm = (PowerManager) mApplicationContext.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock"); - mWakeLock.acquire(); - } + /** + * + * @param sensorType + * @param activity + * @throws SKException + */ + @Override + public void requestPermissionForSensor(final SKSensorType sensorType, final @NonNull Activity activity) throws SKException { + mSensorManager.requestPermissionForSensor(sensorType, activity); } - private void releaseWakeLock() { - if (mWakeLock != null && mWakeLock.isHeld()) { - mWakeLock.release(); - } + /** + * + * @param activity + */ + @Override + public void requestPermissionForAllRegisteredSensors(final @NonNull Activity activity) { + mSensorManager.requestPermissionForAllRegisteredSensors(activity); + } + + /** + * Starts continuous sensing with the specified sensor. + * + * @param sensorType The type of the sensor that will be started. + */ + @Override + public void startContinuousSensingWithSensor(final SKSensorType sensorType) throws SKException { + mSensorManager.startContinuousSensingWithSensor(sensorType); + } + + /** + * Stops continuous sensing with the specified sensor. + * + * @param sensorType The type of the sensor that will be stopped. + */ + @Override + public void stopContinuousSensingWithSensor(final SKSensorType sensorType) throws SKException { + mSensorManager.stopContinuousSensingWithSensor(sensorType); + } + + /** + * Starts continuous sensing with all registered sensors. + */ + @Override + public void startContinuousSensingWithAllRegisteredSensors() throws SKException { + mSensorManager.startContinuousSensingWithAllRegisteredSensors(); + } + + /** + * Starts continuous sensing with all registered sensors. + */ + @Override + public void stopContinuousSensingWithAllRegisteredSensors() throws SKException { + mSensorManager.stopContinuousSensingWithAllRegisteredSensors(); } - private boolean checkWakeLockPermission() throws SKException { - return SKUtilities.checkPermission( - mApplicationContext, - "android.permission.WAKE_LOCK"); + /** + * Get the current time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC). + * + * @return current time in milliseconds + */ + @Override + public long getCurrentTimeMillis() { + return SKUtilities.getCurrentTimeMillis(); + } + + /** + * Get the current time in nanoseconds (the current value of the running Java Virtual Machine's high-resolution time source) + * + * @return current time in nanoseconds + */ + @Override + public long getNanoTime() { + return SKUtilities.getNanoTime(); } - //endregion } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLibInterface.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLibInterface.java index 3e1e2f3..113943f 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLibInterface.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SensingKitLibInterface.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,46 +21,172 @@ package org.sensingkit.sensingkitlib; -import org.sensingkit.sensingkitlib.data.SKSensorData; +import android.app.Activity; +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; @SuppressWarnings("unused") public interface SensingKitLibInterface { - /** Sensor Registration */ - - void registerSensorModule(SKSensorModuleType moduleType) throws SKException; - - void deregisterSensorModule(SKSensorModuleType moduleType) throws SKException; - - boolean isSensorModuleRegistered(SKSensorModuleType moduleType) throws SKException; - - /** Configuration */ - // TODO: Add Configuration - - - /** One Shot Sensing */ - - SKSensorData getDataFromSensor(SKSensorModuleType moduleType) throws SKException; - - - /** Continuous Sensing */ - - void subscribeSensorDataListener(SKSensorModuleType moduleType, SKSensorDataListener dataListener) throws SKException; - - void unsubscribeSensorDataListener(SKSensorModuleType moduleType, SKSensorDataListener dataListener) throws SKException; - - void unsubscribeAllSensorDataListeners(SKSensorModuleType moduleType) throws SKException; - - void startContinuousSensingWithSensor(SKSensorModuleType moduleType) throws SKException; - - void stopContinuousSensingWithSensor(SKSensorModuleType moduleType) throws SKException; - - boolean isSensorModuleSensing(SKSensorModuleType moduleType) throws SKException; - - /** Time */ - + /** + * A Boolean value that indicates whether the sensor is available on the device. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is available on the device, or FALSE if it is not. + */ + boolean isSensorAvailable(final SKSensorType sensorType); + + /** + * A Boolean value that indicates whether the sensor is registered. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is registered or FALSE if it is not. + */ + boolean isSensorRegistered(final SKSensorType sensorType); + + /** + * A Boolean value that indicates whether the sensor is currently sensing. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is currently sensing or FALSE if it is not. + */ + boolean isSensorSensing(final SKSensorType sensorType) throws SKException; + + /** + * Initializes and registers a sensor into the library with a default sensor configuration. + * + * @param sensorType The type of the sensor that will be initialized and registered in the library. + */ + void registerSensor(final SKSensorType sensorType) throws SKException; + + /** + * Initializes and registers a sensor into the library with a custom sensor configuration. + * + * @param sensorType The type of the sensor that will be initialized and registered in the library. + * @param configuration A configuration object that conforms to SKConfiguration. If no configuration is specified, it will default to a pre-determined sensor configuration. + */ + void registerSensor(final SKSensorType sensorType, final SKConfiguration configuration) throws SKException; + + /** + * Deregisters a sensor from the library. Sensor should not be actively sensing when this method is called. All previously subscribed data handlers will also be unsubscribed. + * + * @param sensorType The type of the sensor that will be deregistered. + */ + void deregisterSensor(final SKSensorType sensorType) throws SKException; + + /** + * Provides custom configuration to a sensor. + * + * @param configuration A configuration object that conforms to SKConfiguration. If no configuration is specified, it will default to a pre-determined sensor configuration. + * @param sensorType The type of the sensor that will be configured. + */ + void setConfiguration(final SKConfiguration configuration, final SKSensorType sensorType) throws SKException; + + /** + * Gets the configuration of a sensor. + * + * @param sensorType The type of the sensor. + */ + @NonNull + SKConfiguration getConfiguration(final SKSensorType sensorType) throws SKException; + + /** + * Subscribes for sensor updates using a specified data handler. + * + * @param sensorType The type of the sensor that the data handler will be subscribed to. + * @param dataHandler A data handler that is invoked with each update to handle new sensor data. The block must conform to the SKSensorDataHandler type. + */ + void subscribeSensorDataHandler(final SKSensorType sensorType, final @NonNull SKSensorDataHandler dataHandler) throws SKException; + + /** + * Unsubscribes a data handler. + * + * @param sensorType The type of the sensor for which the event listener will be unsubscribed. + * @param dataHandler The data handler to be unsubscribed. + */ + void unsubscribeSensorDataHandler(final SKSensorType sensorType, final @NonNull SKSensorDataHandler dataHandler) throws SKException; + + /** + * Unsubscribes all data handlers. + * + * @param sensorType The type of the sensor for which the data handlers will be unsubscribed. + */ + void unsubscribeAllSensorDataHandlers(final SKSensorType sensorType) throws SKException; + + /** + * A string with a CSV formatted header that describes the data of the particular sensor. This method is useful in combination with the toString() or csvString() instance method of an SKSensorData object. + * + * @param sensorType The type of the sensor for which the CSV Header will be returned. + * + * @return A String with the CSV header. + */ + @NonNull + String csvHeaderForSensor(final SKSensorType sensorType); + + /** + * TODO: + * + * @param sensorType + * @return + * @throws SKException + */ + boolean isPermissionGrantedForSensor(final SKSensorType sensorType) throws SKException; + + /** + * TODO: + * + * @param sensorType + * @param activity + * @throws SKException + */ + void requestPermissionForSensor(final SKSensorType sensorType, final @NonNull Activity activity) throws SKException ; + + /** + * TODO: + * + * @param activity + */ + void requestPermissionForAllRegisteredSensors(final @NonNull Activity activity); + + /** + * Starts continuous sensing with the specified sensor. + * + * @param sensorType The type of the sensor that will be started. + */ + void startContinuousSensingWithSensor(final SKSensorType sensorType) throws SKException; + + /** + * Stops continuous sensing with the specified sensor. + * + * @param sensorType The type of the sensor that will be stopped. + */ + void stopContinuousSensingWithSensor(final SKSensorType sensorType) throws SKException; + + /** + * Starts continuous sensing with all registered sensors. + */ + void startContinuousSensingWithAllRegisteredSensors() throws SKException; + + /** + * Starts continuous sensing with all registered sensors. + */ + void stopContinuousSensingWithAllRegisteredSensors() throws SKException; + + /** + * Get the current time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC). + * + * @return current time in milliseconds + */ long getCurrentTimeMillis(); + /** + * Get the current time in nanoseconds (the current value of the running Java Virtual Machine's high-resolution time source) + * + * @return current time in nanoseconds + */ long getNanoTime(); - } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAbstractConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAbstractConfiguration.java new file mode 100644 index 0000000..a2480a0 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAbstractConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +@SuppressWarnings("unused") +public abstract class SKAbstractConfiguration implements SKConfiguration { + + private boolean requestWakeLock; + private boolean debugStatus; + + // TODO: Add Documentation + public SKAbstractConfiguration() { + + // Set default + this.requestWakeLock = true; + this.debugStatus = false; + } + + public void setRequestWakeLock(final boolean requestWakeLock) { + this.requestWakeLock = requestWakeLock; + } + + public boolean getRequestWakeLock() { + return this.requestWakeLock; + } + + public void setDebugStatus(final boolean debugSensor) { + this.debugStatus = debugSensor; + } + + public boolean getDebugStatus() { + return this.debugStatus; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAbstractNativeSensorConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAbstractNativeSensorConfiguration.java new file mode 100644 index 0000000..d5f3419 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAbstractNativeSensorConfiguration.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import android.hardware.SensorManager; + +@SuppressWarnings("WeakerAccess") +public abstract class SKAbstractNativeSensorConfiguration extends SKAbstractConfiguration { + + @SuppressWarnings({"unused", "WeakerAccess"}) + public final class SKSensorDelay { + + public static final int FASTEST = SensorManager.SENSOR_DELAY_FASTEST; + public static final int GAME = SensorManager.SENSOR_DELAY_GAME; + public static final int NORMAL = SensorManager.SENSOR_DELAY_NORMAL; + public static final int UI = SensorManager.SENSOR_DELAY_UI; + + SKSensorDelay() { + throw new RuntimeException(); + } + } + + protected int samplingRate; + + public SKAbstractNativeSensorConfiguration() { + super(); + + // Set default values + this.samplingRate = SKSensorDelay.NORMAL; + } + + public SKAbstractNativeSensorConfiguration(final int samplingRate) { + super(); + + this.samplingRate = samplingRate; + } + + @SuppressWarnings("unused") + public int getSamplingRate() { + return this.samplingRate; + } + + @SuppressWarnings("unused") + public void setSamplingRate(final int samplingRate) { + this.samplingRate = samplingRate; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAccelerometerConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAccelerometerConfiguration.java new file mode 100644 index 0000000..3867436 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAccelerometerConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKAccelerometerConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKAccelerometerConfiguration() { + super(); + + // Set default values + } + + public SKAccelerometerConfiguration(SKAccelerometerConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.ACCELEROMETER); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAmbientTemperatureConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAmbientTemperatureConfiguration.java new file mode 100644 index 0000000..aee15da --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAmbientTemperatureConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKAmbientTemperatureConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKAmbientTemperatureConfiguration() { + super(); + + // Set default values + } + + public SKAmbientTemperatureConfiguration(SKAmbientTemperatureConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.AMBIENT_TEMPERATURE); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAudioLevelConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAudioLevelConfiguration.java new file mode 100644 index 0000000..2ee9042 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKAudioLevelConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKAudioLevelConfiguration extends SKAbstractConfiguration { + + public SKAudioLevelConfiguration() { + super(); + + // Set default values + } + + @SuppressWarnings("unused") + public SKAudioLevelConfiguration(SKAudioLevelConfiguration configuration) { + super(); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.AUDIO_LEVEL); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBarometerConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBarometerConfiguration.java new file mode 100644 index 0000000..728b2dd --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBarometerConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKBarometerConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKBarometerConfiguration() { + super(); + + // Set default values + } + + public SKBarometerConfiguration(SKBarometerConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.BAROMETER); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBatteryStatusConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBatteryStatusConfiguration.java new file mode 100644 index 0000000..8507191 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBatteryStatusConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKBatteryStatusConfiguration extends SKAbstractConfiguration { + + public SKBatteryStatusConfiguration() { + super(); + + // Set default values + } + + @SuppressWarnings("unused") + public SKBatteryStatusConfiguration(SKBatteryStatusConfiguration configuration) { + super(); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.BATTERY_STATUS); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBeaconProximityConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBeaconProximityConfiguration.java new file mode 100644 index 0000000..70d4a79 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBeaconProximityConfiguration.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.SKSensorType; + +@SuppressWarnings("WeakerAccess") +public class SKBeaconProximityConfiguration extends SKAbstractConfiguration { + + public enum SKBeaconType { + + /** + * TODO + */ + ALTBEACON("AltBeacon"), + + /** + * TODO + */ + IBEACON("iBeacon"), + + /** + * TODO + */ + EDDYSTONE_UID("Eddystone-UID"); + + private final String name; + + SKBeaconType(final @NonNull String name) { + this.name = name; + } + + @SuppressWarnings("unused") + public @NonNull String getName() { + return this.name; + } + + @NonNull + @Override + public String toString() { + return this.getName(); + } + } + + private SKBeaconType beaconType; + + // Filters + private String filterId1; + private String filterId2; + private String filterId3; + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.BEACON_PROXIMITY); + } + + @SuppressWarnings("unused") + public SKBeaconProximityConfiguration() { + this(SKBeaconType.ALTBEACON, null, null, null); + } + + @SuppressWarnings("unused") + public SKBeaconProximityConfiguration(final SKBeaconType beaconType) { + this(beaconType, null, null, null); + } + + @SuppressWarnings("unused") + public SKBeaconProximityConfiguration(final SKBeaconType beaconType, String filterId1) { + this(beaconType, filterId1, null, null); + } + + @SuppressWarnings("unused") + public SKBeaconProximityConfiguration(final SKBeaconType beaconType, String filterId1, String filterId2) { + this(beaconType, filterId1, filterId2, null); + } + + @SuppressWarnings("unused") + public SKBeaconProximityConfiguration(final SKBeaconType beaconType, String filterId1, String filterId2, String filterId3) { + super(); + + // Set default values + this.beaconType = beaconType; + this.filterId1 = filterId1; + this.filterId2 = filterId2; + this.filterId3 = filterId3; + } + + public SKBeaconProximityConfiguration(SKBeaconProximityConfiguration configuration) { + super(); + + // Save local configuration + beaconType = configuration.beaconType; + filterId1 = configuration.filterId1; + filterId2 = configuration.filterId2; + filterId3 = configuration.filterId3; + } + + @SuppressWarnings("unused") + public SKBeaconType getBeaconType() { + return beaconType; + } + + @SuppressWarnings("unused") + public void setBeaconType(final SKBeaconType beaconType) { + this.beaconType = beaconType; + } + + @SuppressWarnings("unused") + public final String getFilterId1() { + return filterId1; + } + + @SuppressWarnings("unused") + public void setFilterId1(final String filterId1) { + this.filterId1 = filterId1; + } + + @SuppressWarnings("unused") + public final String getFilterId2() { + return filterId2; + } + + @SuppressWarnings("unused") + public void setFilterId2(final String filterId2) { + this.filterId2 = filterId2; + } + + @SuppressWarnings("unused") + public final String getFilterId3() { + return filterId3; + } + + @SuppressWarnings("unused") + public void setFilterId3(final String filterId3) { + this.filterId3 = filterId3; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBluetoothConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBluetoothConfiguration.java new file mode 100644 index 0000000..716a0b0 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKBluetoothConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKBluetoothConfiguration extends SKAbstractConfiguration { + + public SKBluetoothConfiguration() { + super(); + + // Set default values + } + + @SuppressWarnings("unused") + public SKBluetoothConfiguration(SKBluetoothConfiguration configuration) { + super(); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.BLUETOOTH); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleType.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKConfiguration.java similarity index 54% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleType.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKConfiguration.java index 63a8454..6e32111 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/SKSensorModuleType.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKConfiguration.java @@ -1,9 +1,9 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org + * For more information, please visit https://www.sensingkit.org * * SensingKit-Android is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -19,24 +19,19 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib; +package org.sensingkit.sensingkitlib.configuration; -public enum SKSensorModuleType { - ACCELEROMETER, - GRAVITY, - LINEAR_ACCELERATION, - GYROSCOPE, - ROTATION, - MAGNETOMETER, - AMBIENT_TEMPERATURE, - STEP_DETECTOR, - STEP_COUNTER, - LIGHT, - LOCATION, - ACTIVITY, - BATTERY, - SCREEN_STATUS, - AUDIO_RECORDER, - AUDIO_LEVEL, - BLUETOOTH -} \ No newline at end of file +import org.sensingkit.sensingkitlib.SKSensorType; + +@SuppressWarnings("unused") +public interface SKConfiguration { + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + boolean isValidForSensor(final SKSensorType sensorType); + + void setRequestWakeLock(final boolean requestWakeLock); + boolean getRequestWakeLock(); + + void setDebugStatus(final boolean debugStatus); + boolean getDebugStatus(); +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKGravityConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKGravityConfiguration.java new file mode 100644 index 0000000..3b6c55b --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKGravityConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKGravityConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKGravityConfiguration() { + super(); + + // Set default values + } + + public SKGravityConfiguration(SKGravityConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.GRAVITY); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKGyroscopeConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKGyroscopeConfiguration.java new file mode 100644 index 0000000..7c844d9 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKGyroscopeConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKGyroscopeConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKGyroscopeConfiguration() { + super(); + + // Set default values + } + + public SKGyroscopeConfiguration(SKGyroscopeConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.GYROSCOPE); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKHumidityConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKHumidityConfiguration.java new file mode 100644 index 0000000..d878e83 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKHumidityConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKHumidityConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKHumidityConfiguration() { + super(); + + // Set default values + } + + public SKHumidityConfiguration(SKHumidityConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.HUMIDITY); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLightConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLightConfiguration.java new file mode 100644 index 0000000..b38b632 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLightConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKLightConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKLightConfiguration() { + super(); + + // Set default values + } + + public SKLightConfiguration(SKLightConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.LIGHT); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLinearAccelerationConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLinearAccelerationConfiguration.java new file mode 100644 index 0000000..19f3a26 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLinearAccelerationConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKLinearAccelerationConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKLinearAccelerationConfiguration() { + super(); + + // Set default values + } + + public SKLinearAccelerationConfiguration(SKLinearAccelerationConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.LINEAR_ACCELERATION); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLocationConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLocationConfiguration.java new file mode 100644 index 0000000..05852e5 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKLocationConfiguration.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import androidx.annotation.NonNull; + +import com.google.android.gms.location.LocationRequest; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKLocationConfiguration extends SKAbstractConfiguration { + + @SuppressWarnings({"WeakerAccess", "unused"}) + public enum SKPriority { + + /** + * TODO + */ + HIGH_ACCURACY("High Accuracy", LocationRequest.PRIORITY_HIGH_ACCURACY), + + /** + * TODO + */ + BALANCED_POWER_ACCURACY("Balanced Power Accuracy", LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY), + + /** + * TODO + */ + LOW_POWER("Low Power", LocationRequest.PRIORITY_LOW_POWER), + + /** + * TODO + */ + NO_POWER("No Power", LocationRequest.PRIORITY_NO_POWER); + + private final int priorityCode; + private final @NonNull String name; + + SKPriority(final @NonNull String name, final int priorityCode) { + this.name = name; + this.priorityCode = priorityCode; + } + + @SuppressWarnings("unused") + public @NonNull String getName() { + return this.name; + } + + @SuppressWarnings("unused") + public int getPriorityCode() { + return this.priorityCode; + } + + @NonNull + @Override + public String toString() { + return this.getName(); + } + } + + private SKPriority priority; + private int interval; + private int fastestInterval; + + public SKLocationConfiguration() { + super(); + + // Set default values + this.priority = SKPriority.HIGH_ACCURACY; + this.interval = 1000; + this.fastestInterval = 500; + } + + public SKLocationConfiguration(SKLocationConfiguration configuration) { + super(); + + // Save local configuration + this.priority = configuration.priority; + this.interval = configuration.interval; + this.fastestInterval = configuration.fastestInterval; + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.LOCATION); + } + + @SuppressWarnings("unused") + public SKPriority getPriority() { + return priority; + } + + @SuppressWarnings("unused") + public void setPriority(final SKPriority priority) { + this.priority = priority; + } + + @SuppressWarnings("unused") + public int getInterval() { + return interval; + } + + @SuppressWarnings("unused") + public void setInterval(final int interval) { + this.interval = interval; + } + + @SuppressWarnings("unused") + public int getFastestInterval() { + return fastestInterval; + } + + @SuppressWarnings("unused") + public void setFastestInterval(final int fastestInterval) { + this.fastestInterval = fastestInterval; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMagnetometerConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMagnetometerConfiguration.java new file mode 100644 index 0000000..69ddc5e --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMagnetometerConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKMagnetometerConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKMagnetometerConfiguration() { + super(); + + // Set default values + } + + public SKMagnetometerConfiguration(SKMagnetometerConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.MAGNETOMETER); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMicrophoneConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMicrophoneConfiguration.java new file mode 100644 index 0000000..7bda884 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMicrophoneConfiguration.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import android.media.MediaRecorder; +import android.os.Environment; +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.io.File; + +@SuppressWarnings({"unused"}) +public class SKMicrophoneConfiguration extends SKAbstractConfiguration { + + public enum SKAudioSource { + + /** + * TODO + */ + CAMCORDER("Camcorder", MediaRecorder.AudioSource.CAMCORDER), + + /** + * TODO + */ + MIC("Mic", MediaRecorder.AudioSource.MIC), + + /** + * TODO + */ + VOICE_CALL("Voice Call", MediaRecorder.AudioSource.VOICE_CALL), + + /** + * TODO + */ + VOICE_COMMUNICATION("Voice Communication", MediaRecorder.AudioSource.VOICE_COMMUNICATION), + + /** + * TODO + */ + VOICE_DOWNLINK("Voice Downlink", MediaRecorder.AudioSource.VOICE_DOWNLINK), + + /** + * TODO + */ + VOICE_RECOGNITION("Voice Recognition", MediaRecorder.AudioSource.VOICE_RECOGNITION), + + /** + * TODO + */ + VOICE_UPLINK("Voice Uplink", MediaRecorder.AudioSource.VOICE_UPLINK); + + private final String name; + private final int audioSourceCode; + + SKAudioSource(final @NonNull String name, final int audioSourceCode) { + this.name = name; + this.audioSourceCode = audioSourceCode; + } + + @SuppressWarnings("unused") + public @NonNull String getName() { + return this.name; + } + + public int getAudioSourceCode() { + return audioSourceCode; + } + + @NonNull + @Override + public String toString() { + return this.getName(); + } + } + + public enum SKOutputFormat { + + /** + * TODO + */ + AAC_ADTS("AAC ADTS", MediaRecorder.OutputFormat.AAC_ADTS, "m4a"), + + /** + * TODO + */ + AMR_NB("AMR NB", MediaRecorder.OutputFormat.AMR_NB, "amr"), + + /** + * TODO + */ + AMR_WB("AMR WB", MediaRecorder.OutputFormat.AMR_WB, "awb"), + + /** + * TODO + */ + MPEG_4("MPEG 4", MediaRecorder.OutputFormat.MPEG_4, "m4a"); + + private final String name; + private final int outputFormatCode; + private final @NonNull String extension; + + SKOutputFormat(final @NonNull String name, final int outputFormatCode, final @NonNull String extension) { + this.name = name; + this.outputFormatCode = outputFormatCode; + this.extension = extension; + } + + @SuppressWarnings("unused") + public @NonNull String getName() { + return this.name; + } + + public int getOutputFormatCode() { + return outputFormatCode; + } + + @NonNull + public String getExtension() { + return extension; + } + + @NonNull + @Override + public String toString() { + return this.getName(); + } + } + + public enum SKAudioEncoder { + + /** + * TODO + */ + AAC("AAC", MediaRecorder.AudioEncoder.AAC), + + /** + * TODO + */ + AAC_ELD("AAC ELD", MediaRecorder.AudioEncoder.AAC_ELD), + + /** + * TODO + */ + AMR_NB("AMR NB", MediaRecorder.AudioEncoder.AMR_NB), + + /** + * TODO + */ + AMR_WB("AMW WB", MediaRecorder.AudioEncoder.AMR_WB), + + /** + * TODO + */ + HE_AAC("HE AAC", MediaRecorder.AudioEncoder.HE_AAC); + + private final String name; + private final int audioEncoderCode; + + SKAudioEncoder(final @NonNull String name, final int audioEncoderCode) { + this.name = name; + this.audioEncoderCode = audioEncoderCode; + } + + @SuppressWarnings("unused") + public @NonNull String getName() { + return this.name; + } + + public int getAudioEncoderCode() { + return audioEncoderCode; + } + + @NonNull + @Override + public String toString() { + return this.getName(); + } + } + + private String filename; + private File outputDirectory; + private SKAudioSource audioSource; + private SKOutputFormat outputFormat; + private SKAudioEncoder audioEncoder; + private int bitrate; + private int samplingRate; + private int audioChannels; + + public SKMicrophoneConfiguration() { + super(); + + // Set default values + this.filename = "recording"; + this.outputDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + this.audioSource = SKAudioSource.MIC; + this.outputFormat = SKOutputFormat.MPEG_4; + this.audioEncoder = SKAudioEncoder.AAC; + this.bitrate = 96000; + this.samplingRate = 44100; + this.audioChannels = 1; + } + + public SKMicrophoneConfiguration(SKMicrophoneConfiguration configuration) { + super(); + + // Save local configuration + this.filename = configuration.filename; + this.outputDirectory = configuration.outputDirectory; + this.audioSource = configuration.audioSource; + this.outputFormat = configuration.outputFormat; + this.audioEncoder = configuration.audioEncoder; + this.bitrate = configuration.bitrate; + this.samplingRate = configuration.samplingRate; + this.audioChannels = configuration.audioChannels; + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.MICROPHONE); + } + + @SuppressWarnings("unused") + public String getFilename() { + return filename; + } + + @SuppressWarnings("unused") + public void setFilename(final String filename) { + this.filename = filename; + } + + @SuppressWarnings("unused") + public File getOutputDirectory() { + return outputDirectory; + } + + @SuppressWarnings("unused") + public void setOutputDirectory(final File outputDirectory) { + this.outputDirectory = outputDirectory; + } + + @SuppressWarnings("unused") + public File getRecordingFile() { + + // filename.extension + String filename = this.filename + "." + outputFormat.getExtension(); + + // return the full path + return new File(this.outputDirectory, filename); + } + + @SuppressWarnings("unused") + public String getRecordingPath() { + + return getRecordingFile().getPath(); + } + + @SuppressWarnings("unused") + public SKAudioSource getAudioSource() { + return audioSource; + } + + @SuppressWarnings("unused") + public void setAudioSource(final SKAudioSource audioSource) { + this.audioSource = audioSource; + } + + @SuppressWarnings("unused") + public SKOutputFormat getOutputFormat() { + return outputFormat; + } + + @SuppressWarnings("unused") + public void setOutputFormat(final SKOutputFormat outputFormat) { + this.outputFormat = outputFormat; + } + + @SuppressWarnings("unused") + public SKAudioEncoder getAudioEncoder() { + return audioEncoder; + } + + @SuppressWarnings("unused") + public void setAudioEncoder(final SKAudioEncoder audioEncoder) { + this.audioEncoder = audioEncoder; + } + + @SuppressWarnings("unused") + public void setBitrate(final int bitrate) { + this.bitrate = bitrate; + } + + @SuppressWarnings("unused") + public int getBitrate() { + return bitrate; + } + + @SuppressWarnings("unused") + public void setSamplingRate(final int samplingRate) { + this.samplingRate = samplingRate; + } + + @SuppressWarnings("unused") + public int getSamplingRate() { + return samplingRate; + } + + @SuppressWarnings("unused") + public void setAudioChannels(final int audioChannels) { + this.audioChannels = audioChannels; + } + + @SuppressWarnings("unused") + public int getAudioChannels() { + return audioChannels; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMotionActivityConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMotionActivityConfiguration.java new file mode 100644 index 0000000..1c75ce9 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKMotionActivityConfiguration.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKMotionActivityConfiguration extends SKAbstractConfiguration { + + // Tracked Activities + private boolean trackStationary; + private boolean trackWalking; + private boolean trackRunning; + private boolean trackAutomotive; + private boolean trackCycling; + + public SKMotionActivityConfiguration() { + super(); + + // Set default values + this.trackStationary = true; + this.trackWalking = true; + this.trackRunning = true; + this.trackAutomotive = true; + this.trackCycling = true; + } + + @SuppressWarnings("unused") + public SKMotionActivityConfiguration(boolean trackStationary, boolean trackWalking, boolean trackRunning, boolean trackAutomotive, boolean trackCycling) { + super(); + + // Set default values + this.trackStationary = trackStationary; + this.trackWalking = trackWalking; + this.trackRunning = trackRunning; + this.trackAutomotive = trackAutomotive; + this.trackCycling = trackCycling; + } + + @SuppressWarnings("unused") + public SKMotionActivityConfiguration(SKMotionActivityConfiguration configuration) { + super(); + + // Save local configuration + this.trackStationary = configuration.trackStationary; + this.trackWalking = configuration.trackWalking; + this.trackRunning = configuration.trackRunning; + this.trackAutomotive = configuration.trackAutomotive; + this.trackCycling = configuration.trackCycling; + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.MOTION_ACTIVITY); + } + + @SuppressWarnings("unused") + public boolean getTrackStationary() { + return trackStationary; + } + + @SuppressWarnings("unused") + public void setTrackStationary(final boolean trackStationary) { + this.trackStationary = trackStationary; + } + + @SuppressWarnings("unused") + public boolean getTrackWalking() { + return trackWalking; + } + + @SuppressWarnings("unused") + public void setTrackWalking(final boolean trackWalking) { + this.trackWalking = trackWalking; + } + + @SuppressWarnings("unused") + public boolean getTrackRunning() { + return trackRunning; + } + + @SuppressWarnings("unused") + public void setTrackRunning(final boolean trackRunning) { + this.trackRunning = trackRunning; + } + + @SuppressWarnings("unused") + public boolean getTrackAutomotive() { + return trackAutomotive; + } + + @SuppressWarnings("unused") + public void setTrackAutomotive(final boolean trackAutomotive) { + this.trackAutomotive = trackAutomotive; + } + + @SuppressWarnings("unused") + public boolean getTrackCycling() { + return trackCycling; + } + + @SuppressWarnings("unused") + public void setTrackCycling(final boolean trackCycling) { + this.trackCycling = trackCycling; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKNotificationConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKNotificationConfiguration.java new file mode 100644 index 0000000..148af63 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKNotificationConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKNotificationConfiguration extends SKAbstractConfiguration { + + public SKNotificationConfiguration() { + super(); + + // Set default values + } + + @SuppressWarnings("unused") + public SKNotificationConfiguration(SKNotificationConfiguration configuration) { + super(); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.NOTIFICATION); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKRotationConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKRotationConfiguration.java new file mode 100644 index 0000000..944ada7 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKRotationConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKRotationConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKRotationConfiguration() { + super(); + + // Set default values + } + + public SKRotationConfiguration(SKRotationConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.ROTATION); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKScreenStatusConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKScreenStatusConfiguration.java new file mode 100644 index 0000000..f35440b --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKScreenStatusConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKScreenStatusConfiguration extends SKAbstractConfiguration { + + public SKScreenStatusConfiguration() { + super(); + + // Set default values + } + + @SuppressWarnings("unused") + public SKScreenStatusConfiguration(SKScreenStatusConfiguration configuration) { + super(); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.SCREEN_STATUS); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKStepCounterConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKStepCounterConfiguration.java new file mode 100644 index 0000000..8b2b08e --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKStepCounterConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKStepCounterConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKStepCounterConfiguration() { + super(); + + // Set default values + } + + public SKStepCounterConfiguration(SKStepCounterConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.STEP_COUNTER); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKStepDetectorConfiguration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKStepDetectorConfiguration.java new file mode 100644 index 0000000..7df86fd --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/configuration/SKStepDetectorConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.configuration; + +import org.sensingkit.sensingkitlib.SKSensorType; + +public class SKStepDetectorConfiguration extends SKAbstractNativeSensorConfiguration { + + public SKStepDetectorConfiguration() { + super(); + + // Set default values + } + + public SKStepDetectorConfiguration(SKStepDetectorConfiguration configuration) { + super(configuration.samplingRate); + } + + public boolean isValidForSensor(final SKSensorType sensorType) { + return (sensorType == SKSensorType.STEP_DETECTOR); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAbstractData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAbstractData.java index d843a44..d0b7065 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAbstractData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAbstractData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,30 +21,57 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; -public abstract class SKAbstractData implements SKSensorData -{ +import org.sensingkit.sensingkitlib.SKSensorType; + +/* +Abstract class for sensor data + */ +@SuppressWarnings("WeakerAccess") +public abstract class SKAbstractData implements SKSensorData { @SuppressWarnings("unused") - private static final String TAG = "SKAbstractData"; + private static final String TAG = SKAbstractData.class.getSimpleName(); - protected final SKSensorModuleType moduleType; + protected final SKSensorType sensorType; protected final long timestamp; - public SKAbstractData(SKSensorModuleType moduleType, long timestamp) { - this.moduleType = moduleType; + /** + * Initialize the instance + * + * @param sensorType of type SKSensorType + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + */ + public SKAbstractData(final SKSensorType sensorType, final long timestamp) { + this.sensorType = sensorType; this.timestamp = timestamp; } + /** + * Get the sensor data in csv format + * + * @return String in csv format + */ + @NonNull public String toString() { return this.getDataInCSV(); } + /** + * Get the sensor type + * + * @return sensor type + */ @SuppressWarnings("unused") - public SKSensorModuleType getSensorModuleType() { - return moduleType; + public SKSensorType getSensorType() { + return sensorType; } + /** + * Get the timestamp + * + * @return timestamp + */ @SuppressWarnings("unused") public long getTimestamp() { return timestamp; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAccelerometerData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAccelerometerData.java index 49b259b..ca5b364 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAccelerometerData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAccelerometerData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,43 +21,124 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; + +/** + * An instance of SKAccelerometerData encapsulates measurements related to the Accelerometer sensor. + */ public class SKAccelerometerData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKAccelerometerData"; + private static final String TAG = SKAccelerometerData.class.getSimpleName(); - protected final float x; - protected final float y; - protected final float z; + private final float x; + private final float y; + private final float z; - public SKAccelerometerData(long timestamp, float x, float y, float z) { + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and + * midnight, January 1, 1970 UTC) + * @param x X-axis value of the Accelerometer sensor + * @param y Y-axis value of the Accelerometer sensor + * @param z Z-axis value of the Accelerometer sensor + */ - super(SKSensorModuleType.ACCELEROMETER, timestamp); + public SKAccelerometerData(final long timestamp, final float x, final float y, final float z) { + super(SKSensorType.ACCELEROMETER, timestamp); this.x = x; this.y = y; this.z = z; } + /** + * Get the csv header of the Accelerometer sensor data + * + * @return String with a CSV formatted header that describes the data of the Accelerometer + * sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,x,y,z"; + } + + /** + * Get the accelerator measurements in csv format + * + * @return String containing the timestamp and accelerometer measurements in csv format: + * timeIntervalSince1970,x,y,z + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f,%f,%f", this.timestamp, this.x, this.y, this.z); } + /** + * Get the accelerator measurements in JSONObject format + * + * @return JSONObject containing the time stamp and accelerometer measurements in JSONObject + * format: + * sensor type, sensor type in string, timeIntervalSince1970, accelerometer in x,y,z + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("x", this.x); + subJsonObject.put("y", this.y); + subJsonObject.put("z", this.z); + + jsonObject.put("acceleration", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the X-axis accelerator measurement + * + * @return Float containing the X-axis value of the Accelerometer sensor + */ @SuppressWarnings("unused") public float getX() { return this.x; } + /** + * Get the Y-axis accelerator measurement + * + * @return Float containing the y-axis value of the Accelerometer sensor + */ @SuppressWarnings("unused") public float getY() { return this.y; } + /** + * Get the Z-axis accelerator measurement + * + * @return Float containing the z-axis value of the Accelerometer sensor + */ + @SuppressWarnings("unused") public float getZ() { return this.z; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKActivityData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKActivityData.java deleted file mode 100644 index e5c451e..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKActivityData.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.data; - -import com.google.android.gms.location.DetectedActivity; - -import org.sensingkit.sensingkitlib.SKSensorModuleType; - -import java.util.Locale; - -public class SKActivityData extends SKAbstractData { - - @SuppressWarnings("unused") - private static final String TAG = "SKActivityData"; - - protected final int activityType; - protected final int confidence; - - public SKActivityData(long timestamp, int activityType, int confidence) { - - super(SKSensorModuleType.ACTIVITY, timestamp); - - this.activityType = activityType; - this.confidence = confidence; - } - - @Override - public String getDataInCSV() { - return String.format(Locale.US, "%d,%d,%s,%d", this.timestamp, this.activityType, getActivityString(), this.confidence); - } - - @SuppressWarnings("unused") - public int getActivityType() { - return this.activityType; - } - - @SuppressWarnings("unused") - public int getConfidence() { - return this.confidence; - } - - @SuppressWarnings("unused") - public String getActivityString() { - return getNameFromActivityType(this.activityType); - } - - public static String getNameFromActivityType(int activityType) { - - switch (activityType) { - - case DetectedActivity.IN_VEHICLE: - return "in_vehicle"; - - case DetectedActivity.ON_BICYCLE: - return "on_bicycle"; - - case DetectedActivity.ON_FOOT: - return "on_foot"; - - case DetectedActivity.STILL: - return "still"; - - case DetectedActivity.UNKNOWN: - return "unknown"; - - case DetectedActivity.TILTING: - return "tilting"; - - case DetectedActivity.WALKING: - return "walking"; - - case DetectedActivity.RUNNING: - return "running"; - - default: - return "unsupported"; - } - - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAmbientTemperatureData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAmbientTemperatureData.java index 24149dd..53667bf 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAmbientTemperatureData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAmbientTemperatureData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,29 +21,85 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKAmbientTemperatureData encapsulates measurements related to the Ambient Temperature sensor. + */ public class SKAmbientTemperatureData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKAmbientTemperatureData"; - - protected final float temperature; + private static final String TAG = SKAmbientTemperatureData.class.getSimpleName(); - public SKAmbientTemperatureData(long timestamp, float temperature) { + private final float temperature; - super(SKSensorModuleType.AMBIENT_TEMPERATURE, timestamp); + /** + * Initialize Ambient Temperature data instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param temperature In degrees Celsius + */ + public SKAmbientTemperatureData(final long timestamp, final float temperature) { + super(SKSensorType.AMBIENT_TEMPERATURE, timestamp); this.temperature = temperature; } + /** + * Get the csv header of the Ambient Temperature sensor data + * + * @return String with a CSV formatted header that describes the data of the Ambient Temperature sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,temperature"; + } + + /** + * Get the Ambient Temperature sensor data in csv format + * + * @return Ambient Temperature data in csv format: timeIntervalSince1970,temperature + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f", this.timestamp, this.temperature); } + /** + * Get the Ambient Temperature sensor data in JSONObject format + * + * @return JSONObject containing the ambient temperature in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, temperature + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("temperature", this.temperature); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get only the Ambient Temperature + * + * @return Ambient Temperature + */ @SuppressWarnings("unused") public float getTemperature() { return this.temperature; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAudioLevelData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAudioLevelData.java index ed37722..d4e9889 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAudioLevelData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKAudioLevelData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,29 +21,85 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKAudioLevelData encapsulates measurements related to the Audio Level sensor. + */ public class SKAudioLevelData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKAudioLevelData"; - - protected final int level; + private static final String TAG = SKAudioLevelData.class.getSimpleName(); - public SKAudioLevelData(long timestamp, int level) { + private final int level; - super(SKSensorModuleType.AUDIO_LEVEL, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param level - Audio Level + */ + public SKAudioLevelData(final long timestamp, final int level) { + super(SKSensorType.AUDIO_LEVEL, timestamp); this.level = level; } + /** + * Get the csv header of the Audio Level sensor data + * + * @return String with a CSV formatted header that describes the data of the Audio Level sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,level"; + } + + /** + * Get the audio level measurement in csv format + * + * @return String containing the timestamp and audio level measurements in csv format: timeIntervalSince1970,level + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%d", this.timestamp, this.level); } + /** + * Get the audio level measurement in JSONObject format + * + * @return JSONObject containing the timestamp and audio level measurements in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, level + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("audioLevel", this.level); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the audio level only + * + * @return Audio level + */ @SuppressWarnings("unused") public int getLevel() { return this.level; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBarometerData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBarometerData.java new file mode 100644 index 0000000..f2a6dd6 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBarometerData.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +/** + * An instance of SKBarometerData encapsulates measurements related to the Air Pressure sensor. + */ +public class SKBarometerData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKBarometerData.class.getSimpleName(); + + private final float pressure; + + /** + * Initialize the Barometer data instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param pressure Air pressure + */ + public SKBarometerData(final long timestamp, final float pressure) { + super(SKSensorType.BAROMETER, timestamp); + + this.pressure = pressure; + } + + /** + * Get the csv header of the Barometer sensor data + * + * @return String with a CSV formatted header that describes the data of the Barometer sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,pressure"; + } + + /** + * Get the Barometer sensor data in csv format + * + * @return Barometer data in csv format: timeIntervalSince1970,pressure + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%f", this.timestamp, this.pressure); + } + + /** + * Get the Barometer sensor data in JSONObject format + * + * @return JSONObject containing the barometer data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, pressure + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("pressure", this.pressure); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the Air Pressure measurement along + * + * @return Air Pressure measurement + */ + @SuppressWarnings("unused") + public float getPressure() { + return this.pressure; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBatteryData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBatteryData.java deleted file mode 100644 index 152f11f..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBatteryData.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.data; - -import android.os.BatteryManager; - -import org.sensingkit.sensingkitlib.SKSensorModuleType; - -import java.util.Locale; - -import static android.os.BatteryManager.*; - -public class SKBatteryData extends SKAbstractData { - - @SuppressWarnings("unused") - private static final String TAG = "SKBatteryData"; - - protected final int level; - protected final int scale; - protected final int temperature; - protected final int voltage; - protected final int plugged; - protected final int status; - protected final int health; - - public SKBatteryData(long timestamp, int level, int scale, int temperature, int voltage, int plugged, int status, int health) { - - super(SKSensorModuleType.BATTERY, timestamp); - - this.level = level; - this.scale = scale; - this.temperature = temperature; - this.voltage = voltage; - this.plugged = plugged; - this.status = status; - this.health = health; - } - - @Override - public String getDataInCSV() { - return String.format(Locale.US, "%d,%f,%d,%d,%s,%s,%s", this.timestamp, this.getLevelRatio(), this.temperature, this.voltage, getPluggedString(), getBatteryStatusString(), getBatteryHealthString()); - } - - @SuppressWarnings("unused") - public float getLevelRatio() { - - // Calculate the level: level/scale - if (level >= 0 && scale > 0) { - return level / (float)scale; - } - else { - return 0; - } - } - - @SuppressWarnings("unused") - public int getLevel() { - return this.level; - } - - @SuppressWarnings("unused") - public int getScale() { - return this.scale; - } - - @SuppressWarnings("unused") - public int getTemperature() { - return this.temperature; - } - - @SuppressWarnings("unused") - public int getVoltage() { - return this.voltage; - } - - @SuppressWarnings("unused") - public int getPlugged() { - return this.plugged; - } - - @SuppressWarnings("unused") - public int getBatteryStatus() { - return this.status; - } - - @SuppressWarnings("unused") - public int getBatteryHealth() { - return this.health; - } - - @SuppressWarnings("unused") - public String getPluggedString() { - return getPluggedString(this.plugged); - } - - @SuppressWarnings("unused") - public String getBatteryStatusString() { - return getBatteryStatusString(this.status); - } - - @SuppressWarnings("unused") - public String getBatteryHealthString() { - return getBatteryHealthString(this.health); - } - - private static String getPluggedString(int pluggedType) { - - switch (pluggedType) { - - case BATTERY_PLUGGED_USB: - return "usb"; - - case BATTERY_PLUGGED_AC: - return "ac"; - - case BATTERY_PLUGGED_WIRELESS: - return "wireless"; - - default: - return "unknown"; - } - } - - private static String getBatteryStatusString(int status) { - - switch (status) { - - case BatteryManager.BATTERY_STATUS_CHARGING: - return "charging"; - - case BatteryManager.BATTERY_STATUS_DISCHARGING: - return "discharging"; - - case BatteryManager.BATTERY_STATUS_FULL: - return "full"; - - case BatteryManager.BATTERY_STATUS_NOT_CHARGING: - return "not Charging"; - - case BatteryManager.BATTERY_STATUS_UNKNOWN: - return "unknown"; - - default: - return "unsupported"; - } - } - - private String getBatteryHealthString(int health) { - - switch (health) { - - case BatteryManager.BATTERY_HEALTH_COLD: - return "cold"; - - case BatteryManager.BATTERY_HEALTH_DEAD: - return "dead"; - - case BatteryManager.BATTERY_HEALTH_GOOD: - return "good"; - - case BatteryManager.BATTERY_HEALTH_OVERHEAT: - return "over heat"; - - case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: - return "over voltage"; - - case BatteryManager.BATTERY_HEALTH_UNKNOWN: - return "unknown"; - - case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: - return "failure"; - - default: - return "unsupported"; - } - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBatteryStatusData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBatteryStatusData.java new file mode 100644 index 0000000..581dd71 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBatteryStatusData.java @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import android.annotation.TargetApi; +import android.os.BatteryManager; +import android.os.Build; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +/** + * An instance of SKBatteryStatusData encapsulates Battery properties + */ +@SuppressWarnings("WeakerAccess") +public class SKBatteryStatusData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKBatteryStatusData.class.getSimpleName(); + + public enum SKBatteryPlugged { + + /** + * TODO + */ + UNPLUGGED("Unplugged", 0), + + /** + * TODO + */ + USB("USB", BatteryManager.BATTERY_PLUGGED_USB), + + /** + * TODO + */ + AC("AC", BatteryManager.BATTERY_PLUGGED_AC), + + /** + * TODO + */ + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) + WIRELESS("Wireless", BatteryManager.BATTERY_PLUGGED_WIRELESS); + + private final @NonNull String batteryPlugged; + private final int batteryPluggedCode; + + SKBatteryPlugged(final @NonNull String batteryPlugged, final int batteryPluggedCode) { + this.batteryPlugged = batteryPlugged; + this.batteryPluggedCode = batteryPluggedCode; + } + + @SuppressWarnings("WeakerAccess") + public static SKBatteryPlugged valueOf(final int batteryPluggedCode) { + + switch (batteryPluggedCode) { + case 0: + return UNPLUGGED; + + case BatteryManager.BATTERY_PLUGGED_USB: + return USB; + + case BatteryManager.BATTERY_PLUGGED_AC: + return AC; + + case BatteryManager.BATTERY_PLUGGED_WIRELESS: + return WIRELESS; + + default: + throw new RuntimeException("Unsupported SKBatteryPlugged with code: " + batteryPluggedCode); + } + } + + @SuppressWarnings("unused") + public @NonNull String getBatteryPlugged() { + return this.batteryPlugged; + } + + @SuppressWarnings("unused") + public int getBatteryPluggedCode() { + return this.batteryPluggedCode; + } + + @NonNull + @Override + public String toString() { + return this.getBatteryPlugged(); + } + } + + public enum SKBatteryStatus { + + /** + * TODO + */ + CHARGING("Charging", BatteryManager.BATTERY_STATUS_CHARGING), + + /** + * TODO + */ + DISCHARGING("Discharging", BatteryManager.BATTERY_STATUS_DISCHARGING), + + /** + * TODO + */ + FULL("Full", BatteryManager.BATTERY_STATUS_FULL), + + /** + * TODO + */ + NOT_CHARGING("Not Charging", BatteryManager.BATTERY_STATUS_NOT_CHARGING), + + /** + * TODO + */ + UNKNOWN("Unknown", BatteryManager.BATTERY_STATUS_UNKNOWN); + + private final @NonNull String batteryStatus; + private final int batteryStatusCode; + + SKBatteryStatus(final @NonNull String batteryStatus, final int batteryStatusCode) { + this.batteryStatus = batteryStatus; + this.batteryStatusCode = batteryStatusCode; + } + + @SuppressWarnings("WeakerAccess") + public static SKBatteryStatus valueOf(final int batteryStatusCode) { + + switch (batteryStatusCode) { + + case BatteryManager.BATTERY_STATUS_CHARGING: + return CHARGING; + + case BatteryManager.BATTERY_STATUS_DISCHARGING: + return DISCHARGING; + + case BatteryManager.BATTERY_STATUS_FULL: + return FULL; + + case BatteryManager.BATTERY_STATUS_NOT_CHARGING: + return NOT_CHARGING; + + case BatteryManager.BATTERY_STATUS_UNKNOWN: + return UNKNOWN; + + default: + throw new RuntimeException("Unsupported SKBatteryStatus with code: " + batteryStatusCode); + } + } + + @SuppressWarnings("unused") + public @NonNull String getBatteryStatus() { + return this.batteryStatus; + } + + @SuppressWarnings("unused") + public int getBatteryStatusCode() { + return this.batteryStatusCode; + } + + @NonNull + @Override + public String toString() { + return this.getBatteryStatus(); + } + } + + public enum SKBatteryHealth { + + /** + * TODO + */ + COLD("Cold", BatteryManager.BATTERY_HEALTH_COLD), + + /** + * TODO + */ + DEAD("Dead", BatteryManager.BATTERY_HEALTH_DEAD), + + /** + * TODO + */ + GOOD("Good", BatteryManager.BATTERY_HEALTH_GOOD), + + /** + * TODO + */ + OVERHEAT("Overheat", BatteryManager.BATTERY_HEALTH_OVERHEAT), + + /** + * TODO + */ + OVER_VOLTAGE("Over Voltage", BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE), + + /** + * TODO + */ + UNKNOWN("Unknown", BatteryManager.BATTERY_HEALTH_UNKNOWN), + + /** + * TODO + */ + UNSPECIFIED_FAILURE("Unspecified Failure", BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE); + + private final @NonNull String batteryHealth; + private final int batteryHealthCode; + + SKBatteryHealth(final @NonNull String batteryHealth, final int batteryHealthCode) { + this.batteryHealth = batteryHealth; + this.batteryHealthCode = batteryHealthCode; + } + + @SuppressWarnings("WeakerAccess") + public static SKBatteryHealth valueOf(final int batteryHealthCode) { + + switch (batteryHealthCode) { + + case BatteryManager.BATTERY_HEALTH_COLD: + return COLD; + + case BatteryManager.BATTERY_HEALTH_DEAD: + return DEAD; + + case BatteryManager.BATTERY_HEALTH_GOOD: + return GOOD; + + case BatteryManager.BATTERY_HEALTH_OVERHEAT: + return OVERHEAT; + + case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: + return OVER_VOLTAGE; + + case BatteryManager.BATTERY_HEALTH_UNKNOWN: + return UNKNOWN; + + case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: + return UNSPECIFIED_FAILURE; + + case 9: + return UNKNOWN; // TODO: Check what this 9 constant is. + + default: + throw new RuntimeException("Unsupported SKBatteryHealth with code: " + batteryHealthCode); + } + } + + @SuppressWarnings("unused") + public @NonNull String getBatteryHealth() { + return this.batteryHealth; + } + + @SuppressWarnings("unused") + public int getBatteryHealthCode() { + return this.batteryHealthCode; + } + + @NonNull + @Override + public String toString() { + return this.getBatteryHealth(); + } + } + + private final int level; + private final int scale; + private final int temperature; + private final int voltage; + private final SKBatteryPlugged plugged; + private final SKBatteryStatus status; + private final SKBatteryHealth health; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param level Indicates the current battery charge level. Value ranges from 0 to maximum battery level + * @param scale Maximum battery level + * @param temperature Current battery temperature + * @param voltage Current battery voltage + * @param pluggedCode Values are: 0 - on battery, BATTERY_PLUGGED_AC, BATTERY_PLUGGED_USB, BATTERY_PLUGGED_WIRELESS + * @param statusCode Values are: BATTERY_STATUS_CHARGING, BATTERY_STATUS_DISCHARGING, BATTERY_STATUS_FULL, + * BATTERY_STATUS_NOT_CHARGING, BATTERY_STATUS_UNKNOWN + * @param healthCode Values are: BATTERY_HEALTH_COLD, BATTERY_HEALTH_DEAD, BATTERY_HEALTH_GOOD, BATTERY_HEALTH_OVERHEAT, + * BATTERY_HEALTH_OVER_VOLTAGE, BATTERY_HEALTH_UNKNOWN + */ + public SKBatteryStatusData(final long timestamp, final int level, final int scale, final int temperature, final int voltage, final int pluggedCode, final int statusCode, final int healthCode) { + super(SKSensorType.BATTERY_STATUS, timestamp); + + this.level = level; + this.scale = scale; + this.temperature = temperature; + this.voltage = voltage; + this.plugged = SKBatteryPlugged.valueOf(pluggedCode); + this.status = SKBatteryStatus.valueOf(statusCode); + this.health = SKBatteryHealth.valueOf(healthCode); + } + + /** + * Get the csv header of the Battery sensor data + * + * @return String with a CSV formatted header that describes the data of the Battery sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + public static String csvHeader() { + return "timeIntervalSince1970,charge,temperature,voltage,plugged,status,health"; + } + + /** + * Get the battery properties in csv format + * + * @return String containing the battery properties in csv format: timeIntervalSince1970,charge,temperature, + * voltage, + * plugged string ("usb", "ac", "wireless" or "unknown"), + * status string ("charging", "discharging", "full", "not charging", "unknown" or "unsupported"), + * health string ("cold", "dead", "good", "over heat", "over voltage", "unknown", "failure" or "unsupported") + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%f,%d,%d,%s,%s,%s", this.timestamp, this.getLevelRatio(), this.temperature, this.voltage, + this.plugged.getBatteryPlugged(), this.status.getBatteryStatus(), this.health.getBatteryHealth()); + } + + /** + * Get the battery properties in JSONObject format + * + * @return JSONObject containing the battery properties in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970,charge,temperature,voltage, + * plugged string ("usb", "ac", "wireless" or "unknown"), + * status string ("charging", "discharging", "full", "not charging", "unknown" or "unsupported"), + * health string ("cold", "dead", "good", "over heat", "over voltage", "unknown", "failure" or "unsupported") + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("charge", this.getLevelRatio()); + subJsonObject.put("temperature", this.temperature); + subJsonObject.put("voltage", this.voltage); + subJsonObject.put("plugged", this.plugged.getBatteryPlugged()); + subJsonObject.put("status", this.status.getBatteryStatus()); + subJsonObject.put("health", this.health.getBatteryHealth()); + + jsonObject.put("battery", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the battery charge + * + * @return charge (level/scale) + */ + @SuppressWarnings("unused") + public float getLevelRatio() { + + // Calculate the level: level/scale + if (level >= 0 && scale > 0) { + return level / (float) scale; + } else { + return 0; + } + } + + /** + * Get the battery level + * + * @return level + */ + @SuppressWarnings("unused") + public int getLevel() { + return this.level; + } + + /** + * Get the battery scale + * + * @return scale + */ + @SuppressWarnings("unused") + public int getScale() { + return this.scale; + } + + /** + * Get the battery temperature + * + * @return temperature + */ + @SuppressWarnings("unused") + public int getTemperature() { + return this.temperature; + } + + /** + * Get the battery voltage + * + * @return voltage + */ + @SuppressWarnings("unused") + public int getVoltage() { + return this.voltage; + } + + /** + * Get the battery plugged state + * + * @return plugged + */ + @SuppressWarnings("unused") + public SKBatteryPlugged getBatteryPlugged() { + return this.plugged; + } + + /** + * Get the battery status + * + * @return status + */ + @SuppressWarnings("unused") + public SKBatteryStatus getBatteryStatus() { + return this.status; + } + + /** + * Get the battery health + * + * @return health + */ + @SuppressWarnings("unused") + public SKBatteryHealth getBatteryHealth() { + return this.health; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBeaconProximityCollectionData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBeaconProximityCollectionData.java new file mode 100644 index 0000000..6f76f58 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBeaconProximityCollectionData.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.ArrayList; +import java.util.Locale; + +/** + * An instance of SKBeaconProximityCollectionData encapsulates measurements related to all the Beacon devices. + */ +public class SKBeaconProximityCollectionData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKBeaconProximityCollectionData.class.getSimpleName(); + + private final ArrayList mDevices; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param devices One SKBeaconProximityData object for each Beacon device + */ + public SKBeaconProximityCollectionData(final long timestamp, final @NonNull ArrayList devices) { + super(SKSensorType.BEACON_PROXIMITY, timestamp); + + this.mDevices = devices; + } + + /** + * Get the csv header of the Beacon Proximity sensor data + * + * @return String with a CSV formatted header that describes the data of the Beacon Proximity sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return SKBeaconProximityData.csvHeader(); + } + + /** + * Get the data for all Beacon devices in CSV format + * + * @return String formatted as follows: timeIntervalSince1970,device1 data, device2 data,,, + */ + @Override + @NonNull + public String getDataInCSV() { + + // Calculate capacity and init StringBuilder + int capacity = 10 * mDevices.size(); + StringBuilder stringBuilder = new StringBuilder(capacity); + + // Add deviceData + for (SKBeaconProximityData deviceData : mDevices) { + + stringBuilder.append(String.format(Locale.US, "%s\n", deviceData.getDataInCSV())); + } + + // Delete last \n + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + + // Return in String + return stringBuilder.toString(); + } + + + /** + * Get the data for all Beacon devices in JSONObject format + * + * @return JSONObject formatted as follows: device1 data, device, data,,, + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + // Add deviceData + int i = 1; + for (SKBeaconProximityData deviceData : mDevices) { + jsonObject.put("beaconDeviceNo" + i++, deviceData.getDataInJSON()); + } + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + + /** + * Get Beacon device data + * + * @return an ArrayList containing an SKBeaconProximityData object for each Beacon device + */ + @SuppressWarnings("unused") + public ArrayList getDevices() { + return this.mDevices; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBeaconProximityData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBeaconProximityData.java new file mode 100644 index 0000000..c2fa4aa --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBeaconProximityData.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * Ming-Jiun Huang, ud2601@gmail.com + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import org.altbeacon.beacon.Beacon; +import org.altbeacon.beacon.Identifier; +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +@SuppressWarnings("WeakerAccess") +public class SKBeaconProximityData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKBeaconProximityData.class.getSimpleName(); + + private final Beacon mBeacon; + + public SKBeaconProximityData(final long timestamp, final @NonNull Beacon beacon) { + super(SKSensorType.BEACON_PROXIMITY, timestamp); + + this.mBeacon = beacon; + } + + /** + * Get the csv header of the Beacon Proximity sensor data + * + * @return String with a CSV formatted header that describes the data of the Beacon Proximity sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,beaconType,manufacturer,id1,id2,id3,rssi,txPower,distance"; + } + + /** + * Get the Beacon Proximity sensor data in csv format + * + * @return String containing the Beacon Proximity sensor data in csv format: + * sensor type, sensor type in string, timeIntervalSince1970, beaconType, manufacturer, id1,id2,id3,rssi,txPower,distance + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%d,%d,%s,%d,%d,%d,%d,%f", + this.timestamp, this.getBeaconTypeCode(), this.getManufacturer(), + this.getId1().toString(), this.getId2().toInt(), this.getId3().toInt(), + this.getRssi(), this.getTxPower(), this.getDistance()); + } + + /** + * Get the Beacon Proximity sensor data in JSONObject format + * + * @return JSONObject containing the Beacon Proximity sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, beaconType, manufacturer, id1,id2,id3,rssi,txPower,distance + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("beaconType", this.getBeaconTypeCode()); + subJsonObject.put("manufacturer", this.getManufacturer()); + subJsonObject.put("id1", this.getId1().toString()); + subJsonObject.put("id2", this.getId2().toInt()); + subJsonObject.put("id3", this.getId3().toInt()); + subJsonObject.put("rssi", this.getRssi()); + subJsonObject.put("txPower", this.getTxPower()); + subJsonObject.put("distance", this.getDistance()); + + jsonObject.put("beaconProximity", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + @SuppressWarnings("unused") + public int getBeaconTypeCode() { + return mBeacon.getBeaconTypeCode(); + } + + @SuppressWarnings("unused") + public int getManufacturer() { + return mBeacon.getManufacturer(); + } + + @SuppressWarnings("unused") + public Identifier getId1() { + return mBeacon.getId1(); + } + + @SuppressWarnings("unused") + public Identifier getId2() { + return mBeacon.getId2(); + } + + @SuppressWarnings("unused") + public Identifier getId3() { + return mBeacon.getId3(); + } + + @SuppressWarnings("unused") + public int getRssi() { + return mBeacon.getRssi(); + } + + @SuppressWarnings("unused") + public int getTxPower() { + return mBeacon.getTxPower(); + } + + @SuppressWarnings("unused") + public String getBluetoothAddress() { + return mBeacon.getBluetoothAddress(); + } + + @SuppressWarnings("unused") + public String getBluetoothName() { + return mBeacon.getBluetoothName(); + } + + @SuppressWarnings("unused") + public double getDistance() { + return mBeacon.getDistance(); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothCollectionData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothCollectionData.java new file mode 100644 index 0000000..f98edb7 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothCollectionData.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.ArrayList; +import java.util.Locale; + +/** + * An instance of SKBluetoothCollectionData encapsulates measurements related to all Bluetooth devices. + */ +public class SKBluetoothCollectionData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKBluetoothCollectionData.class.getSimpleName(); + + private final ArrayList mDevices; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param devices One BluetoothData object for each Bluetooth device + */ + public SKBluetoothCollectionData(final long timestamp, final @NonNull ArrayList devices) { + super(SKSensorType.BLUETOOTH, timestamp); + + this.mDevices = devices; + } + + /** + * Get the csv header of the Bluetooth sensor data + * + * @return String with a CSV formatted header that describes the data of the Bluetooth sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return SKBluetoothData.csvHeader(); + } + + /** + * Get the data for all Bluetooth devices in CSV format + * + * @return String formatted as follows: timestamp,device1 data, device2 data,,, + */ + @Override + @NonNull + public String getDataInCSV() { + + // Calculate capacity and init StringBuilder + int capacity = 10 * mDevices.size(); + StringBuilder stringBuilder = new StringBuilder(capacity); + + // Add deviceData + for (SKBluetoothData deviceData : mDevices) { + + stringBuilder.append(String.format(Locale.US, "%s\n", deviceData.getDataInCSV())); + } + + // Delete last \n + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + + // Return in String + return stringBuilder.toString(); + } + + /** + * Get the data for all Bluetooth devices in JSONObject format + * + * @return JSONObject formatted as follows: device1 data, device2 data,,, + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + + // Add deviceData + int i = 1; + for (SKBluetoothData deviceData : mDevices) { + jsonObject.put("bluetoothDeviceNo" + i++, deviceData.getDataInJSON()); + } + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + + /** + * Get Bluetooth device data + * + * @return an ArrayList containing an SKBluetoothDeviceData object for each Bluetooth device + */ + @SuppressWarnings("unused") + public ArrayList getDevices() { + return this.mDevices; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothData.java index be3938f..b4cd91e 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,47 +21,123 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; -import java.util.ArrayList; import java.util.Locale; +/** + * An instance of SKBluetoothData encapsulates measurements related to one Bluetooth device. + */ public class SKBluetoothData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKBluetoothData"; - - private final ArrayList mBluetoothDevices; - - public SKBluetoothData(long timestamp, ArrayList bluetoothDevices) { - - super(SKSensorModuleType.BLUETOOTH, timestamp); + private static final String TAG = SKBluetoothData.class.getSimpleName(); + + private final String name; + private final String address; + private final int rssi; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param name Device name + * @param address Device Address + * @param rssi Device RSSI + */ + public SKBluetoothData(final long timestamp, final @NonNull String name, final @NonNull String address, final int rssi) { + super(SKSensorType.BLUETOOTH, timestamp); + + this.name = name; + this.address = address; + this.rssi = rssi; + } - this.mBluetoothDevices = bluetoothDevices; + /** + * Get the csv header of the Bluetooth sensor data + * + * @return String with a CSV formatted header that describes the data of the Bluetooth sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,name,address,rssi"; } + /** + * Get Bluetooth data in CSV format + * + * @return String formatted as a CSV, containing: timeIntervalSince1970,name,address,rssi + */ @Override + @NonNull public String getDataInCSV() { + return String.format(Locale.US, "%d,%s,%s,%d", this.timestamp, this.name, this.address, this.rssi); + } - // Calculate capacity and init StringBuilder - int capacity = 10 * mBluetoothDevices.size(); - StringBuilder stringBuilder = new StringBuilder(capacity); - - // Add deviceData - for (SKBluetoothDeviceData deviceData : mBluetoothDevices) { - stringBuilder.append(String.format(Locale.US, "%d,%s\n", this.timestamp, deviceData.getDataInCSV())); + /** + * Get the Bluetooth data in JSONObject format + * + * @return JSONObject containing the bluetooth data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, name,address,rssi + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("name", this.name); + subJsonObject.put("address", this.address); + subJsonObject.put("rssi", this.rssi); + + jsonObject.put("bluetooth", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); } + return jsonObject; + } - // Delete last \n - stringBuilder.deleteCharAt(stringBuilder.length()-1); - // Return in String - return stringBuilder.toString(); + /** + * Get the Bluetooth device name + * + * @return Bluetooth device name + */ + @SuppressWarnings("unused") + @NonNull + public String getName() { + return this.name; + } + + /** + * Get the Bluetooth device address + * + * @return Bluetooth device address + */ + @SuppressWarnings("unused") + @NonNull + public String getAddress() { + return this.address; } + /** + * Get the Bluetooth device RSSI + * + * @return Bluetooth device RSSI + */ @SuppressWarnings("unused") - public ArrayList getBluetoothDevices() { - return this.mBluetoothDevices; + public int getRssi() { + return this.rssi; } } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothDeviceData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothDeviceData.java deleted file mode 100644 index b9c7e64..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKBluetoothDeviceData.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.data; - -import org.sensingkit.sensingkitlib.SKSensorModuleType; - -import java.util.Locale; - -public class SKBluetoothDeviceData extends SKAbstractData { - - @SuppressWarnings("unused") - private static final String TAG = "SKBluetoothDeviceData"; - - protected final String name; - protected final String address; - protected final int rssi; - - public SKBluetoothDeviceData(long timestamp, String name, String address, int rssi) { - - super(SKSensorModuleType.BLUETOOTH, timestamp); - - this.name = name; - this.address = address; - this.rssi = rssi; - } - - @Override - public String getDataInCSV() { - return String.format(Locale.US, "%d,%s,%s,%d", this.timestamp, this.name, this.address, this.rssi); - } - - @SuppressWarnings("unused") - public String getName() { - return this.name; - } - - @SuppressWarnings("unused") - public String getAddress() { - return this.address; - } - - @SuppressWarnings("unused") - public int getRssi() { - return this.rssi; - } -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGravityData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGravityData.java index a589256..d5711da 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGravityData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGravityData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,43 +21,117 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKGravityData encapsulates measurements related to the Gravity sensor. + */ public class SKGravityData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKGravityData"; - - protected final float x; - protected final float y; - protected final float z; + private static final String TAG = SKGravityData.class.getSimpleName(); - public SKGravityData(long timestamp, float x, float y, float z) { + private final float x; + private final float y; + private final float z; - super(SKSensorModuleType.GRAVITY, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param x X-axis value + * @param y Y-axis value + * @param z Z-axis value + */ + public SKGravityData(final long timestamp, final float x, final float y, final float z) { + super(SKSensorType.GRAVITY, timestamp); this.x = x; this.y = y; this.z = z; } + /** + * Get the csv header of the Gravity sensor data + * + * @return String with a CSV formatted header that describes the data of the Gravity sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,x,y,z"; + } + + /** + * Get the Gravity sensor data in csv format + * + * @return String in csv format: timeIntervalSince1970, x-axis, y-axis, z-axis + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f,%f,%f", this.timestamp, this.x, this.y, this.z); } + /** + * Get the Gravity sensor data in JSONObject format + * + * @return JSONObject containing the Gravity sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, x-axis, y-axis, z-axis + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("x", this.x); + subJsonObject.put("y", this.y); + subJsonObject.put("z", this.z); + + jsonObject.put("gravity", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the Gravity sensor X-axis value + * + * @return X-axis value + */ @SuppressWarnings("unused") public float getX() { return this.x; } + /** + * Get the Gravity sensor Y-axis value + * + * @return Y-axis value + */ @SuppressWarnings("unused") public float getY() { return this.y; } + /** + * Get the Gravity sensor Z-axis value + * + * @return Z-axis value + */ @SuppressWarnings("unused") public float getZ() { return this.z; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGyroscopeData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGyroscopeData.java index b798680..81b2245 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGyroscopeData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKGyroscopeData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,43 +21,117 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKGyroscopeData encapsulates measurements related to the Gyroscope sensor. + */ public class SKGyroscopeData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKGyroscopeData"; - - protected final float x; - protected final float y; - protected final float z; + private static final String TAG = SKGyroscopeData.class.getSimpleName(); - public SKGyroscopeData(long timestamp, float x, float y, float z) { + private final float x; + private final float y; + private final float z; - super(SKSensorModuleType.GYROSCOPE, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param x X-axis of the Gyroscope data + * @param y Y-axis of the Gyroscope data + * @param z Z-axis of the Gyroscope data + */ + public SKGyroscopeData(final long timestamp, final float x, final float y, final float z) { + super(SKSensorType.GYROSCOPE, timestamp); this.x = x; this.y = y; this.z = z; } + /** + * Get the csv header of the Gyroscope sensor data + * + * @return String with a CSV formatted header that describes the data of the Gyroscope sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,x,y,z"; + } + + /** + * Get the Gyroscope data in csv format + * + * @return String in csv format: timeIntervalSince1970, X-axis, Y-axis, Z-axis + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f,%f,%f", this.timestamp, this.x, this.y, this.z); } + /** + * Get the Gyroscope sensor data in JSONObject format + * + * @return JSONObject containing the Gyroscope sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, x-axis, y-axis, z-axis + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("x", this.x); + subJsonObject.put("y", this.y); + subJsonObject.put("z", this.z); + + jsonObject.put("gyroscope", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the X-axis of the Gyroscope sensor data + * + * @return X-axis value + */ @SuppressWarnings("unused") public float getX() { return this.x; } + /** + * Get the Y-axis of the Gyroscope sensor data + * + * @return Y-axis value + */ @SuppressWarnings("unused") public float getY() { return this.y; } + /** + * Get the Z-axis of the Gyroscope sensor data + * + * @return Z-axis value + */ @SuppressWarnings("unused") public float getZ() { return this.z; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKHumidityData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKHumidityData.java new file mode 100644 index 0000000..d3ba04c --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKHumidityData.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +/** + * An instance of SKHumidityData encapsulates measurements related to the Humidity sensor. + */ +public class SKHumidityData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKHumidityData.class.getSimpleName(); + + private final float humidity; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param humidity Humidity measurement + */ + public SKHumidityData(final long timestamp, final float humidity) { + + super(SKSensorType.HUMIDITY, timestamp); + + this.humidity = humidity; + } + + /** + * Get the csv header of the Humidity sensor data + * + * @return String with a CSV formatted header that describes the data of the Humidity sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,humidity"; + } + + /** + * Get humidity sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, humidity + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%f", this.timestamp, this.humidity); + } + + /** + * Get humidity sensor data in JSONObject format + * + * @return JSONObject containing the humidity sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, humidity + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("humidity", this.humidity); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + @SuppressWarnings("unused") + public float getHumidity() { + return this.humidity; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLightData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLightData.java index 5a69bed..1f05440 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLightData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLightData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,29 +21,85 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKLightData encapsulates measurements related to the Light sensor. + */ public class SKLightData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKLightData"; - - protected final float light; + private static final String TAG = SKLightData.class.getSimpleName(); - public SKLightData(long timestamp, float light) { + private final float light; - super(SKSensorModuleType.LIGHT, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param light Ambient light in lux + */ + public SKLightData(final long timestamp, final float light) { + super(SKSensorType.LIGHT, timestamp); this.light = light; } + /** + * Get the csv header of the Light sensor data + * + * @return String with a CSV formatted header that describes the data of the Light sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,lux"; + } + + /** + * Get light sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, ambient light in lux + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f", this.timestamp, this.light); } + /** + * Get light sensor data in JSONObject format + * + * @return JSONObject containing the light sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, light + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("light", this.light); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get light sensor data + * + * @return Ambient light in lux + */ @SuppressWarnings("unused") public float getLight() { return this.light; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLinearAccelerationData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLinearAccelerationData.java index c6280c4..018cba2 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLinearAccelerationData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLinearAccelerationData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,43 +21,118 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKLinearAccelerationData encapsulates measurements related to the Linear Acceleration sensor. + * Measures the acceleration force in mass/seconds**2, excluding the force of gravity + */ public class SKLinearAccelerationData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKLinearAccelerationData"; - - protected final float x; - protected final float y; - protected final float z; + private static final String TAG = SKLinearAccelerationData.class.getSimpleName(); - public SKLinearAccelerationData(long timestamp, float x, float y, float z) { + private final float x; + private final float y; + private final float z; - super(SKSensorModuleType.LINEAR_ACCELERATION, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param x Force in X direction + * @param y Force in Y direction + * @param z Force in Z direction + */ + public SKLinearAccelerationData(final long timestamp, final float x, final float y, final float z) { + super(SKSensorType.LINEAR_ACCELERATION, timestamp); this.x = x; this.y = y; this.z = z; } + /** + * Get the csv header of the Linear Acceleration sensor data + * + * @return String with a CSV formatted header that describes the data of the Linear Acceleration sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,x,y,z"; + } + + /** + * Get Linear Acceleration sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, x force, y force, z force + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f,%f,%f", this.timestamp, this.x, this.y, this.z); } + /** + * Get the Linear Acceleration sensor data in JSONObject format + * + * @return JSONObject containing the Linear Acceleration sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, x-axis, y-axis, z-axis + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("x", this.x); + subJsonObject.put("y", this.y); + subJsonObject.put("z", this.z); + + jsonObject.put("linearAcceleration", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get Linear Acceleration force in X direction + * + * @return force in X direction + */ @SuppressWarnings("unused") public float getX() { return this.x; } + /** + * Get Linear Acceleration force in Y direction + * + * @return force in Y direction + */ @SuppressWarnings("unused") public float getY() { return this.y; } + /** + * Get Linear Acceleration force in Z direction + * + * @return force in Z direction + */ @SuppressWarnings("unused") public float getZ() { return this.z; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLocationData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLocationData.java index 9772596..0525c5e 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLocationData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKLocationData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -22,34 +22,138 @@ package org.sensingkit.sensingkitlib.data; import android.location.Location; +import androidx.annotation.NonNull; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKLocationData encapsulates measurements related to the Location sensor. + */ public class SKLocationData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKLocationData"; - - protected final Location location; + private static final String TAG = SKLocationData.class.getSimpleName(); - public SKLocationData(long timestamp, Location location) { + private final Location location; - super(SKSensorModuleType.LOCATION, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param location Location object + */ + public SKLocationData(final long timestamp, final @NonNull Location location) { + super(SKSensorType.LOCATION, timestamp); this.location = location; } + /** + * Get the csv header of the Location sensor data + * + * @return String with a CSV formatted header that describes the data of the Location sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,latitude,longitude,altitude,accuracy"; + } + + /** + * Get location sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, latitude, longitude, altitude, accuracy + */ @Override + @NonNull public String getDataInCSV() { - return String.format(Locale.US, "%d,%s", this.timestamp, this.location); + return String.format(Locale.US, "%d,%f,%f,%f,%f", this.timestamp, + this.location.getLatitude(), this.location.getLongitude(), this.location.getAltitude(), + this.location.getAccuracy()); } + /** + * Get the location sensor data in JSONObject format + * + * @return JSONObject containing the location sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, latitude, longitude, altitude, accuracy + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("latitude", this.location.getLatitude()); + subJsonObject.put("longitude", this.location.getLongitude()); + subJsonObject.put("altitude", this.location.getAltitude()); + subJsonObject.put("accuracy", this.location.getAccuracy()); + + jsonObject.put("location", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get Location object + * + * @return Location object + */ @SuppressWarnings("unused") public Location getLocation() { return location; } + /** + * Get Latitude + * + * @return Latitude + */ + @SuppressWarnings("unused") + public double getLatitude() { + return location.getLatitude(); + } + + /** + * Get Longitude + * + * @return Longitude + */ + @SuppressWarnings("unused") + public double getLongitude() { + return location.getLongitude(); + } + + /** + * Get Altitude + * + * @return Altitude + */ + @SuppressWarnings("unused") + public double getAltitude() { + return location.getAltitude(); + } + + /** + * Get Accuracy + * + * @return Accuracy + */ + @SuppressWarnings("unused") + public float getAccuracy() { + return location.getAccuracy(); + } + } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMagnetometerData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMagnetometerData.java index 0b109bc..55dbcab 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMagnetometerData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMagnetometerData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,43 +21,121 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; + +/** + * An instance of SKMagnetometerData encapsulates measurements related to the Magnetometer sensor. + * Measures the magnetic force in micro-Tesla + */ + public class SKMagnetometerData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKMagnetometerData"; + private static final String TAG = SKMagnetometerData.class.getSimpleName(); - protected final float x; - protected final float y; - protected final float z; + private final float x; + private final float y; + private final float z; - public SKMagnetometerData(long timestamp, float x, float y, float z) { - - super(SKSensorModuleType.MAGNETOMETER, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param x Force in X-direction + * @param y Force in Y-direction + * @param z Force in Z-direction + */ + public SKMagnetometerData(final long timestamp, final float x, final float y, final float z) { + super(SKSensorType.MAGNETOMETER, timestamp); this.x = x; this.y = y; this.z = z; } + /** + * Get the csv header of the Magnetometer sensor data + * + * @return String with a CSV formatted header that describes the data of the Magnetometer sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,x,y,z"; + } + + /** + * Get Magnetometer sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, x force, y force, z force + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f,%f,%f", this.timestamp, this.x, this.y, this.z); } + + /** + * Get the Magnetometer sensor data in JSONObject format + * + * @return JSONObject containing the Magnetometer sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, x force, y force, z force + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("x", this.x); + subJsonObject.put("y", this.y); + subJsonObject.put("z", this.z); + + jsonObject.put("magnetometer", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get Magnetometer force in X direction + * + * @return force in X direction + */ @SuppressWarnings("unused") public float getX() { return this.x; } + /** + * Get Magnetometer force in Y direction + * + * @return force in Y direction + */ @SuppressWarnings("unused") public float getY() { return this.y; } + /** + * Get Magnetometer force in Z direction + * + * @return force in Z direction + */ @SuppressWarnings("unused") public float getZ() { return this.z; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMicrophoneData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMicrophoneData.java new file mode 100644 index 0000000..4079205 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMicrophoneData.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +/** + * An instance of SKMicrophoneData encapsulates measurements related to the Microphone sensor. + */ +public class SKMicrophoneData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKMicrophoneData.class.getSimpleName(); + + private final String state; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param state Microphone sensor status (Start, Stop) + */ + public SKMicrophoneData(final long timestamp, final @NonNull String state) { + super(SKSensorType.STEP_DETECTOR, timestamp); + + this.state = state; + } + + /** + * Get the csv header of the Step Counter sensor data + * + * @return String with a CSV formatted header that describes the data of the Step Counter sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,state"; + } + + /** + * Get Step Detector sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970 + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%s", this.timestamp, this.state); + } + + /** + * Get Step Detector sensor data in JSONObject format + * + * @return JSONObject containing Step Detector sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, state + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("state", this.state); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + + /** + * Get Microphone Status + * + * @return String with the status of the Microphone sensor + */ + @SuppressWarnings("unused") + public String getState() { + return this.state; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMotionActivityData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMotionActivityData.java new file mode 100644 index 0000000..4552638 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKMotionActivityData.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + +import androidx.annotation.NonNull; + +import com.google.android.gms.location.ActivityTransition; +import com.google.android.gms.location.DetectedActivity; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +/** + * An instance of SKMotionActivityData encapsulates measurements related to the Motion Activity sensor. + * Activity is classified as Stationary, Walking, Running, Automotive or Cycling. + */ +public class SKMotionActivityData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKMotionActivityData.class.getSimpleName(); + + @SuppressWarnings("WeakerAccess") + public enum SKActivityType { + + /** + * TODO + */ + STATIONARY("Still", DetectedActivity.STILL), + + /** + * TODO + */ + WALKING("Walking", DetectedActivity.WALKING), + + /** + * TODO + */ + RUNNING("Running", DetectedActivity.RUNNING), + + /** + * TODO + */ + AUTOMOTIVE("Automotive", DetectedActivity.IN_VEHICLE), + + /** + * TODO + */ + CYCLING("Cycling", DetectedActivity.ON_BICYCLE); + + private final @NonNull String activityType; + private final int activityTypeCode; + + SKActivityType(final @NonNull String activityType, final int activityTypeCode) { + this.activityType = activityType; + this.activityTypeCode = activityTypeCode; + } + + public static SKActivityType valueOf(final int activityTypeCode) { + + switch (activityTypeCode) { + + case DetectedActivity.STILL: + return STATIONARY; + + case DetectedActivity.WALKING: + return WALKING; + + case DetectedActivity.RUNNING: + return RUNNING; + + case DetectedActivity.IN_VEHICLE: + return AUTOMOTIVE; + + case DetectedActivity.ON_BICYCLE: + return CYCLING; + + default: + throw new RuntimeException("Unsupported SKActivityType with code: " + activityTypeCode); + } + } + + @SuppressWarnings("unused") + public @NonNull String getActivityType() { + return this.activityType; + } + + @SuppressWarnings("unused") + public int getActivityTypeCode() { + return this.activityTypeCode; + } + + @NonNull + @Override + public String toString() { + return this.getActivityType(); + } + } + + public enum SKTransitionType { + + /** + * TODO + */ + ENTER("Enter", ActivityTransition.ACTIVITY_TRANSITION_ENTER), + + /** + * TODO + */ + EXIT("Exit", ActivityTransition.ACTIVITY_TRANSITION_EXIT); + + private final @NonNull String transitionType; + private final int transitionTypeCode; + + SKTransitionType(final @NonNull String transitionType, final int transitionTypeCode) { + this.transitionType = transitionType; + this.transitionTypeCode = transitionTypeCode; + } + + @SuppressWarnings("WeakerAccess") + public static SKTransitionType valueOf(final int transitionTypeCode) { + + switch (transitionTypeCode) { + + case ActivityTransition.ACTIVITY_TRANSITION_ENTER: + return ENTER; + + case ActivityTransition.ACTIVITY_TRANSITION_EXIT: + return EXIT; + + default: + throw new RuntimeException("Unsupported SKTransitionType with code: " + transitionTypeCode); + } + } + + @SuppressWarnings("unused") + public @NonNull String getTransitionType() { + return this.transitionType; + } + + @SuppressWarnings("unused") + public int getTransitionTypeCode() { + return this.transitionTypeCode; + } + + @NonNull + @Override + public String toString() { + return this.getTransitionType(); + } + } + + private final SKActivityType activityType; + private final SKTransitionType transitionType; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param activityTypeCode The type of the activity + * @param transitionTypeCode TODO + */ + public SKMotionActivityData(final long timestamp, final int activityTypeCode, final int transitionTypeCode) { + + super(SKSensorType.MOTION_ACTIVITY, timestamp); + + this.activityType = SKActivityType.valueOf(activityTypeCode); + this.transitionType = SKTransitionType.valueOf(transitionTypeCode); + } + + /** + * Get the csv header of the Motion Activity sensor data + * + * @return String with a CSV formatted header that describes the data of the Motion Activity sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,activityCode,activityString,transitionCode,transitionString"; + } + + /** + * Get the Motion Activity sensor data in csv format + * + * @return Activity data in csv format: timeIntervalSince1970, activity, activityString + * + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%d,%s", this.timestamp, this.activityType.getActivityTypeCode(), this.activityType.getActivityType()); + } + + /** + * Get the Motion Activity sensor data in JSONObject format + * + * @return JSONObject containing the Motion Activity sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, activity, activityString, confidence + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("activity", this.activityType.getActivityTypeCode()); + subJsonObject.put("activityString", this.activityType.getActivityType()); + subJsonObject.put("transition", this.transitionType.getTransitionTypeCode()); + subJsonObject.put("transitionString", this.transitionType.getTransitionType()); + + jsonObject.put("motionActivity", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + + /** + * Get the activity type + * + * @return Activity type + */ + @SuppressWarnings("unused") + public SKActivityType getActivityType() { + return this.activityType; + } + + /** + * Get the activity type + * + * @return Activity type + * + */ + @SuppressWarnings("unused") + public SKTransitionType getTransitionType() { + return this.transitionType; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKNotificationData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKNotificationData.java new file mode 100644 index 0000000..2093246 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKNotificationData.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.data; + + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; + +import java.util.Locale; + +public class SKNotificationData extends SKAbstractData { + + @SuppressWarnings("unused") + private static final String TAG = SKNotificationData.class.getSimpleName(); + + private final String actionType; + private final String packageName; + + /** + * TODO + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + */ + public SKNotificationData(final long timestamp, final @NonNull String actionType, final @NonNull String packageName) { + super(SKSensorType.NOTIFICATION, timestamp); + + this.actionType = actionType; + this.packageName = packageName; + } + + /** + * Get the csv header of the Notification sensor data + * + * @return String with a CSV formatted header that describes the data of the Notification sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,actionType,packageName"; + } + + /** + * Get the Notification sensor data in csv format + * + * @return Notification data in csv format: timeIntervalSince1970,actionType,packageName + */ + @Override + @NonNull + public String getDataInCSV() { + return String.format(Locale.US, "%d,%s,%s", this.timestamp, this.actionType, this.packageName); + } + + + /** + * Get the Notification sensor data in JSONObject format + * + * @return JSONObject containing the Notification sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, actionType, packageName + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("actionType", this.actionType); + subJsonObject.put("packageName", this.packageName); + + jsonObject.put("notification", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get the notification action type (posted, removed) + * + * @return actionType (posted/removed) + */ + @SuppressWarnings("unused") + public String getActionType() { + return this.actionType; + } + + /** + * Get the notification package name + * + * @return package name + */ + @SuppressWarnings("unused") + public String getPackageName() { + return this.packageName; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKRotationData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKRotationData.java index 51a7fc4..ab6d21d 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKRotationData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKRotationData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,24 +21,42 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKRotationData encapsulates measurements related to the Rotation sensor. + */ public class SKRotationData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKRotationData"; - - protected final float x; - protected final float y; - protected final float z; - protected final float cos; - protected final float headingAccuracy; - - public SKRotationData(long timestamp, float x, float y, float z, float cos, float headingAccuracy) { - - super(SKSensorModuleType.ROTATION, timestamp); + private static final String TAG = SKRotationData.class.getSimpleName(); + + private final float x; + private final float y; + private final float z; + private final float cos; + private final float headingAccuracy; + + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param x Rotation axis x-component*sin(theta/2) + * @param y Rotation axis y-component*sin(theta/2) + * @param z Rotation axis z-component*sin(theta/2) + * @param cos Cos(theta) + *

+ * where theta is the angle of rotation + * @param headingAccuracy Estimated accuracy in radians + */ + public SKRotationData(final long timestamp, final float x, final float y, final float z, final float cos, final float headingAccuracy) { + super(SKSensorType.ROTATION, timestamp); this.x = x; this.y = y; @@ -47,35 +65,117 @@ public SKRotationData(long timestamp, float x, float y, float z, float cos, floa this.headingAccuracy = headingAccuracy; } - public SKRotationData(long timestamp, float x, float y, float z) { + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param x Rotation axis x-component*sin(theta/2) + * @param y Rotation axis y-component*sin(theta/2) + * @param z Rotation axis z-component*sin(theta/2) + *

+ * where theta is the angle of rotation + */ + public SKRotationData(final long timestamp, final float x, final float y, final float z) { this(timestamp, x, y, z, 0, 0); } + /** + * Get the csv header of the Rotation sensor data + * + * @return String with a CSV formatted header that describes the data of the Rotation sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,x,y,z,cos,headingAccuracy"; + } + + /** + * Get Rotation sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, x, y, z, cos, headingAccuracy + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d,%f,%f,%f,%f,%f", this.timestamp, this.x, this.y, this.z, this.cos, this.headingAccuracy); } + /** + * Get the Rotation sensor data in JSONObject format + * + * @return JSONObject containing the Rotation sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, x, y, z, cos, headingAccuracy + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("x", this.x); + subJsonObject.put("y", this.y); + subJsonObject.put("z", this.z); + subJsonObject.put("cos", this.cos); + subJsonObject.put("headingAccuracy", this.headingAccuracy); + + jsonObject.put("rotation", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get X component of rotation + * + * @return X component + */ @SuppressWarnings("unused") public float getX() { return this.x; } + /** + * Get Y component of rotation + * + * @return Y component + */ @SuppressWarnings("unused") - public float getY() { + public float getY() { return this.y; } + /** + * Get Z component of rotation + * + * @return Z component + */ @SuppressWarnings("unused") public float getZ() { return this.z; } + /** + * Get cos of the angle of rotation + * + * @return Cos(theta) + */ @SuppressWarnings("unused") public float getCos() { return this.cos; } + /** + * Get heading accuracy of rotation data + * + * @return Heading accuracy + */ @SuppressWarnings("unused") public float getHeadingAccuracy() { return this.headingAccuracy; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKScreenStatusData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKScreenStatusData.java index 3f28892..1fbfec6 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKScreenStatusData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKScreenStatusData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,47 +21,117 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKScreenStatusData encapsulates measurements related to the Screen Status sensor. + */ public class SKScreenStatusData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKScreenStatusData"; + private static final String TAG = SKScreenStatusData.class.getSimpleName(); public static final int SCREEN_OFF = 0; public static final int SCREEN_ON = 1; - public static final int SCREEN_UNKNOWN = 2; - - protected final int status; + public static final int SCREEN_UNLOCKED = 2; + public static final int SCREEN_UNKNOWN = 3; - public SKScreenStatusData(long timestamp, int status) { + private final int status; - super(SKSensorModuleType.SCREEN_STATUS, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param status Screen status + */ + public SKScreenStatusData(final long timestamp, final int status) { + super(SKSensorType.SCREEN_STATUS, timestamp); this.status = status; } + /** + * Get the csv header of the Screen Status sensor data + * + * @return String with a CSV formatted header that describes the data of the Screen Status sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,status,statusString"; + } + + /** + * Get Screen Status sensor data in CSV format + * + * @return String in CSV format: timestamp, status, statusString + */ @Override + @NonNull public String getDataInCSV() { - return String.format(Locale.US, "%d,%s", this.timestamp, this.getStatusString()); + return String.format(Locale.US, "%d,%d,%s", this.timestamp, this.getStatus(), this.getStatusString()); } + /** + * Get Screen Status data in JSONObject format + * + * @return JSONObject containing the Screen Status data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, status, statusString + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + JSONObject subJsonObject = new JSONObject(); + subJsonObject.put("status", this.getStatus()); + subJsonObject.put("statusString", this.getStatusString()); + + jsonObject.put("screenStatus", subJsonObject); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + /** + * Get screen status + * + * @return Screen status as an int + */ @SuppressWarnings("unused") public int getStatus() { return this.status; } + /** + * Get screen status as a string + * + * @return Screen status as a string: "off", "on", "unlocked" or "unknown" + */ @SuppressWarnings("unused") public String getStatusString() { switch (this.status) { case SCREEN_OFF: - return "screen off"; + return "off"; case SCREEN_ON: - return "screen on"; + return "on"; + + case SCREEN_UNLOCKED: + return "unlocked"; default: return "unknown"; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKSensorData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKSensorData.java index b124970..92f1499 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKSensorData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKSensorData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,12 +21,20 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; + +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.SKSensorType; +import org.json.JSONObject; @SuppressWarnings("unused") public interface SKSensorData { - SKSensorModuleType getSensorModuleType(); + SKSensorType getSensorType(); + + @NonNull String getDataInCSV(); -} + @NonNull + JSONObject getDataInJSON(); +} \ No newline at end of file diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepCounterData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepCounterData.java index f1d95ca..361b616 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepCounterData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepCounterData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,31 +21,87 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKStepCounterData encapsulates measurements related to the Step Counter sensor. + */ public class SKStepCounterData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKStepCounterData"; - - protected final float steps; + private static final String TAG = SKStepCounterData.class.getSimpleName(); - public SKStepCounterData(long timestamp, float steps) { + private final int steps; - super(SKSensorModuleType.STEP_COUNTER, timestamp); + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + * @param steps Number of steps + */ + public SKStepCounterData(final long timestamp, final int steps) { + super(SKSensorType.STEP_COUNTER, timestamp); this.steps = steps; } + /** + * Get the csv header of the Step Counter sensor data + * + * @return String with a CSV formatted header that describes the data of the Step Counter sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970,numberOfSteps"; + } + + /** + * Get Step Counter sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970, numberOfSteps + */ @Override + @NonNull public String getDataInCSV() { - return String.format(Locale.US, "%d,%f", this.timestamp, this.steps); + return String.format(Locale.US, "%d,%d", this.timestamp, this.steps); + } + + /** + * Get the Step Counter sensor data in JSONObject format + * + * @return JSONObject containing the Step Counter sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, numberOfSteps + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + jsonObject.put("numberOfSteps", this.steps); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; } + /** + * Get number of steps + * + * @return number of steps + */ @SuppressWarnings("unused") - public float getSteps() { + public int getSteps() { return this.steps; } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepDetectorData.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepDetectorData.java index 6f584fb..6531672 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepDetectorData.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/data/SKStepDetectorData.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -21,23 +21,74 @@ package org.sensingkit.sensingkitlib.data; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.sensingkit.sensingkitlib.SKSensorType; import java.util.Locale; +/** + * An instance of SKStepCounterData encapsulates measurements related to the Step Counter sensor. + */ public class SKStepDetectorData extends SKAbstractData { @SuppressWarnings("unused") - private static final String TAG = "SKStepDetectorData"; + private static final String TAG = SKStepDetectorData.class.getSimpleName(); - public SKStepDetectorData(long timestamp) { + /** + * Initialize the instance + * + * @param timestamp Time in milliseconds (the difference between the current time and midnight, January 1, 1970 UTC) + */ + public SKStepDetectorData(final long timestamp) { - super(SKSensorModuleType.STEP_DETECTOR, timestamp); + super(SKSensorType.STEP_DETECTOR, timestamp); } + /** + * Get the csv header of the Step Counter sensor data + * + * @return String with a CSV formatted header that describes the data of the Step Counter sensor. + */ + @SuppressWarnings({"unused", "SameReturnValue"}) + @NonNull + public static String csvHeader() { + return "timeIntervalSince1970"; + } + + /** + * Get Step Detector sensor data in CSV format + * + * @return String in CSV format: timeIntervalSince1970 + */ @Override + @NonNull public String getDataInCSV() { return String.format(Locale.US, "%d", this.timestamp); } + + /** + * Get the Step Detector sensor data in JSONObject format + * + * @return JSONObject containing the Step Detector sensor data in JSONObject format: + * sensor type, sensor type in string, timeIntervalSince1970, numberOfSteps + */ + @Override + @NonNull + public JSONObject getDataInJSON() { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("sensorType", this.getSensorType()); + jsonObject.put("sensorTypeString", this.getSensorType().toString()); + jsonObject.put("timestamp", this.timestamp); + + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractGoogleServicesSensorModule.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractGoogleServicesSensorModule.java deleted file mode 100644 index 98c1567..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractGoogleServicesSensorModule.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.Context; -import android.os.Bundle; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.GoogleApiClient; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; - - -public abstract class SKAbstractGoogleServicesSensorModule extends SKAbstractSensorModule implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { - - @SuppressWarnings("unused") - private static final String TAG = "SKAbstractGoogleServicesSensorModule"; - - protected GoogleApiClient mClient; - - protected SKAbstractGoogleServicesSensorModule(final Context context, final SKSensorModuleType sensorModuleType) throws SKException { - super(context, sensorModuleType); - - - } - - protected abstract void serviceConnected(); - - @Override - public void onConnected(Bundle connectionHint) { - serviceConnected(); - } - - @Override - public void onConnectionSuspended(int cause) { - // Ignore, will try to reconnect automatically - } - - @Override - public void onConnectionFailed(ConnectionResult result) { - // At least one of the API client connect attempts failed - // No client is connected - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractNativeSensorModule.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractNativeSensorModule.java deleted file mode 100644 index 3b562a7..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractNativeSensorModule.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.os.Build; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKExceptionErrorCode; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; - -public abstract class SKAbstractNativeSensorModule extends SKAbstractSensorModule { - - @SuppressWarnings("unused") - private static final String TAG = "SKAbstractNativeSensorModule"; - - private final SensorManager mSensorManager; - private final Sensor mSensor; - private final SensorEventListener mSensorEventListener; - - protected SKAbstractNativeSensorModule(final Context context, final SKSensorModuleType sensorModuleType) throws SKException { - super(context, sensorModuleType); - - mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); - mSensor = mSensorManager.getDefaultSensor(getSensorType(sensorModuleType)); - - mSensorEventListener = new SensorEventListener() { - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // Ignore - } - - @Override - public void onSensorChanged(SensorEvent event) { - - // Build the data object - SKAbstractData data = buildData(event); - - // Submit sensor data object - submitSensorData(data); - } - }; - } - - @Override - public void startSensing() throws SKException { - - this.isSensing = true; - - boolean status = mSensorManager.registerListener(mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL); - - if (!status) { - throw new SKException(TAG, "SensorModule '" + getSensorName() + "' could not be started.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - } - - @Override - public void stopSensing() { - - mSensorManager.unregisterListener(mSensorEventListener); - - this.isSensing = false; - } - - protected abstract SKAbstractData buildData(SensorEvent event); - - @SuppressLint("InlinedApi") // There is a check in STEP_DETECTOR and STEP_COUNTER - private static int getSensorType(SKSensorModuleType sensorType) throws SKException{ - - switch (sensorType) { - - case ACCELEROMETER: - return Sensor.TYPE_ACCELEROMETER; - - case GRAVITY: - return Sensor.TYPE_GRAVITY; - - case LINEAR_ACCELERATION: - return Sensor.TYPE_LINEAR_ACCELERATION; - - case GYROSCOPE: - return Sensor.TYPE_GYROSCOPE; - - case ROTATION: - return Sensor.TYPE_ROTATION_VECTOR; - - case MAGNETOMETER: - return Sensor.TYPE_MAGNETIC_FIELD; - - case AMBIENT_TEMPERATURE: - return Sensor.TYPE_AMBIENT_TEMPERATURE; - - case STEP_DETECTOR: - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - return Sensor.TYPE_STEP_DETECTOR; - } - else - { - throw new SKException(TAG, "STEP_DETECTOR requires Android KitKat or greater.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - case STEP_COUNTER: - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - return Sensor.TYPE_STEP_COUNTER; - } - else - { - throw new SKException(TAG, "STEP_COUNTER requires Android KitKat or greater.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - case LIGHT: - return Sensor.TYPE_LIGHT; - - case LOCATION: - case ACTIVITY: - case BATTERY: - throw new SKException(TAG, "Not a native SensorModule.", SKExceptionErrorCode.UNKNOWN_ERROR); - - default: - throw new SKException(TAG, "Unknown SensorModule", SKExceptionErrorCode.UNKNOWN_ERROR); - - } - } - -} \ No newline at end of file diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractSensorModule.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractSensorModule.java deleted file mode 100644 index 8cf134f..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAbstractSensorModule.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.Context; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKExceptionErrorCode; -import org.sensingkit.sensingkitlib.SKSensorDataListener; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; - -import java.util.ArrayList; - -public abstract class SKAbstractSensorModule implements SKSensorModuleInterface { - - @SuppressWarnings("unused") - private static final String TAG = "SKAbstractSensorModule"; - - protected final Context mApplicationContext; - protected final SKSensorModuleType mSensorModuleType; - protected boolean isSensing = false; - protected ArrayList mSensorDataListeners; - - protected SKAbstractSensorModule(final Context context, final SKSensorModuleType sensorModuleType) { - - this.mApplicationContext = context; - this.mSensorModuleType = sensorModuleType; - } - - public boolean isSensing() { - return isSensing; - } - - public SKSensorModuleType getSensorType() { - return this.mSensorModuleType; - } - - public String getSensorName() throws SKException { - return SKSensorModuleUtilities.getSensorModuleInString(mSensorModuleType); - } - - public void subscribeSensorDataListener(SKSensorDataListener callback) throws SKException { - - // Init the list - if (this.mSensorDataListeners == null) { - this.mSensorDataListeners = new ArrayList<>(); - } - - // Register the callback - if (this.mSensorDataListeners.contains(callback)) { - throw new SKException(TAG, "SKSensorDataListener already registered.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - this.mSensorDataListeners.add(callback); - } - - public void unsubscribeSensorDataListener(SKSensorDataListener callback) throws SKException { - - // Unregister the callback - if (this.mSensorDataListeners == null || !this.mSensorDataListeners.remove(callback)) { - throw new SKException(TAG, "SKSensorDataListener is not registered.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - // Delete the callBackList if it is empty - if (this.mSensorDataListeners.size() == 0) { - this.mSensorDataListeners = null; - } - } - - public void unsubscribeAllSensorDataListeners() throws SKException { - - // Clear all callbacks - if (this.mSensorDataListeners != null) { - this.mSensorDataListeners.clear(); - this.mSensorDataListeners = null; - } - } - - protected abstract boolean shouldPostSensorData(SKAbstractData data); - - protected void submitSensorData(SKAbstractData data) { - - // If there is a significant change - if (shouldPostSensorData(data)) { - - if (mSensorDataListeners != null) { - - // CallBack with data as parameter - for (SKSensorDataListener callback : mSensorDataListeners) { - callback.onDataReceived(mSensorModuleType, data); - } - } - } - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKActivity.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKActivity.java deleted file mode 100644 index 401d75e..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKActivity.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; -import com.google.android.gms.location.ActivityRecognitionApi; -import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.location.ActivityRecognition; -import com.google.android.gms.location.ActivityRecognitionResult; -import com.google.android.gms.location.DetectedActivity; - - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; -import org.sensingkit.sensingkitlib.data.SKActivityData; - -public class SKActivity extends SKAbstractGoogleServicesSensorModule { - - @SuppressWarnings("unused") - private static final String TAG = "SKActivity"; - - private ActivityRecognitionApi mActivityRecognition; - private PendingIntent mRecognitionPendingIntent; - private BroadcastReceiver mBroadcastReceiver; - - // Last data sensed - private int mLastActivityTypeSensed = Integer.MAX_VALUE; - private int mLastConfidenceSensed = Integer.MAX_VALUE; - - public SKActivity(final Context context) throws SKException { - super(context, SKSensorModuleType.ACTIVITY); - - mClient = new GoogleApiClient.Builder(context) - .addApi(ActivityRecognition.API) - .addConnectionCallbacks(this) - .addOnConnectionFailedListener(this) - .build(); - - mActivityRecognition = ActivityRecognition.ActivityRecognitionApi; - - mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - - ActivityRecognitionResult result = intent.getParcelableExtra(SKActivityRecognitionIntentService.RECOGNITION_RESULT); - - // Get activity from the list of activities - DetectedActivity activity = getActivity(result); - - // Get the type of activity - int activityType = activity.getType(); - - // Get the confidence percentage for the most probable activity - int confidence = activity.getConfidence(); - - // Build the data object - SKAbstractData data = new SKActivityData(result.getTime(), activityType, confidence); - - // Submit sensor data object - submitSensorData(data); - } - }; - } - - private DetectedActivity getActivity(ActivityRecognitionResult result) { - - // Get the most probable activity from the list of activities in the result - DetectedActivity mostProbableActivity = result.getMostProbableActivity(); - - // If the activity is ON_FOOT, choose between WALKING or RUNNING - if (mostProbableActivity.getType() == DetectedActivity.ON_FOOT) { - - // Iterate through all possible activities. The activities are sorted by most probable activity first. - for (DetectedActivity activity : result.getProbableActivities()) { - - if (activity.getType() == DetectedActivity.WALKING || activity.getType() == DetectedActivity.RUNNING) { - return activity; - } - } - - // It is ON_FOOT, but not sure if it is WALKING or RUNNING - Log.i(TAG, "Activity ON_FOOT, but not sure if it is WALKING or RUNNING."); - return mostProbableActivity; - } - else - { - return mostProbableActivity; - } - - } - - @Override - public void startSensing() { - - this.isSensing = true; - - mClient.connect(); - } - - @Override - public void stopSensing() { - - unregisterIntent(); - unregisterLocalBroadcastManager(); - - mClient.disconnect(); - - this.isSensing = false; - - // Clear last sensed values - mLastActivityTypeSensed = Integer.MAX_VALUE; - mLastConfidenceSensed = Integer.MAX_VALUE; - } - - @Override - protected void serviceConnected() - { - Log.i(TAG, "GoogleApiClient Connected!"); - - registerLocalBroadcastManager(); - registerIntent(); - } - - private void registerIntent() { - - if (mRecognitionPendingIntent == null) { - Intent intent = new Intent(mApplicationContext, SKActivityRecognitionIntentService.class); - mRecognitionPendingIntent = PendingIntent.getService(mApplicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - mActivityRecognition.requestActivityUpdates(mClient, 0, mRecognitionPendingIntent); - } - - private void unregisterIntent() { - - mActivityRecognition.removeActivityUpdates(mClient, mRecognitionPendingIntent); - mRecognitionPendingIntent.cancel(); - mRecognitionPendingIntent = null; - } - - private void registerLocalBroadcastManager() { - LocalBroadcastManager manager = LocalBroadcastManager.getInstance(mApplicationContext); - manager.registerReceiver(mBroadcastReceiver, new IntentFilter(SKActivityRecognitionIntentService.BROADCAST_UPDATE)); - } - - private void unregisterLocalBroadcastManager() { - LocalBroadcastManager manager = LocalBroadcastManager.getInstance(mApplicationContext); - manager.unregisterReceiver(mBroadcastReceiver); - } - - @Override - protected boolean shouldPostSensorData(SKAbstractData data) { - - // Only post when specific values changed - - int activityType = ((SKActivityData)data).getActivityType(); - int confidence = ((SKActivityData)data).getConfidence(); - - // Ignore Temperature and Voltage - boolean shouldPost = (mLastActivityTypeSensed != activityType || - mLastConfidenceSensed != confidence ); - - if (shouldPost) { - - this.mLastActivityTypeSensed = activityType; - this.mLastConfidenceSensed = confidence; - } - - return shouldPost; - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKActivityRecognitionIntentService.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKActivityRecognitionIntentService.java deleted file mode 100644 index 2738806..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKActivityRecognitionIntentService.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.app.IntentService; -import android.content.Intent; -import android.support.v4.content.LocalBroadcastManager; - -import com.google.android.gms.location.ActivityRecognitionResult; - -public class SKActivityRecognitionIntentService extends IntentService { - - @SuppressWarnings("unused") - private static final String TAG = "SKActivityRecognitionIntentService"; - - public static final String RECOGNITION_RESULT = "result"; - public static final String BROADCAST_UPDATE = "new_update"; - - public SKActivityRecognitionIntentService() { - - // Set the label for the service's background thread - super("ActivityRecognitionIntentService"); - } - - @Override - protected void onHandleIntent(Intent intent) { - - // If the intent contains an update - if (ActivityRecognitionResult.hasResult(intent)) { - - // Get the update - ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); - - Intent i = new Intent(BROADCAST_UPDATE); - i.putExtra(RECOGNITION_RESULT, result); - LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); - manager.sendBroadcast(i); - } - - } - -} \ No newline at end of file diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAudioLevel.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAudioLevel.java deleted file mode 100644 index 7a62f21..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAudioLevel.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.Context; -import android.media.AudioFormat; -import android.media.AudioRecord; -import android.media.MediaRecorder; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; -import org.sensingkit.sensingkitlib.data.SKAudioLevelData; - -public class SKAudioLevel extends SKAbstractSensorModule { - - @SuppressWarnings("unused") - private static final String TAG = "SKAudioLevel"; - - private static final int sampleRate = 8000; - private static final int bufferSizeFactor = 1; - - private final int bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT) * bufferSizeFactor; - - private final AudioRecord audioRecord; - - public SKAudioLevel(final Context context) throws SKException { - super(context, SKSensorModuleType.AUDIO_LEVEL); - - // Configure the AudioRecord - audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); - } - - @Override - protected boolean shouldPostSensorData(SKAbstractData data) { - - // Always post sensor data - return true; - } - - @Override - public void startSensing() { - - this.isSensing = true; - - // monitor audio - audioRecord.startRecording(); - - // init the thread that read the audio buffer - Thread thread = new Thread(new Runnable() { - public void run() { - readAudioBuffer(); - } - }); - - // Set priority to max and start the thread that reads the audio level - thread.setPriority(Thread.currentThread().getThreadGroup().getMaxPriority()); - thread.start(); - } - - @Override - public void stopSensing() { - - audioRecord.stop(); - - this.isSensing = false; - } - - private void readAudioBuffer() { - - short[] buffer = new short[bufferSize]; - - int bufferReadResult; - - do { - // read buffer - bufferReadResult = audioRecord.read(buffer, 0, bufferSize); - - // get max audio level - int level = getMaxAbs(buffer); - - // Build the data object - SKAbstractData data = new SKAudioLevelData(System.currentTimeMillis(), level); - - // Submit sensor data object - submitSensorData(data); - } - while (bufferReadResult > 0 && audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING); - } - - // Get the Max Abs of the raw data - private int getMaxAbs(short[] raw) { - - int max = Math.abs(raw[0]); - - for (int i = 1 ; i < raw.length; i++) - { - max = Math.max(max, Math.abs(raw[i])); - } - - return max; - } -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAudioRecorder.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAudioRecorder.java deleted file mode 100644 index 9f447be..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAudioRecorder.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.Context; -import android.media.MediaRecorder; -import android.os.Environment; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKExceptionErrorCode; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; - -import java.io.IOException; - -public class SKAudioRecorder extends SKAbstractSensorModule { - - @SuppressWarnings("unused") - private static final String TAG = "SKAudioRecorder"; - - private static final String outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.aac"; - - private final MediaRecorder recorder; - - public SKAudioRecorder(final Context context) throws SKException { - super(context, SKSensorModuleType.AUDIO_RECORDER); - - recorder = new MediaRecorder(); - recorder.setAudioSource(MediaRecorder.AudioSource.MIC); - recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS); - recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); - recorder.setOutputFile(outputFile); - } - - @Override - protected boolean shouldPostSensorData(SKAbstractData data) { - - // This sensor does not post data - return false; - } - - @Override - public void startSensing() throws SKException { - - this.isSensing = true; - - try { - recorder.prepare(); - } catch (IOException e) { - e.printStackTrace(); - throw new SKException(TAG, "AudioRecorder sensor could not be prepared.", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - recorder.start(); - } - - @Override - public void stopSensing() { - - this.isSensing = false; - - recorder.stop(); - recorder.reset(); - recorder.release(); - } -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKBattery.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKBattery.java deleted file mode 100644 index c2efefd..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKBattery.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; -import org.sensingkit.sensingkitlib.data.SKBatteryData; - -public class SKBattery extends SKAbstractSensorModule { - - @SuppressWarnings("unused") - private static final String TAG = "SKBattery"; - - // Last data sensed - private int mLastLevelSensed = Integer.MAX_VALUE; - private int mLastScaleSensed = Integer.MAX_VALUE; - private int mLastTemperatureSensed = Integer.MAX_VALUE; - private int mLastVoltageSensed = Integer.MAX_VALUE; - private int mLastPluggedSensed = Integer.MAX_VALUE; - private int mLastStatusSensed = Integer.MAX_VALUE; - private int mLastHealthSensed = Integer.MAX_VALUE; - - private final BroadcastReceiver mBroadcastReceiver; - - public SKBattery(final Context context) throws SKException { - super(context, SKSensorModuleType.BATTERY); - - mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - - // Read Battery - int level = intent.getIntExtra("level", -1); - int scale = intent.getIntExtra("scale", -1); - int temperature = intent.getIntExtra("temperature", 0); - int voltage = intent.getIntExtra("voltage", 0); - int plugged = intent.getIntExtra("plugged", -1); - int status = intent.getIntExtra("status", 0); - int health = intent.getIntExtra("health", 0); - - // Build the data object - SKAbstractData data = new SKBatteryData(System.currentTimeMillis(), level, scale, temperature, voltage, plugged, status, health); - - // Submit sensor data object - submitSensorData(data); - } - }; - } - - @Override - public void startSensing() { - - this.isSensing = true; - - registerLocalBroadcastManager(); - } - - @Override - public void stopSensing() { - - unregisterLocalBroadcastManager(); - - this.isSensing = false; - - // Clear last sensed values - mLastLevelSensed = Integer.MAX_VALUE; - mLastScaleSensed = Integer.MAX_VALUE; - mLastTemperatureSensed = Integer.MAX_VALUE; - mLastVoltageSensed = Integer.MAX_VALUE; - mLastPluggedSensed = Integer.MAX_VALUE; - mLastStatusSensed = Integer.MAX_VALUE; - mLastHealthSensed = Integer.MAX_VALUE; - } - - private void registerLocalBroadcastManager() { - IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - mApplicationContext.registerReceiver(mBroadcastReceiver, filter); - } - - private void unregisterLocalBroadcastManager() { - mApplicationContext.unregisterReceiver(mBroadcastReceiver); - } - - @Override - protected boolean shouldPostSensorData(SKAbstractData data) { - - // Only post when specific values changed - - int level = ((SKBatteryData)data).getLevel(); - int scale = ((SKBatteryData)data).getScale(); - int temperature = ((SKBatteryData)data).getTemperature(); - int voltage = ((SKBatteryData)data).getVoltage(); - int plugged = ((SKBatteryData)data).getPlugged(); - int status = ((SKBatteryData)data).getBatteryStatus(); - int health = ((SKBatteryData)data).getBatteryHealth(); - - // Ignore Temperature and Voltage - boolean shouldPost = (mLastLevelSensed != level || - mLastScaleSensed != scale || - mLastPluggedSensed != plugged || - mLastStatusSensed != status || - mLastHealthSensed != health ); - - if (shouldPost) { - this.mLastLevelSensed = level; - this.mLastScaleSensed = scale; - this.mLastTemperatureSensed = temperature; - this.mLastVoltageSensed = voltage; - this.mLastPluggedSensed = plugged; - this.mLastStatusSensed = status; - this.mLastHealthSensed = health; - } - - return shouldPost; - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLocation.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLocation.java deleted file mode 100644 index 1d267fd..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLocation.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.Context; -import android.util.Log; - -import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.location.LocationListener; -import com.google.android.gms.location.LocationRequest; -import com.google.android.gms.location.LocationServices; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; -import org.sensingkit.sensingkitlib.data.SKLocationData; - -public class SKLocation extends SKAbstractGoogleServicesSensorModule implements LocationListener { - - @SuppressWarnings("unused") - private static final String TAG = "SKLocation"; - - public SKLocation(final Context context) throws SKException { - super(context, SKSensorModuleType.LOCATION); - - mClient = new GoogleApiClient.Builder(context) - .addApi(LocationServices.API) - .addConnectionCallbacks(this) - .addOnConnectionFailedListener(this) - .build(); - } - - @Override - public void startSensing() { - - this.isSensing = true; - - mClient.connect(); - } - - @Override - public void stopSensing() { - - unregisterForLocationUpdates(); - mClient.disconnect(); - - this.isSensing = false; - } - - @Override - protected void serviceConnected() - { - Log.i(TAG, "GoogleApiClient Connected!"); - - registerForLocationUpdates(); - } - - @Override - public void onLocationChanged(android.location.Location location) { - - // Build the data object - SKAbstractData data = new SKLocationData(System.currentTimeMillis(), location); - - // Submit sensor data object - submitSensorData(data); - } - - private void registerForLocationUpdates() { - - LocationRequest locationRequest = LocationRequest.create(); - locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); - locationRequest.setInterval(1000); // Update location every second - - LocationServices.FusedLocationApi.requestLocationUpdates(mClient, locationRequest, this); - } - - private void unregisterForLocationUpdates() { - - LocationServices.FusedLocationApi.removeLocationUpdates(mClient, this); - - } - - @Override - protected boolean shouldPostSensorData(SKAbstractData data) { - - // Always post sensor data - return true; - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKScreenStatus.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKScreenStatus.java deleted file mode 100644 index 73e4166..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKScreenStatus.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; -import org.sensingkit.sensingkitlib.data.SKAbstractData; -import org.sensingkit.sensingkitlib.data.SKScreenStatusData; - -public class SKScreenStatus extends SKAbstractSensorModule { - - private final BroadcastReceiver mBroadcastReceiver; - - @SuppressWarnings("unused") - private static final String TAG = "SKScreenStatus"; - - public SKScreenStatus(final Context context) throws SKException { - super(context, SKSensorModuleType.SCREEN_STATUS); - - mBroadcastReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - - // Read Status - int status; - - if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { - status = SKScreenStatusData.SCREEN_OFF; - } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { - status = SKScreenStatusData.SCREEN_ON; - } else { - status = SKScreenStatusData.SCREEN_UNKNOWN; - } - - // Build the data object - SKAbstractData data = new SKScreenStatusData(System.currentTimeMillis(), status); - - // Submit sensor data object - submitSensorData(data); - } - }; - } - - @Override - protected boolean shouldPostSensorData(SKAbstractData data) { - - // Always post sensor data - return true; - } - - @Override - public void startSensing() { - - this.isSensing = true; - - registerLocalBroadcastManager(); - } - - @Override - public void stopSensing() { - - unregisterLocalBroadcastManager(); - - this.isSensing = false; - } - - private void registerLocalBroadcastManager() { - - // Register for SCREEN_STATUS ON and OFF notifications - mApplicationContext.registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON)); - mApplicationContext.registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF)); - } - - private void unregisterLocalBroadcastManager() { - mApplicationContext.unregisterReceiver(mBroadcastReceiver); - } -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKSensorModuleUtilities.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKSensorModuleUtilities.java deleted file mode 100644 index da40807..0000000 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKSensorModuleUtilities.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk - * - * This file is part of SensingKit-Android library. - * For more information, please visit http://www.sensingkit.org - * - * SensingKit-Android is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SensingKit-Android is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SensingKit-Android. If not, see . - */ - -package org.sensingkit.sensingkitlib.modules; - -import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKExceptionErrorCode; -import org.sensingkit.sensingkitlib.SKSensorModuleType; - -public final class SKSensorModuleUtilities { - - @SuppressWarnings("unused") - private static final String TAG = "SKSensorModuleUtilities"; - - public static String getSensorModuleInString(SKSensorModuleType moduleType) throws SKException { - - switch (moduleType) { - - case ACCELEROMETER: - return "Accelerometer"; - - case GRAVITY: - return "Gravity"; - - case LINEAR_ACCELERATION: - return "Linear Acceleration"; - - case GYROSCOPE: - return "Gyroscope"; - - case ROTATION: - return "Rotation"; - - case MAGNETOMETER: - return "Magnetometer"; - - case AMBIENT_TEMPERATURE: - return "Ambient Temperature"; - - case STEP_DETECTOR: - return "Step Detector"; - - case STEP_COUNTER: - return "Step Counter"; - - case LIGHT: - return "Light"; - - case LOCATION: - return "Location"; - - case ACTIVITY: - return "Activity"; - - case BATTERY: - return "Battery"; - - case SCREEN_STATUS: - return "Screen Status"; - - case AUDIO_RECORDER: - return "Audio Recorder"; - - case AUDIO_LEVEL: - return "Audio Level"; - - case BLUETOOTH: - return "Bluetooth"; - - default: - throw new SKException(TAG, "Unknown SensorModule", SKExceptionErrorCode.UNKNOWN_ERROR); - } - - } - -} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAbstractNativeSensor.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAbstractNativeSensor.java new file mode 100644 index 0000000..10afb5c --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAbstractNativeSensor.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKExceptionErrorCode; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKAbstractNativeSensorConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; + +@SuppressWarnings("WeakerAccess") +public abstract class SKAbstractNativeSensor extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKAbstractNativeSensor.class.getSimpleName(); + + private SensorManager mSensorManager; + private Sensor mSensor; + private SensorEventListener mSensorEventListener; + + protected SKAbstractNativeSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) throws SKException { + super(context, sensorType, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "initSensor");} + + mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); + + if (mSensorManager == null) { + throw new SKException(TAG, "Could not access the system service: SENSOR_SERVICE.", SKExceptionErrorCode.UNKNOWN_ERROR); + } + + mSensor = mSensorManager.getDefaultSensor(getSensorType(sensorType)); + + if (mSensor == null) { + throw new SKException(TAG, "Sensor [" + sensorType.getName() + "] is not available in the device.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + mSensorEventListener = new SensorEventListener() { + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // Ignore + } + + @Override + public void onSensorChanged(SensorEvent event) { + + // Build the data object + SKAbstractData data = buildData(event); + + // Submit sensor data object + submitSensorData(data); + } + }; + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensor [" + sensorType.getName() + "]");} + + // Not required for this type of sensor + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + // Get the configuration + SKAbstractNativeSensorConfiguration configuration = (SKAbstractNativeSensorConfiguration)mConfiguration; + + boolean status = mSensorManager.registerListener(mSensorEventListener, mSensor, configuration.getSamplingRate()); + + if (!status) { + throw new SKException(TAG, "Sensor '" + getSensorName() + "' could not be started.", SKExceptionErrorCode.SENSOR_ERROR); + } + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + mSensorManager.unregisterListener(mSensorEventListener); + + super.stopSensing(); + } + + @NonNull + protected abstract SKAbstractData buildData(final SensorEvent event); + + @SuppressLint("InlinedApi") // There is a check in SKSensorManager + private static int getSensorType(final SKSensorType sensorType) { + + switch (sensorType) { + + case ACCELEROMETER: + return Sensor.TYPE_ACCELEROMETER; + + case GRAVITY: + return Sensor.TYPE_GRAVITY; + + case LINEAR_ACCELERATION: + return Sensor.TYPE_LINEAR_ACCELERATION; + + case GYROSCOPE: + return Sensor.TYPE_GYROSCOPE; + + case ROTATION: + return Sensor.TYPE_ROTATION_VECTOR; + + case MAGNETOMETER: + return Sensor.TYPE_MAGNETIC_FIELD; + + case AMBIENT_TEMPERATURE: + return Sensor.TYPE_AMBIENT_TEMPERATURE; + + case STEP_DETECTOR: + return Sensor.TYPE_STEP_DETECTOR; + + case STEP_COUNTER: + return Sensor.TYPE_STEP_COUNTER; + + case LIGHT: + return Sensor.TYPE_LIGHT; + + case HUMIDITY: + return Sensor.TYPE_RELATIVE_HUMIDITY; + + case BAROMETER: + return Sensor.TYPE_PRESSURE; + + default: + throw new RuntimeException("Sensor '" + sensorType.getName() + "' is not a native sensor."); + } + } + +} \ No newline at end of file diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAbstractSensor.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAbstractSensor.java new file mode 100644 index 0000000..f880d27 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAbstractSensor.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.Context; +import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKExceptionErrorCode; +import org.sensingkit.sensingkitlib.SKSensorDataHandler; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; + +import java.util.ArrayList; + +@SuppressWarnings("WeakerAccess") +public abstract class SKAbstractSensor implements SKSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKAbstractSensor.class.getSimpleName(); + + protected final Context mApplicationContext; + protected final SKSensorType mSensorType; + protected boolean isSensing = false; + protected SKConfiguration mConfiguration; + + private ArrayList mSensorDataListeners; + + protected SKAbstractSensor(final @NonNull Context context, final SKSensorType sensorType, final @NonNull SKConfiguration configuration) throws SKException { + + // Check if the correct configuration type provided + if (!configuration.isValidForSensor(sensorType)) { + throw new SKException(TAG, "Wrong SKConfiguration class provided (" + configuration.getClass() + ") for sensor " + sensorType.getName() + ".", + SKExceptionErrorCode.CONFIGURATION_NOT_VALID); + } + + this.mApplicationContext = context; + this.mSensorType = sensorType; + this.mConfiguration = configuration; + + // call sensor init method + initSensor(context, sensorType, configuration); + } + + protected abstract void initSensor(final @NonNull Context context, final SKSensorType sensorType, final @NonNull SKConfiguration configuration) throws SKException; + + @SuppressWarnings("unused") + protected abstract void updateSensor(final @NonNull Context context, final SKSensorType sensorType, final @NonNull SKConfiguration configuration) throws SKException; + + @CallSuper + public void startSensing() throws SKException { + this.isSensing = true; + } + + @CallSuper + public void stopSensing() throws SKException { + this.isSensing = false; + } + + public boolean isSensing() { + return isSensing; + } + + public SKSensorType getSensorType() { + return this.mSensorType; + } + + @NonNull + public String getSensorName() { + return mSensorType.getName(); + } + + @Override + public void setConfiguration(final @NonNull SKConfiguration configuration) throws SKException { + + // Check if the correct configuration type provided + if (!configuration.isValidForSensor(mSensorType)) { + throw new SKException(TAG, "Wrong SKConfiguration class provided (" + configuration.getClass() + ") for sensor " + mSensorType.getName() + ".", + SKExceptionErrorCode.CONFIGURATION_NOT_VALID); + } + + this.mConfiguration = configuration; + + // call update sensor configuration + updateSensor(mApplicationContext, mSensorType, configuration); + } + + public void subscribeSensorDataHandler(final @NonNull SKSensorDataHandler handler) throws SKException { + + // Init the list + if (this.mSensorDataListeners == null) { + this.mSensorDataListeners = new ArrayList<>(); + } + + // Register the callback + if (this.mSensorDataListeners.contains(handler)) { + throw new SKException(TAG, "SKSensorDataHandler already registered.", SKExceptionErrorCode.DATA_HANDLER_ALREADY_REGISTERED); + } + + this.mSensorDataListeners.add(handler); + } + + public void unsubscribeSensorDataHandler(final @NonNull SKSensorDataHandler handler) throws SKException { + + // Unregister the callback + if (this.mSensorDataListeners == null || !this.mSensorDataListeners.remove(handler)) { + throw new SKException(TAG, "SKSensorDataHandler is not registered.", SKExceptionErrorCode.DATA_HANDLER_NOT_REGISTERED); + } + + // Delete the callBackList if it is empty + if (this.mSensorDataListeners.size() == 0) { + this.mSensorDataListeners = null; + } + } + + public void unsubscribeAllSensorDataHandlers() { + + // Clear all callbacks + if (this.mSensorDataListeners != null) { + this.mSensorDataListeners.clear(); + this.mSensorDataListeners = null; + } + } + + protected abstract boolean shouldPostSensorData(final @NonNull SKAbstractData data); + + protected boolean shouldDebugSensor() { + return mConfiguration.getDebugStatus(); + } + + protected void submitSensorData(final @NonNull SKAbstractData data) { + + // If there is a significant change + if (shouldPostSensorData(data)) { + + if (mSensorDataListeners != null) { + + // CallBack with data as parameter + for (SKSensorDataHandler callback : mSensorDataListeners) { + callback.onDataReceived(mSensorType, data); + } + } + } + } + + @Override + public void sensorDeregistered() { + // Override this method in the sensor subclass if needed. + } + + @Override + public String[] getRequiredPermissions() { + // Override this method in the sensor subclass if a special permission is needed. + return new String[]{}; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAccelerometer.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAccelerometer.java similarity index 55% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAccelerometer.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAccelerometer.java index 53256c2..01900c4 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAccelerometer.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAccelerometer.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKAccelerometerConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKAccelerometerData; -public class SKAccelerometer extends SKAbstractNativeSensorModule { +public class SKAccelerometer extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKAccelerometer"; + private static final String TAG = SKAccelerometer.class.getSimpleName(); - public SKAccelerometer(final Context context) throws SKException { - super(context, SKSensorModuleType.ACCELEROMETER); + public SKAccelerometer(final Context context, final @NonNull SKAccelerometerConfiguration configuration) throws SKException { + super(context, SKSensorType.ACCELEROMETER, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final SensorEvent event) { return new SKAccelerometerData(System.currentTimeMillis(), event.values[0], event.values[1], event.values[2]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKAccelerometerConfiguration((SKAccelerometerConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAmbientTemperature.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAmbientTemperature.java similarity index 57% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAmbientTemperature.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAmbientTemperature.java index a2e5ea8..f1c1e62 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKAmbientTemperature.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAmbientTemperature.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKAmbientTemperatureConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKAmbientTemperatureData; -public class SKAmbientTemperature extends SKAbstractNativeSensorModule { +public class SKAmbientTemperature extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKAmbientTemperature"; + private static final String TAG = SKAmbientTemperature.class.getSimpleName(); - public SKAmbientTemperature(final Context context) throws SKException { - super(context, SKSensorModuleType.AMBIENT_TEMPERATURE); + public SKAmbientTemperature(final Context context, final @NonNull SKAmbientTemperatureConfiguration configuration) throws SKException { + super(context, SKSensorType.AMBIENT_TEMPERATURE, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final SensorEvent event) { return new SKAmbientTemperatureData(System.currentTimeMillis(), event.values[0]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKAmbientTemperatureConfiguration((SKAmbientTemperatureConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAudioLevel.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAudioLevel.java new file mode 100644 index 0000000..46f3cfa --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKAudioLevel.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.Manifest; +import android.content.Context; +import android.media.AudioFormat; +import android.media.AudioRecord; +import android.media.MediaRecorder; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKAudioLevelConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKAudioLevelData; + +public class SKAudioLevel extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKAudioLevel.class.getSimpleName(); + + private static final int sampleRate = 8000; + private static final int bufferSizeFactor = 1; + + private int bufferSize; + + private AudioRecord audioRecord; + + public SKAudioLevel(final Context context, final SKAudioLevelConfiguration configuration) throws SKException { + super(context, SKSensorType.AUDIO_LEVEL, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + + this.bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT) * bufferSizeFactor; + Log.i(TAG, "Init sensor with BufferSize: " + this.bufferSize); + + // Configure the AudioRecord + this.audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + + // Not required for this type of sensor + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKAudioLevelConfiguration((SKAudioLevelConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + // monitor audio + audioRecord.startRecording(); + + // init the thread that read the audio buffer + Thread thread = new Thread(this::readAudioBuffer); + + // Set priority to max and start the thread that reads the audio level + thread.setPriority(Thread.currentThread().getThreadGroup().getMaxPriority()); + thread.start(); + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + audioRecord.stop(); + + super.stopSensing(); + } + + private void readAudioBuffer() { + + short[] buffer = new short[bufferSize]; + + int bufferReadResult; + + do { + // read buffer + bufferReadResult = audioRecord.read(buffer, 0, bufferSize); + + // get max audio level + int level = getMaxAbs(buffer); + + // Build the data object + SKAbstractData data = new SKAudioLevelData(System.currentTimeMillis(), level); + + // Submit sensor data object + submitSensorData(data); + } + while (bufferReadResult > 0 && audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING); + } + + // Get the Max Abs of the raw data + private int getMaxAbs(final short[] raw) { + + int max = Math.abs(raw[0]); + + for (int i = 1 ; i < raw.length; i++) + { + max = Math.max(max, Math.abs(raw[i])); + } + + return max; + } + + @Override + public void sensorDeregistered() { + super.sensorDeregistered(); + + // Release sensor + audioRecord.release(); + } + + @Override + public String[] getRequiredPermissions() { + return new String[]{Manifest.permission.RECORD_AUDIO}; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBarometer.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBarometer.java new file mode 100644 index 0000000..9985a7e --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBarometer.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.Context; +import android.hardware.SensorEvent; +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKBarometerConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKBarometerData; + +public class SKBarometer extends SKAbstractNativeSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKBarometer.class.getSimpleName(); + + public SKBarometer(final Context context, final SKBarometerConfiguration configuration) throws SKException { + super(context, SKSensorType.BAROMETER, configuration); + } + + @Override + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { + return new SKBarometerData(System.currentTimeMillis(), event.values[0]); + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKBarometerConfiguration((SKBarometerConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBatteryStatus.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBatteryStatus.java new file mode 100644 index 0000000..17ba803 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBatteryStatus.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKBatteryStatusConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKBatteryStatusData; + +@SuppressWarnings("unused") +public class SKBatteryStatus extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKBatteryStatus.class.getSimpleName(); + + // Last data sensed + private int mLastLevelSensed = Integer.MAX_VALUE; + private int mLastScaleSensed = Integer.MAX_VALUE; + private int mLastTemperatureSensed = Integer.MAX_VALUE; + private int mLastVoltageSensed = Integer.MAX_VALUE; + private SKBatteryStatusData.SKBatteryPlugged mLastPluggedSensed = null; + private SKBatteryStatusData.SKBatteryStatus mLastStatusSensed = null; + private SKBatteryStatusData.SKBatteryHealth mLastHealthSensed = null; + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + + // Read Battery + int level = intent.getIntExtra("level", -1); + int scale = intent.getIntExtra("scale", -1); + int temperature = intent.getIntExtra("temperature", 0); + int voltage = intent.getIntExtra("voltage", 0); + int plugged = intent.getIntExtra("plugged", -1); + int status = intent.getIntExtra("status", 0); + int health = intent.getIntExtra("health", 0); + + // Build the data object + SKAbstractData data = new SKBatteryStatusData(System.currentTimeMillis(), level, scale, temperature, voltage, plugged, status, health); + + // Submit sensor data object + submitSensorData(data); + } + }; + + public SKBatteryStatus(final Context context, SKBatteryStatusConfiguration configuration) throws SKException { + super(context, SKSensorType.BATTERY_STATUS, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + registerLocalBroadcastManager(); + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + unregisterLocalBroadcastManager(); + + super.stopSensing(); + + // Clear last sensed values + mLastLevelSensed = Integer.MAX_VALUE; + mLastScaleSensed = Integer.MAX_VALUE; + mLastTemperatureSensed = Integer.MAX_VALUE; + mLastVoltageSensed = Integer.MAX_VALUE; + mLastPluggedSensed = null; + mLastStatusSensed = null; + mLastHealthSensed = null; + } + + private void registerLocalBroadcastManager() { + IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + mApplicationContext.registerReceiver(mBroadcastReceiver, filter); + } + + private void unregisterLocalBroadcastManager() { + mApplicationContext.unregisterReceiver(mBroadcastReceiver); + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKBatteryStatusConfiguration((SKBatteryStatusConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Only post when specific values changed + + // Cast into SKBatteryStatusData + SKBatteryStatusData batteryData = (SKBatteryStatusData)data; + + // Read values + int level = batteryData.getLevel(); + int scale = batteryData.getScale(); + int temperature = batteryData.getTemperature(); + int voltage = batteryData.getVoltage(); + SKBatteryStatusData.SKBatteryPlugged plugged = batteryData.getBatteryPlugged(); + SKBatteryStatusData.SKBatteryStatus status = batteryData.getBatteryStatus(); + SKBatteryStatusData.SKBatteryHealth health = batteryData.getBatteryHealth(); + + // Ignore Temperature and Voltage + boolean shouldPost = (mLastLevelSensed != level || + mLastScaleSensed != scale || + mLastPluggedSensed != plugged || + mLastStatusSensed != status || + mLastHealthSensed != health ); + + if (shouldPost) { + + // Save last sensed values + this.mLastLevelSensed = level; + this.mLastScaleSensed = scale; + this.mLastTemperatureSensed = temperature; + this.mLastVoltageSensed = voltage; + this.mLastPluggedSensed = plugged; + this.mLastStatusSensed = status; + this.mLastHealthSensed = health; + } + + return shouldPost; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBeaconProximity.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBeaconProximity.java new file mode 100644 index 0000000..8eb7f3d --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBeaconProximity.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2016. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.RemoteException; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.altbeacon.beacon.Beacon; +import org.altbeacon.beacon.BeaconConsumer; +import org.altbeacon.beacon.BeaconManager; +import org.altbeacon.beacon.BeaconParser; +import org.altbeacon.beacon.Identifier; +import org.altbeacon.beacon.RangeNotifier; +import org.altbeacon.beacon.Region; +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKExceptionErrorCode; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKBeaconProximityConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKBeaconProximityConfiguration.SKBeaconType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKBeaconProximityCollectionData; +import org.sensingkit.sensingkitlib.data.SKBeaconProximityData; + +import java.util.ArrayList; + +@SuppressWarnings("ResourceType") +public class SKBeaconProximity extends SKAbstractSensor implements BeaconConsumer { + + @SuppressWarnings("unused") + private static final String TAG = SKBeaconProximity.class.getSimpleName(); + + private static final String BEACON_RANGING_IDENTIFIER = "org.sensingkit.beaconRangingIdentifier"; + + private BeaconManager mBeaconManager; + private Region mRegion; + + private final RangeNotifier mRangeNotifier = (beacons, region) -> { + + if (beacons.size() > 0) { + + // Get the timestamp + long timestamp = System.currentTimeMillis(); + + // Create the SKBeaconProximityData objects and add them to a new list + ArrayList deviceData = new ArrayList<>(beacons.size()); + + for (Beacon beacon : beacons) { + deviceData.add(new SKBeaconProximityData(timestamp, beacon)); + } + + // Build the data object + SKAbstractData data = new SKBeaconProximityCollectionData(timestamp, deviceData); + + // Submit sensor data object + submitSensorData(data); + } + }; + + public SKBeaconProximity(final @NonNull Context context, final @NonNull SKBeaconProximityConfiguration configuration) throws SKException { + super(context, SKSensorType.BEACON_PROXIMITY, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + + // Init BeaconManager + mBeaconManager = BeaconManager.getInstanceForApplication(mApplicationContext); + //BeaconManager.setDebug(true); // Debug only + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + + // Unbind first if needed + if (mBeaconManager.isBound(this)) { + mBeaconManager.unbind(this); + } + + // Cast the configuration instance + SKBeaconProximityConfiguration beaconProximityConfiguration = (SKBeaconProximityConfiguration) configuration; + + // Configure BeaconParsers + mBeaconManager.getBeaconParsers().clear(); + String layout = SKBeaconProximity.getBeaconLayout(beaconProximityConfiguration.getBeaconType()); + mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(layout)); + + // Configure Region + Identifier id1 = (beaconProximityConfiguration.getFilterId1() != null? Identifier.parse(beaconProximityConfiguration.getFilterId1()) : null); + Identifier id2 = (beaconProximityConfiguration.getFilterId2() != null? Identifier.parse(beaconProximityConfiguration.getFilterId2()) : null); + Identifier id3 = (beaconProximityConfiguration.getFilterId3() != null? Identifier.parse(beaconProximityConfiguration.getFilterId3()) : null); + mRegion = new Region(BEACON_RANGING_IDENTIFIER, id1, id2, id3); + + // Bind + mBeaconManager.bind(this); + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKBeaconProximityConfiguration((SKBeaconProximityConfiguration)mConfiguration); + } + + @Override + public void onBeaconServiceConnect() { + if (shouldDebugSensor()) {Log.i(TAG, "onBeaconServiceConnect [" + mSensorType.getName() + "]");} + } + + @Override + public Context getApplicationContext() { + return mApplicationContext; + } + + @Override + public void unbindService(final @NonNull ServiceConnection serviceConnection) { + if (shouldDebugSensor()) {Log.i(TAG, "unbindService [" + mSensorType.getName() + "]");} + + mApplicationContext.unbindService(serviceConnection); + } + + @Override + public boolean bindService(final @NonNull Intent intent, final @NonNull ServiceConnection serviceConnection, final int i) { + if (shouldDebugSensor()) {Log.i(TAG, "bindService [" + mSensorType.getName() + "]");} + + return mApplicationContext.bindService(intent, serviceConnection, i); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + // Register the callback + mBeaconManager.removeAllRangeNotifiers(); + mBeaconManager.addRangeNotifier(mRangeNotifier); + + try { + mBeaconManager.startRangingBeaconsInRegion(mRegion); + + } catch (RemoteException ex) { + Log.e(TAG, ex.toString()); + throw new SKException(TAG, "Beacon Proximity sensor could not be started on this device.", SKExceptionErrorCode.SENSOR_ERROR); + } + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + try { + mBeaconManager.stopRangingBeaconsInRegion(mRegion); + super.stopSensing(); + + } catch (RemoteException ex) { + throw new SKException(TAG, "Beacon Proximity sensor could not be stopped.", SKExceptionErrorCode.SENSOR_ERROR); + } + } + + @Override + public void sensorDeregistered() { + super.sensorDeregistered(); + + // Remove callback + mBeaconManager.removeRangeNotifier(mRangeNotifier); + + // Release sensor + mBeaconManager.unbind(this); + } + + private static String getBeaconLayout(final SKBeaconType beaconType) { + + switch (beaconType) { + + case ALTBEACON: + return BeaconParser.ALTBEACON_LAYOUT; + + case IBEACON: + return "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"; + + case EDDYSTONE_UID: + return BeaconParser.EDDYSTONE_UID_LAYOUT; + + //case EDDYSTONE_TLM: + // return BeaconParser.EDDYSTONE_TLM_LAYOUT; + + //case EDDYSTONE_URL: + // return BeaconParser.EDDYSTONE_URL_LAYOUT; + + default: + throw new RuntimeException(); + } + } + + @Override + public String[] getRequiredPermissions() { + return new String[]{Manifest.permission.ACCESS_FINE_LOCATION}; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKBluetooth.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBluetooth.java similarity index 59% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKBluetooth.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBluetooth.java index 513344d..58aa17b 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKBluetooth.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKBluetooth.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,42 +19,40 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; +import android.Manifest; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import androidx.annotation.NonNull; +import android.util.Log; import org.sensingkit.sensingkitlib.SKException; import org.sensingkit.sensingkitlib.SKExceptionErrorCode; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKBluetoothConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKBluetoothCollectionData; import org.sensingkit.sensingkitlib.data.SKBluetoothData; -import org.sensingkit.sensingkitlib.data.SKBluetoothDeviceData; import java.util.ArrayList; @SuppressWarnings("ResourceType") -public class SKBluetooth extends SKAbstractSensorModule { +public class SKBluetooth extends SKAbstractSensor { @SuppressWarnings("unused") - private static final String TAG = "SKBluetooth"; + private static final String TAG = SKBluetooth.class.getSimpleName(); - private final BluetoothAdapter mBluetoothAdapter; - private ArrayList mBluetoothDevices; + private BluetoothAdapter mBluetoothAdapter; + private ArrayList mBluetoothDevices; - public SKBluetooth(Context context) throws SKException { - super(context, SKSensorModuleType.BLUETOOTH); - - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mBluetoothDevices = new ArrayList<>(); - - if (mBluetoothAdapter == null) { - throw new SKException(TAG, "Bluetooth sensor module is not supported from the device.", SKExceptionErrorCode.UNKNOWN_ERROR); - } + public SKBluetooth(final @NonNull Context context, final @NonNull SKBluetoothConfiguration configuration) throws SKException { + super(context, SKSensorType.BLUETOOTH, configuration); } // Create a BroadcastReceiver for ACTION_FOUND and ACTION_DISCOVERY_FINISHED @@ -76,13 +74,13 @@ public void onReceive(Context context, Intent intent) { int rssi = (int) intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE); // Create SKBluetoothDevice and add to mBluetoothDevices array - SKBluetoothDeviceData deviceData = new SKBluetoothDeviceData(System.currentTimeMillis(), name, address, rssi); + SKBluetoothData deviceData = new SKBluetoothData(System.currentTimeMillis(), name, address, rssi); mBluetoothDevices.add(deviceData); } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { // Discovery Finished // Build the data object - SKAbstractData data = new SKBluetoothData(System.currentTimeMillis(), mBluetoothDevices); + SKAbstractData data = new SKBluetoothCollectionData(System.currentTimeMillis(), mBluetoothDevices); // Clean the arrayList mBluetoothDevices = new ArrayList<>(); @@ -97,7 +95,34 @@ public void onReceive(Context context, Intent intent) { }; @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mBluetoothDevices = new ArrayList<>(); + + if (mBluetoothAdapter == null) { + throw new SKException(TAG, "Bluetooth sensor is not supported from the device.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); + } + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKBluetoothConfiguration((SKBluetoothConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; @@ -105,16 +130,17 @@ protected boolean shouldPostSensorData(SKAbstractData data) { @Override public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} if (mBluetoothAdapter == null) { - throw new SKException(TAG, "Bluetooth sensor module is not supported from the device.", SKExceptionErrorCode.UNKNOWN_ERROR); + throw new SKException(TAG, "Bluetooth sensor is not supported from the device.", SKExceptionErrorCode.SENSOR_NOT_AVAILABLE); } if (!mBluetoothAdapter.isEnabled()) { - throw new SKException(TAG, "Bluetooth is not enabled.", SKExceptionErrorCode.UNKNOWN_ERROR); + throw new SKException(TAG, "Bluetooth is not enabled.", SKExceptionErrorCode.SENSOR_ERROR); } - this.isSensing = true; + super.startSensing(); registerLocalBroadcastManager(); @@ -123,14 +149,15 @@ public void startSensing() throws SKException { } @Override - public void stopSensing() { + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} // Stop Bluetooth Scanning mBluetoothAdapter.cancelDiscovery(); unregisterLocalBroadcastManager(); - this.isSensing = false; + super.stopSensing(); } private void registerLocalBroadcastManager() { @@ -145,4 +172,9 @@ private void registerLocalBroadcastManager() { private void unregisterLocalBroadcastManager() { mApplicationContext.unregisterReceiver(mReceiver); } + + @Override + public String[] getRequiredPermissions() { + return new String[]{Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN}; + } } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKGravity.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKGravity.java similarity index 56% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKGravity.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKGravity.java index ef89cf9..98ab542 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKGravity.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKGravity.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKGravityConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKGravityData; -public class SKGravity extends SKAbstractNativeSensorModule { +public class SKGravity extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKGravity"; + private static final String TAG = SKGravity.class.getSimpleName(); - public SKGravity(final Context context) throws SKException { - super(context, SKSensorModuleType.GRAVITY); + public SKGravity(final @NonNull Context context, final @NonNull SKGravityConfiguration configuration) throws SKException { + super(context, SKSensorType.GRAVITY, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { return new SKGravityData(System.currentTimeMillis(), event.values[0], event.values[1], event.values[2]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKGravityConfiguration((SKGravityConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKGyroscope.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKGyroscope.java similarity index 56% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKGyroscope.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKGyroscope.java index 370e841..4f6fd2b 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKGyroscope.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKGyroscope.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKGyroscopeConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKGyroscopeData; -public class SKGyroscope extends SKAbstractNativeSensorModule { +public class SKGyroscope extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKGyroscope"; + private static final String TAG = SKGyroscope.class.getSimpleName(); - public SKGyroscope(final Context context) throws SKException { - super(context, SKSensorModuleType.GYROSCOPE); + public SKGyroscope(final @NonNull Context context, final @NonNull SKGyroscopeConfiguration configuration) throws SKException { + super(context, SKSensorType.GYROSCOPE, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { return new SKGyroscopeData(System.currentTimeMillis(), event.values[0], event.values[1], event.values[2]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKGyroscopeConfiguration((SKGyroscopeConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKHumidity.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKHumidity.java new file mode 100644 index 0000000..3d94dfd --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKHumidity.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.Context; +import android.hardware.SensorEvent; +import androidx.annotation.NonNull; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKHumidityConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKHumidityData; + +public class SKHumidity extends SKAbstractNativeSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKHumidity.class.getSimpleName(); + + public SKHumidity(final @NonNull Context context, final @NonNull SKHumidityConfiguration configuration) throws SKException { + super(context, SKSensorType.HUMIDITY, configuration); + } + + @Override + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { + return new SKHumidityData(System.currentTimeMillis(), event.values[0]); + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKHumidityConfiguration((SKHumidityConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLight.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLight.java similarity index 61% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLight.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLight.java index df76ac0..03d6a53 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLight.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLight.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,35 +19,44 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKLightConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKLightData; -public class SKLight extends SKAbstractNativeSensorModule { +public class SKLight extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKLight"; + private static final String TAG = SKLight.class.getSimpleName(); private float lastLightSensed = Float.MAX_VALUE; - public SKLight(final Context context) throws SKException { - super(context, SKSensorModuleType.LIGHT); + public SKLight(final @NonNull Context context, final @NonNull SKLightConfiguration configuration) throws SKException { + super(context, SKSensorType.LIGHT, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { return new SKLightData(System.currentTimeMillis(), event.values[0]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKLightConfiguration((SKLightConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Only post when light value changes @@ -62,7 +71,7 @@ protected boolean shouldPostSensorData(SKAbstractData data) { return shouldPost; } - public void stopSensing() { + public void stopSensing() throws SKException { super.stopSensing(); diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLinearAcceleration.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLinearAcceleration.java similarity index 57% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLinearAcceleration.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLinearAcceleration.java index c2dfd01..dd4906f 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKLinearAcceleration.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLinearAcceleration.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKLinearAccelerationConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKLinearAccelerationData; -public class SKLinearAcceleration extends SKAbstractNativeSensorModule { +public class SKLinearAcceleration extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKLinearAcceleration"; + private static final String TAG = SKLinearAcceleration.class.getSimpleName(); - public SKLinearAcceleration(final Context context) throws SKException { - super(context, SKSensorModuleType.LINEAR_ACCELERATION); + public SKLinearAcceleration(final @NonNull Context context, final @NonNull SKLinearAccelerationConfiguration configuration) throws SKException { + super(context, SKSensorType.LINEAR_ACCELERATION, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { return new SKLinearAccelerationData(System.currentTimeMillis(), event.values[0], event.values[1], event.values[2]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKLinearAccelerationConfiguration((SKLinearAccelerationConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLocation.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLocation.java new file mode 100644 index 0000000..f3fd14e --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKLocation.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.location.Location; +import androidx.annotation.NonNull; +import android.util.Log; + +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationCallback; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationResult; +import com.google.android.gms.location.LocationServices; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKLocationConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKLocationData; + + +public class SKLocation extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKLocation.class.getSimpleName(); + + private FusedLocationProviderClient mFusedLocationClient; + private LocationRequest mLocationRequest; + + private final LocationCallback mLocationCallback = new LocationCallback() { + @Override + public void onLocationResult(LocationResult locationResult) { + super.onLocationResult(locationResult); + + if (locationResult == null) { + if (shouldDebugSensor()) {Log.i(TAG, "locationResult is null");} + return; + } + + // Build the data object + Location location = locationResult.getLastLocation(); + SKAbstractData data = new SKLocationData(System.currentTimeMillis(), location); + + // Submit sensor data object + submitSensorData(data); + } + }; + + public SKLocation(final @NonNull Context context, final @NonNull SKLocationConfiguration configuration) throws SKException { + super(context, SKSensorType.LOCATION, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context); + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + + // Cast the configuration instance + SKLocationConfiguration locationConfiguration = (SKLocationConfiguration)mConfiguration; + + // Configure the LocationRequest + mLocationRequest = LocationRequest.create(); + mLocationRequest.setPriority(locationConfiguration.getPriority().getPriorityCode()); + mLocationRequest.setInterval(locationConfiguration.getInterval()); + mLocationRequest.setFastestInterval(locationConfiguration.getFastestInterval()); + } + + @SuppressLint("MissingPermission") + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + // Start the request + mFusedLocationClient.requestLocationUpdates(mLocationRequest, + mLocationCallback, + null); + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + mFusedLocationClient.removeLocationUpdates(mLocationCallback); + + super.stopSensing(); + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKLocationConfiguration((SKLocationConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } + + @Override + public String[] getRequiredPermissions() { + return new String[]{Manifest.permission.ACCESS_FINE_LOCATION}; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKMagnetometer.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMagnetometer.java similarity index 55% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKMagnetometer.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMagnetometer.java index 4320821..962cc06 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKMagnetometer.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMagnetometer.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKMagnetometerConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKMagnetometerData; -public class SKMagnetometer extends SKAbstractNativeSensorModule { +public class SKMagnetometer extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKMagnetometer"; + private static final String TAG = SKMagnetometer.class.getSimpleName(); - public SKMagnetometer(final Context context) throws SKException { - super(context, SKSensorModuleType.MAGNETOMETER); + public SKMagnetometer(final @NonNull Context context, final @NonNull SKMagnetometerConfiguration configuration) throws SKException { + super(context, SKSensorType.MAGNETOMETER, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { return new SKMagnetometerData(System.currentTimeMillis(), event.values[0], event.values[1], event.values[2]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKMagnetometerConfiguration((SKMagnetometerConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMicrophone.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMicrophone.java new file mode 100644 index 0000000..84dd72c --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMicrophone.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.Manifest; +import android.content.Context; +import android.media.MediaRecorder; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKExceptionErrorCode; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKMicrophoneConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKMicrophoneData; + +import java.io.IOException; + +public class SKMicrophone extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKMicrophone.class.getSimpleName(); + + private MediaRecorder mMediaRecorder; + + public SKMicrophone(final @NonNull Context context, final @NonNull SKMicrophoneConfiguration configuration) throws SKException { + super(context, SKSensorType.MICROPHONE, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + + mMediaRecorder = new MediaRecorder(); + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + + // Cast the configuration instance + SKMicrophoneConfiguration microphoneConfiguration = (SKMicrophoneConfiguration)configuration; + + // Check if permission to file writing is granted + if (!microphoneConfiguration.getOutputDirectory().canWrite()) { + throw new SKException(TAG, "Microphone sensor does not have the permission to record in the following outputDirectory: " + + microphoneConfiguration.getRecordingPath() + ".", SKExceptionErrorCode.FILE_WRITER_PERMISSION_DENIED); + } + + // Check if file already exists + if (microphoneConfiguration.getRecordingFile().exists()) { + throw new SKException(TAG, "Filename already exists (" + + microphoneConfiguration.getRecordingFile() + ").", SKExceptionErrorCode.FILE_ALREADY_EXISTS); + } + + mMediaRecorder.reset(); + + // Set configuration + mMediaRecorder.setAudioSource(microphoneConfiguration.getAudioSource().getAudioSourceCode()); + mMediaRecorder.setOutputFormat(microphoneConfiguration.getOutputFormat().getOutputFormatCode()); + mMediaRecorder.setAudioEncoder(microphoneConfiguration.getAudioEncoder().getAudioEncoderCode()); + mMediaRecorder.setOutputFile(microphoneConfiguration.getRecordingPath()); + mMediaRecorder.setAudioEncodingBitRate(microphoneConfiguration.getBitrate()); + mMediaRecorder.setAudioSamplingRate(microphoneConfiguration.getSamplingRate()); + mMediaRecorder.setAudioChannels(microphoneConfiguration.getAudioChannels()); + + // Prepare for recording + try { + mMediaRecorder.prepare(); + } catch (IOException e) { + Log.e(TAG, e.getLocalizedMessage()); + throw new SKException(TAG, "Microphone sensor could not be prepared.", SKExceptionErrorCode.SENSOR_ERROR); + } + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKMicrophoneConfiguration((SKMicrophoneConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + mMediaRecorder.start(); + + // Build the data object + SKAbstractData data = new SKMicrophoneData(System.currentTimeMillis(), "Started"); + + // Submit sensor data object + submitSensorData(data); + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + // Stop recording + mMediaRecorder.stop(); + + // Build the data object + SKAbstractData data = new SKMicrophoneData(System.currentTimeMillis(), "Stopped"); + + // Submit sensor data object + submitSensorData(data); + + super.stopSensing(); + } + + @Override + public void sensorDeregistered() { + super.sensorDeregistered(); + + // Release sensor + mMediaRecorder.reset(); + mMediaRecorder.release(); + } + + @Override + public String[] getRequiredPermissions() { + return new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMotionActivity.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMotionActivity.java new file mode 100644 index 0000000..d553327 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMotionActivity.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.annotation.SuppressLint; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import androidx.annotation.NonNull; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import android.util.Log; + +import com.google.android.gms.location.ActivityRecognition; +import com.google.android.gms.location.ActivityRecognitionClient; +import com.google.android.gms.location.ActivityTransition; +import com.google.android.gms.location.ActivityTransitionRequest; +import com.google.android.gms.location.DetectedActivity; +import com.google.android.gms.tasks.Task; + + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKMotionActivityConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKMotionActivityData; + +import java.util.ArrayList; +import java.util.List; + +public class SKMotionActivity extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKMotionActivity.class.getSimpleName(); + + private ActivityRecognitionClient mActivityRecognitionClient; + private PendingIntent mActivityRecognitionPendingIntent; + private List mRegisteredTransitions; + private LocalBroadcastManager mLocalBroadcastManager; + + public SKMotionActivity(final @NonNull Context context, final @NonNull SKMotionActivityConfiguration configuration) throws SKException { + super(context, SKSensorType.MOTION_ACTIVITY, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + + mActivityRecognitionClient = ActivityRecognition.getClient(mApplicationContext); + mLocalBroadcastManager = LocalBroadcastManager.getInstance(mApplicationContext); + + Intent intent = new Intent(mApplicationContext, SKMotionActivityIntentService.class); + mActivityRecognitionPendingIntent = PendingIntent.getService(mApplicationContext, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + + // Cast the configuration instance + SKMotionActivityConfiguration motionActivityConfiguration = (SKMotionActivityConfiguration)mConfiguration; + + // update transitions + mRegisteredTransitions = buildTransitions(motionActivityConfiguration); + } + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + + int activityType = intent.getIntExtra("activityType", -1); + int transitionType = intent.getIntExtra("transitionType", -1); + //long timestamp = intent.getLongExtra("elapsedRealTimeNanos", -1); // TODO: fix + + // Build the data object + SKAbstractData data = new SKMotionActivityData(System.currentTimeMillis(), activityType, transitionType); + + // Submit sensor data object + submitSensorData(data); + } + }; + + private @NonNull List buildTransitions(final @NonNull SKMotionActivityConfiguration configuration) { + + // reset list + List transitions = new ArrayList<>(); + + if (configuration.getTrackStationary()) { + registerTrackedActivity(transitions, DetectedActivity.STILL); + } + + if (configuration.getTrackWalking()) { + registerTrackedActivity(transitions, DetectedActivity.WALKING); + } + + if (configuration.getTrackRunning()) { + registerTrackedActivity(transitions, DetectedActivity.RUNNING); + } + + if (configuration.getTrackAutomotive()) { + registerTrackedActivity(transitions, DetectedActivity.IN_VEHICLE); + } + + if (configuration.getTrackCycling()) { + registerTrackedActivity(transitions, DetectedActivity.ON_BICYCLE); + } + + return transitions; + } + + private void registerTrackedActivity(@NonNull List transitions, final int activity) { + if (shouldDebugSensor()) {Log.i(TAG, "registerTrackedActivity");} + + transitions.add( + new ActivityTransition.Builder() + .setActivityType(activity) + .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) + .build()); + + transitions.add( + new ActivityTransition.Builder() + .setActivityType(activity) + .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) + .build()); + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + // Register Receiver + IntentFilter filter = new IntentFilter(SKMotionActivityIntentService.ACTIVITY_TRANSITION_ACTION); + mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, filter); + + assert(mRegisteredTransitions != null); + ActivityTransitionRequest request = new ActivityTransitionRequest(mRegisteredTransitions); + + @SuppressLint("MissingPermission") + Task task = mActivityRecognitionClient.requestActivityTransitionUpdates(request, mActivityRecognitionPendingIntent); + + task.addOnSuccessListener( + result -> { + // Handle success + } + ); + + task.addOnFailureListener( + e -> Log.e(TAG, e.getMessage()) + ); + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + @SuppressLint("MissingPermission") + Task task = mActivityRecognitionClient.removeActivityTransitionUpdates(mActivityRecognitionPendingIntent); + + task.addOnSuccessListener( + result -> mActivityRecognitionPendingIntent.cancel()); + + task.addOnFailureListener( + e -> Log.e(TAG, e.getMessage())); + + // Unregister receiver + this.mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver); + + super.stopSensing(); + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKMotionActivityConfiguration((SKMotionActivityConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMotionActivityIntentService.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMotionActivityIntentService.java new file mode 100644 index 0000000..194f2cb --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKMotionActivityIntentService.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.app.IntentService; +import android.content.Intent; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import com.google.android.gms.location.ActivityTransitionEvent; +import com.google.android.gms.location.ActivityTransitionResult; + +public class SKMotionActivityIntentService extends IntentService { + + public static final String ACTIVITY_TRANSITION_ACTION = "org.sensingkit.SensingKit-Android.SKMotionActivityIntentService"; + + @SuppressWarnings("unused") + private static final String TAG = SKMotionActivityIntentService.class.getSimpleName(); + + private final LocalBroadcastManager mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); + + public SKMotionActivityIntentService() { + + // Set the label for the service's background thread + super("SKMotionActivityIntentService"); + } + + @Override + protected void onHandleIntent(final Intent intent) { + + if (intent == null) { + return; + } + + // If the intent contains an update + if (ActivityTransitionResult.hasResult(intent)) { + + // Get the update + ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent); + + if (result == null) { + return; + } + + for (ActivityTransitionEvent event : result.getTransitionEvents()) { + // chronological sequence of events. + + Intent i = new Intent(ACTIVITY_TRANSITION_ACTION); + i.putExtra("activityType", event.getActivityType()); + i.putExtra("transitionType", event.getTransitionType()); + i.putExtra("elapsedRealTimeNanos", event.getElapsedRealTimeNanos()); + + // send the broadcast to the SKMotionActivity.BroadcastReceiver + mLocalBroadcastManager.sendBroadcast(i); + } + } + } +} \ No newline at end of file diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKNotification.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKNotification.java new file mode 100644 index 0000000..b001df1 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKNotification.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2017. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKNotificationConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKNotificationData; + +public class SKNotification extends SKAbstractSensor { + + @SuppressWarnings("unused") + private static final String TAG = SKNotification.class.getSimpleName(); + + private final BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + + if (isSensing) { + + // Get properties + String actionType = intent.getStringExtra("actionType"); + long postTime = intent.getLongExtra("postTime", -1); + String packageName = intent.getStringExtra("packageName"); + + // Build the data object + SKAbstractData data = new SKNotificationData(postTime, actionType, packageName); + + // Submit sensor data object + submitSensorData(data); + } + + } + }; + + public SKNotification(final @NonNull Context context, final @NonNull SKNotificationConfiguration configuration) throws SKException { + super(context, SKSensorType.NOTIFICATION, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKNotificationConfiguration((SKNotificationConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + // Register Receiver + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { + IntentFilter filter = new IntentFilter(SKNotificationListenerService.NOTIFICATION_ACTION); + mApplicationContext.registerReceiver(mNotificationReceiver, filter); + } + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + // Unregister receiver + mApplicationContext.unregisterReceiver(mNotificationReceiver); + + super.stopSensing(); + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKNotificationListenerService.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKNotificationListenerService.java new file mode 100644 index 0000000..13b25de --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKNotificationListenerService.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit https://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.Intent; +import android.os.Build; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import android.util.Log; + +@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) +public class SKNotificationListenerService extends NotificationListenerService { + + public static final String NOTIFICATION_ACTION = "org.sensingkit.SensingKit-Android.SKNotificationListenerService"; + + @SuppressWarnings("unused") + private static final String TAG = SKNotificationListenerService.class.getSimpleName(); + + @Override + public void onListenerConnected() { + Log.i(TAG, "Connected!"); + } + + @Override + public void onNotificationPosted(final StatusBarNotification sbn) { + sendNotification("posted", sbn); + } + + @Override + public void onNotificationRemoved(final StatusBarNotification sbn) { + sendNotification("removed", sbn); + } + + private void sendNotification(final @NonNull String actionType, final @NonNull StatusBarNotification sbn) { + + // Build intent + Intent i = new Intent(NOTIFICATION_ACTION); + i.putExtra("actionType", actionType); + i.putExtra("postTime", sbn.getPostTime()); + i.putExtra("packageName", sbn.getPackageName()); + + // send the broadcast to the SKNotification.NotificationServiceReceiver + this.sendBroadcast(i); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKRotation.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKRotation.java similarity index 60% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKRotation.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKRotation.java index 82b359f..bd74288 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKRotation.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKRotation.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,28 +19,31 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKRotationConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKRotationData; -public class SKRotation extends SKAbstractNativeSensorModule { +public class SKRotation extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKRotation"; + private static final String TAG = SKRotation.class.getSimpleName(); - public SKRotation(final Context context) throws SKException { - super(context, SKSensorModuleType.ROTATION); + public SKRotation(final Context context, final SKRotationConfiguration configuration) throws SKException { + super(context, SKSensorType.ROTATION, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { if (event.values.length >= 6) { return new SKRotationData(System.currentTimeMillis(), event.values[0], event.values[1], event.values[2], event.values[3], event.values[4]); } @@ -50,7 +53,13 @@ protected SKAbstractData buildData(SensorEvent event) } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKRotationConfiguration((SKRotationConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKScreenStatus.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKScreenStatus.java new file mode 100644 index 0000000..9f2ac97 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKScreenStatus.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import androidx.annotation.NonNull; +import android.util.Log; + +import org.sensingkit.sensingkitlib.SKException; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKScreenStatusConfiguration; +import org.sensingkit.sensingkitlib.data.SKAbstractData; +import org.sensingkit.sensingkitlib.data.SKScreenStatusData; + +public class SKScreenStatus extends SKAbstractSensor { + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + + // Read Status + int status; + + String action = intent.getAction(); + + if (action == null) { + status = SKScreenStatusData.SCREEN_UNKNOWN; + } + else { + switch (action) { + case Intent.ACTION_SCREEN_OFF: + status = SKScreenStatusData.SCREEN_OFF; + break; + case Intent.ACTION_SCREEN_ON: + status = SKScreenStatusData.SCREEN_ON; + break; + case Intent.ACTION_USER_PRESENT: + status = SKScreenStatusData.SCREEN_UNLOCKED; + break; + default: + status = SKScreenStatusData.SCREEN_UNKNOWN; + break; + } + } + + // Build the data object + SKAbstractData data = new SKScreenStatusData(System.currentTimeMillis(), status); + + // Submit sensor data object + submitSensorData(data); + } + }; + + @SuppressWarnings("unused") + private static final String TAG = SKScreenStatus.class.getSimpleName(); + + public SKScreenStatus(final @NonNull Context context, final @NonNull SKScreenStatusConfiguration configuration) throws SKException { + super(context, SKSensorType.SCREEN_STATUS, configuration); + } + + @Override + protected void initSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "initSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + + // configure sensor + updateSensor(context, sensorType, configuration); + } + + @Override + protected void updateSensor(@NonNull Context context, SKSensorType sensorType, @NonNull SKConfiguration configuration) { + if (shouldDebugSensor()) {Log.i(TAG, "updateSensing [" + mSensorType.getName() + "]");} + // Not required for this type of sensor + } + + @Override + @NonNull + public SKConfiguration getConfiguration() { + return new SKScreenStatusConfiguration((SKScreenStatusConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { + + // Always post sensor data + return true; + } + + @Override + public void startSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "startSensing [" + mSensorType.getName() + "]");} + + super.startSensing(); + + registerLocalBroadcastManager(); + } + + @Override + public void stopSensing() throws SKException { + if (shouldDebugSensor()) {Log.i(TAG, "stopSensing [" + mSensorType.getName() + "]");} + + unregisterLocalBroadcastManager(); + + super.stopSensing(); + } + + private void registerLocalBroadcastManager() { + + // Register for SCREEN_STATUS ON, OFF and UNLOCKED (USER_PRESENT) notifications + mApplicationContext.registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON)); + mApplicationContext.registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF)); + mApplicationContext.registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_USER_PRESENT)); + } + + private void unregisterLocalBroadcastManager() { + mApplicationContext.unregisterReceiver(mBroadcastReceiver); + } +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKSensorModuleInterface.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKSensor.java similarity index 50% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKSensorModuleInterface.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKSensor.java index 94bbc18..3d01b86 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKSensorModuleInterface.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKSensor.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,22 +19,33 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; + +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorDataListener; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorDataHandler; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; @SuppressWarnings("unused") -public interface SKSensorModuleInterface { +public interface SKSensor { - SKSensorModuleType getSensorType(); + SKSensorType getSensorType(); + @NonNull String getSensorName(); void startSensing() throws SKException; - void stopSensing(); + void stopSensing() throws SKException; boolean isSensing(); - void subscribeSensorDataListener(SKSensorDataListener callback) throws SKException; - void unsubscribeSensorDataListener(SKSensorDataListener callback) throws SKException; - void unsubscribeAllSensorDataListeners() throws SKException; + void subscribeSensorDataHandler(final @NonNull SKSensorDataHandler handler) throws SKException; + void unsubscribeSensorDataHandler(final @NonNull SKSensorDataHandler handler) throws SKException; + void unsubscribeAllSensorDataHandlers(); + + void setConfiguration(final @NonNull SKConfiguration configuration) throws SKException; + @NonNull SKConfiguration getConfiguration(); + + void sensorDeregistered(); + + String[] getRequiredPermissions(); } diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKSensorUtilities.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKSensorUtilities.java new file mode 100644 index 0000000..0133aa2 --- /dev/null +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKSensorUtilities.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk + * + * This file is part of SensingKit-Android library. + * For more information, please visit http://www.sensingkit.org + * + * SensingKit-Android is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SensingKit-Android is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with SensingKit-Android. If not, see . + */ + +package org.sensingkit.sensingkitlib.sensors; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; +import androidx.annotation.NonNull; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.data.*; + +@SuppressWarnings("WeakerAccess") +public final class SKSensorUtilities { + + @SuppressWarnings("unused") + private static final String TAG = SKSensorUtilities.class.getSimpleName(); + + /** + * Return a string with a CSV formatted header that describes the data of the particular sensor. + */ + static @NonNull + public String csvHeaderForSensor(final SKSensorType sensorType) { + + switch (sensorType) { + + case ACCELEROMETER: + return SKAccelerometerData.csvHeader(); + + case GRAVITY: + return SKGravityData.csvHeader(); + + case LINEAR_ACCELERATION: + return SKLinearAccelerationData.csvHeader(); + + case GYROSCOPE: + return SKGyroscopeData.csvHeader(); + + case ROTATION: + return SKRotationData.csvHeader(); + + case MAGNETOMETER: + return SKMagnetometerData.csvHeader(); + + case AMBIENT_TEMPERATURE: + return SKAmbientTemperatureData.csvHeader(); + + case STEP_DETECTOR: + return SKStepDetectorData.csvHeader(); + + case STEP_COUNTER: + return SKStepCounterData.csvHeader(); + + case LIGHT: + return SKLightData.csvHeader(); + + case LOCATION: + return SKLocationData.csvHeader(); + + case MOTION_ACTIVITY: + return SKMotionActivityData.csvHeader(); + + case BATTERY_STATUS: + return SKBatteryStatusData.csvHeader(); + + case SCREEN_STATUS: + return SKScreenStatusData.csvHeader(); + + case MICROPHONE: + return SKMicrophoneData.csvHeader(); + + case AUDIO_LEVEL: + return SKAudioLevelData.csvHeader(); + + case BLUETOOTH: + return SKBluetoothData.csvHeader(); + + case BEACON_PROXIMITY: + return SKBeaconProximityData.csvHeader(); + + case HUMIDITY: + return SKHumidityData.csvHeader(); + + case BAROMETER: + return SKBarometerData.csvHeader(); + + case NOTIFICATION: + return SKNotificationData.csvHeader(); + + default: + throw new RuntimeException("csvHeader for Sensor '" + sensorType.getName() + "' is missing."); + } + } + + /** + * A Boolean value that indicates whether the sensor is available on the device. + * + * @param sensorType The type of the sensor that will be checked. + * + * @return TRUE if the sensor is available on the device, or FALSE if it is not. + */ + public static boolean isSensorAvailable(final SKSensorType sensorType, final @NonNull Context context) { + + // Get package manager + PackageManager packageManager = context.getPackageManager(); + + switch (sensorType) { + + case ACCELEROMETER: + case GRAVITY: + case LINEAR_ACCELERATION: + return packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER); + + case GYROSCOPE: + case ROTATION: + return packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_GYROSCOPE); + + case MAGNETOMETER: + return packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS); + + case AMBIENT_TEMPERATURE: + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && + packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_AMBIENT_TEMPERATURE); + + case STEP_DETECTOR: + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && + packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR); + + case STEP_COUNTER: + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && + packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER); + + case LIGHT: + return packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_LIGHT); + + case LOCATION: + return packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION) && + isGooglePlayServicesAvailable(context); + + case MOTION_ACTIVITY: + return isGooglePlayServicesAvailable(context); + + case BATTERY_STATUS: + case SCREEN_STATUS: + return true; + + case MICROPHONE: + case AUDIO_LEVEL: + return packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE); + + case BLUETOOTH: + return packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); + + case BEACON_PROXIMITY: + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && + packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); + + case HUMIDITY: + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && + packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_RELATIVE_HUMIDITY); + + case BAROMETER: + return packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_BAROMETER); + + case NOTIFICATION: + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; + + default: + throw new RuntimeException("Availability check for Sensor '" + sensorType.getName() + "' is missing."); + } + } + + public static boolean isGooglePlayServicesAvailable(final @NonNull Context context) { + GoogleApiAvailability api = GoogleApiAvailability.getInstance(); + int code = api.isGooglePlayServicesAvailable(context); + return code == ConnectionResult.SUCCESS; + } + +} diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKStepCounter.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKStepCounter.java similarity index 54% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKStepCounter.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKStepCounter.java index 8513a5c..751f962 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKStepCounter.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKStepCounter.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKStepCounterConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKStepCounterData; -public class SKStepCounter extends SKAbstractNativeSensorModule { +public class SKStepCounter extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKStepCounter"; + private static final String TAG = SKStepCounter.class.getSimpleName(); - public SKStepCounter(final Context context) throws SKException { - super(context, SKSensorModuleType.STEP_COUNTER); + public SKStepCounter(final @NonNull Context context, final @NonNull SKStepCounterConfiguration configuration) throws SKException { + super(context, SKSensorType.STEP_COUNTER, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { - return new SKStepCounterData(System.currentTimeMillis(), event.values[0]); + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { + return new SKStepCounterData(System.currentTimeMillis(), (int)event.values[0]); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKStepCounterConfiguration((SKStepCounterConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKStepDetector.java b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKStepDetector.java similarity index 54% rename from SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKStepDetector.java rename to SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKStepDetector.java index f6c7d1f..763917c 100644 --- a/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/modules/SKStepDetector.java +++ b/SensingKitLib/src/main/java/org/sensingkit/sensingkitlib/sensors/SKStepDetector.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014. Queen Mary University of London - * Kleomenis Katevas, k.katevas@qmul.ac.uk + * Copyright (c) 2014. Kleomenis Katevas + * Kleomenis Katevas, k.katevas@imperial.ac.uk * * This file is part of SensingKit-Android library. * For more information, please visit http://www.sensingkit.org @@ -19,33 +19,42 @@ * along with SensingKit-Android. If not, see . */ -package org.sensingkit.sensingkitlib.modules; +package org.sensingkit.sensingkitlib.sensors; import android.content.Context; import android.hardware.SensorEvent; +import androidx.annotation.NonNull; import org.sensingkit.sensingkitlib.SKException; -import org.sensingkit.sensingkitlib.SKSensorModuleType; +import org.sensingkit.sensingkitlib.SKSensorType; +import org.sensingkit.sensingkitlib.configuration.SKConfiguration; +import org.sensingkit.sensingkitlib.configuration.SKStepDetectorConfiguration; import org.sensingkit.sensingkitlib.data.SKAbstractData; import org.sensingkit.sensingkitlib.data.SKStepDetectorData; -public class SKStepDetector extends SKAbstractNativeSensorModule { +public class SKStepDetector extends SKAbstractNativeSensor { @SuppressWarnings("unused") - private static final String TAG = "SKStepDetector"; + private static final String TAG = SKStepDetector.class.getSimpleName(); - public SKStepDetector(final Context context) throws SKException { - super(context, SKSensorModuleType.STEP_DETECTOR); + public SKStepDetector(final @NonNull Context context, final @NonNull SKStepDetectorConfiguration configuration) throws SKException { + super(context, SKSensorType.STEP_DETECTOR, configuration); } @Override - protected SKAbstractData buildData(SensorEvent event) - { + @NonNull + protected SKAbstractData buildData(final @NonNull SensorEvent event) { return new SKStepDetectorData(System.currentTimeMillis()); } @Override - protected boolean shouldPostSensorData(SKAbstractData data) { + @NonNull + public SKConfiguration getConfiguration() { + return new SKStepDetectorConfiguration((SKStepDetectorConfiguration)mConfiguration); + } + + @Override + protected boolean shouldPostSensorData(final @NonNull SKAbstractData data) { // Always post sensor data return true; diff --git a/build.gradle b/build.gradle index 9405f3f..842090f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,17 +3,49 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' + classpath 'com.android.tools.build:gradle:3.5.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } +plugins { + id "com.jfrog.bintray" version "1.7" +} + +bintray { + user = System.getenv('bintray.user') + key = System.getenv('bintray.api.key') + pkg { + repo = 'SensingKit-Android' + name = 'SensingKit-Android' + userOrg = 'SensingKit' + licenses = ['LGPL-3.0'] + vcsUrl = 'https://github.com/SensingKit/SensingKit-Android.git' + version { + name = project.version + released = new Date() + gpg { + sign = true + passphrase = System.getenv('bintray.gpg.password') + } + mavenCentralSync { + sync = true + user = System.getenv('maven.user') + password = System.getenv('maven.password') + close = '1' + } + } + } +} + allprojects { repositories { jcenter() + maven { url "https://maven.google.com" } } } diff --git a/gradle.properties b/gradle.properties index 5d08ba7..dde311d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,6 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 18f81f8..f5ab9ee 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Dec 04 21:39:37 GMT 2014 +#Wed Aug 21 08:38:09 EEST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip