├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── styles.xml │ │ │ ├── attrs.xml │ │ │ ├── dimens.xml │ │ │ ├── themes.xml │ │ │ ├── colors.xml │ │ │ └── strings.xml │ │ ├── drawable-hdpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── drawable-ldpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── drawable-mdpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── drawable-tvdpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── drawable-xhdpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── drawable-xxhdpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── drawable-xxxhdpi │ │ │ ├── sensors2osc.png │ │ │ └── sensors2osc_notification.png │ │ ├── values-v21 │ │ │ └── styles.xml │ │ ├── values-v35 │ │ │ └── styles.xml │ │ ├── values-watch │ │ │ └── dimens.xml │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ ├── activity_multi_touch.xml │ │ │ ├── activity_settings.xml │ │ │ ├── help_sensor.xml │ │ │ ├── sensor.xml │ │ │ ├── activity_start_up.xml │ │ │ ├── activity_about.xml │ │ │ └── activity_guide.xml │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ ├── menu │ │ │ └── start_up.xml │ │ ├── xml │ │ │ └── preferences.xml │ │ ├── xml-v26 │ │ │ └── preferences.xml │ │ ├── layout-watch │ │ │ └── activity_start_up.xml │ │ ├── values-night │ │ │ └── themes.xml │ │ ├── values-nb-rNO │ │ │ └── strings.xml │ │ ├── values-pt │ │ │ └── strings.xml │ │ ├── values-ja │ │ │ └── strings.xml │ │ ├── values-tr │ │ │ └── strings.xml │ │ ├── values-fr │ │ │ └── strings.xml │ │ ├── values-ta │ │ │ └── strings.xml │ │ ├── values-de │ │ │ └── strings.xml │ │ └── values-nl │ │ │ └── strings.xml │ │ ├── java │ │ └── org │ │ │ └── sensors2 │ │ │ └── osc │ │ │ ├── dispatch │ │ │ ├── OscCommunication.java │ │ │ ├── Bundling.java │ │ │ ├── OscConfiguration.java │ │ │ ├── SensorConfiguration.java │ │ │ ├── OscHandler.java │ │ │ └── OscDispatcher.java │ │ │ ├── bluetoothSensors │ │ │ ├── sensorHandlers │ │ │ │ ├── ServiceMeasurementUUID.java │ │ │ │ ├── SensorHandler.java │ │ │ │ ├── models │ │ │ │ │ └── BluetoothOscData.java │ │ │ │ ├── GeneralHandler.java │ │ │ │ ├── BaseSensorHandler.java │ │ │ │ ├── BarometricPressureHandler.java │ │ │ │ ├── CyclingCadenceHandler.java │ │ │ │ ├── HeartRateHandler.java │ │ │ │ ├── RunningSpeedAndCadenceHandler.java │ │ │ │ ├── CyclingPowerHandler.java │ │ │ │ └── CyclingDistanceSpeedHandler.java │ │ │ └── BluetoothConnectionManager.java │ │ │ ├── fragments │ │ │ ├── MultiTouchFragment.java │ │ │ ├── SettingsFragment.java │ │ │ ├── HelpSensorFragment.java │ │ │ ├── StartupFragment.java │ │ │ └── SensorFragment.java │ │ │ ├── sensors │ │ │ └── Settings.java │ │ │ ├── activities │ │ │ ├── SettingsActivity.java │ │ │ ├── AboutActivity.java │ │ │ └── GuideActivity.java │ │ │ ├── views │ │ │ └── MultiTouchView.java │ │ │ └── preferences │ │ │ └── AutoCompletePreference.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── fastlane └── metadata │ └── android │ ├── en-US │ ├── changelogs │ │ ├── 1.txt │ │ ├── 8.txt │ │ ├── 2.txt │ │ ├── 6.txt │ │ ├── 9.txt │ │ ├── 12.txt │ │ ├── 11.txt │ │ ├── 13.txt │ │ ├── 5.txt │ │ ├── 7.txt │ │ ├── 3.txt │ │ └── 4.txt │ ├── short-description.txt │ ├── images │ │ ├── icon.png │ │ ├── featureGraphic.png │ │ └── phoneScreenshots │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ └── 6.png │ └── full-description.txt │ └── de-DE │ ├── short-description.txt │ └── full-description.txt ├── graphic ├── sensors2osc.png └── sensors2osc_notification.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── example ├── python │ └── receiver.py └── puredata │ └── osc-test.pd ├── gradle.properties ├── README.md ├── LICENSE ├── Changelog.md ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/1.txt: -------------------------------------------------------------------------------- 1 | - First release. 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/short-description.txt: -------------------------------------------------------------------------------- 1 | Sensordaten über Open Sound Control (OSC) senden 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/8.txt: -------------------------------------------------------------------------------- 1 | - Small changes to colors 2 | - Update preview images 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short-description.txt: -------------------------------------------------------------------------------- 1 | Send sensor data via Open Sound Control (OSC) 2 | -------------------------------------------------------------------------------- /graphic/sensors2osc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensorApps/Sensors2OSC/HEAD/graphic/sensors2osc.png -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values-v35/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/5.txt: -------------------------------------------------------------------------------- 1 | - Option to block screen for blacking 2 | - Bugfixes: 3 | * Android 12: Sending data does not crash anymore. 4 | * Android 12: Editing host and port does not crash anymore. 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full-description.txt: -------------------------------------------------------------------------------- 1 | Read sensor data from your phone and send them to a receiver via Open Sound 2 | Control (OSC). 3 | 4 | Typical use case is controlling a music application from your phone or tablet. 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/full-description.txt: -------------------------------------------------------------------------------- 1 | Sensordaten aus dem Telefon auslesen und an einen Empfänger über Open 2 | Sound Control (OSC) senden. 3 | 4 | Ein Standard-Anwendungsfall ist das Steuern einer Musik-Anwendung vom 5 | Telefon oder Tablet aus. 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/7.txt: -------------------------------------------------------------------------------- 1 | - Use dark mode for older devices. 2 | 3 | - Bugfixes: 4 | * Use theme colors for multitouch view. 5 | * Prevent crash on switching between day and night while background 6 | * Android 12: Prevent crash on setting to highest sensor rate 7 | -------------------------------------------------------------------------------- /app/src/main/res/values-watch/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 8dp 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Aug 24 00:49:21 CEST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 8dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/3.txt: -------------------------------------------------------------------------------- 1 | - Change of format: Instead of different messages for each dimension only one message with a list of float values is sent. 2 | - Change of format: NFC tag values are sent as strings instead of floats. 3 | - Views are rotatable. 4 | - Bugfixes: 5 | * Orientation is sent, if device does not have a dedicated sensor, but magnetic field and accelerometer are available. 6 | * Sensors are only listed once, even if device reports multiple versions of it. 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/4.txt: -------------------------------------------------------------------------------- 1 | - **breaking**: NFC tag values are removed. 2 | - **breaking**: Minimum required Android version is now 4.0.1. 3 | - Data is sent in background, screen can be turned off. 4 | - App rotation is disabled when sending data. 5 | - Autocomplete from history in settings. 6 | - Enable sending OSC as bundles in settings. 7 | - Added translations: 8 | * French 9 | * Dutch 10 | * Norwegian Bokmal 11 | - Bugfixes: 12 | * Altering settings does not reset sending state. 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_multi_touch.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle files 2 | .gradle/ 3 | build/ 4 | 5 | # Local configuration file (sdk path, etc) 6 | local.properties 7 | 8 | # Log/OS Files 9 | *.log 10 | 11 | # Android Studio generated files and folders 12 | captures/ 13 | .externalNativeBuild/ 14 | .cxx/ 15 | *.apk 16 | output.json 17 | 18 | # IntelliJ 19 | *.iml 20 | .idea/ 21 | misc.xml 22 | deploymentTargetDropDown.xml 23 | render.experimental.xml 24 | 25 | # Keystore files 26 | *.jks 27 | *.keystore 28 | 29 | # Google Services (e.g. APIs or Firebase) 30 | google-services.json 31 | 32 | # Android Profiling 33 | *.hprof 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/dispatch/OscCommunication.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.dispatch; 2 | 3 | import android.os.Looper; 4 | 5 | /** 6 | * Created by thomas on 31.03.15. 7 | */ 8 | public class OscCommunication extends Thread { 9 | private OscHandler handler; 10 | 11 | public OscCommunication(String name) { 12 | super(name); 13 | } 14 | 15 | @Override 16 | public void run() { 17 | Looper.prepare(); 18 | handler = new OscHandler(Looper.myLooper()); 19 | Looper.loop(); 20 | } 21 | 22 | public OscHandler getOscHandler() { 23 | return handler; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/bluetoothSensors/sensorHandlers/ServiceMeasurementUUID.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.bluetoothSensors.sensorHandlers; 2 | 3 | import java.util.UUID; 4 | 5 | public class ServiceMeasurementUUID { 6 | private final UUID serviceUUID; 7 | private final UUID measurementUUID; 8 | 9 | public ServiceMeasurementUUID(UUID serviceUUID, UUID measurementUUID){ 10 | this.serviceUUID = serviceUUID; 11 | this.measurementUUID = measurementUUID; 12 | } 13 | 14 | public UUID getMeasurementUUID() { 15 | return measurementUUID; 16 | } 17 | 18 | public UUID getServiceUUID() { 19 | return serviceUUID; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/thomas/bin/android-studio/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/bluetoothSensors/sensorHandlers/SensorHandler.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.bluetoothSensors.sensorHandlers; 2 | 3 | import android.bluetooth.BluetoothGatt; 4 | import android.bluetooth.BluetoothGattCharacteristic; 5 | 6 | import org.sensors2.osc.bluetoothSensors.sensorHandlers.models.BluetoothOscData; 7 | 8 | import java.util.List; 9 | 10 | public interface SensorHandler { 11 | List getServices(); 12 | BluetoothOscData getPayload(ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic); 13 | void addGatt(BluetoothGatt gatt); 14 | void removeGatt(BluetoothGatt gatt); 15 | void disconnect(); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/dispatch/Bundling.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.dispatch; 2 | 3 | /** 4 | * Created by thomas on 31.03.15. 5 | */ 6 | public final class Bundling { 7 | public static final String DIMENSIONS = "dimensions"; 8 | public static final String SENSOR_TYPE = "sensorType"; 9 | public static final String OSC_PREFIX = "oscPrefix"; 10 | public static final String NAME = "name"; 11 | public static final String SENSOR_NAME = "sensorName"; 12 | public static final String SENSOR_RANGE = "sensorRange"; 13 | public static final String RESOLUTION = "resolution"; 14 | public static final String VALUES = "values"; 15 | public static final String STRING_VALUE = "string_value"; 16 | public static final String OSC_PARAMETER = "oscParameter"; 17 | } -------------------------------------------------------------------------------- /app/src/main/res/menu/start_up.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 15 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/bluetoothSensors/sensorHandlers/models/BluetoothOscData.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.bluetoothSensors.sensorHandlers.models; 2 | 3 | import java.util.List; 4 | 5 | public class BluetoothOscData { 6 | private final String oscAddress; 7 | private final float[] data; 8 | 9 | public BluetoothOscData(String oscAddress, List data) { 10 | this.oscAddress = oscAddress; 11 | float[] floatArray = new float[data.size()]; 12 | int i = 0; 13 | for (Float f : data) { 14 | floatArray[i++] = (f != null ? f : Float.NaN); // Or whatever default you want. 15 | } 16 | this.data = floatArray; 17 | } 18 | 19 | public float[] getData() { 20 | return data; 21 | } 22 | 23 | public String getOscAddress() { 24 | return oscAddress; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/bluetoothSensors/sensorHandlers/GeneralHandler.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.bluetoothSensors.sensorHandlers; 2 | 3 | import android.bluetooth.BluetoothGattCharacteristic; 4 | import android.os.Build; 5 | 6 | import org.sensors2.osc.bluetoothSensors.sensorHandlers.models.BluetoothOscData; 7 | 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | import androidx.annotation.RequiresApi; 12 | 13 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) 14 | public class GeneralHandler extends BaseSensorHandler implements SensorHandler{ 15 | @Override 16 | public List getServices() { 17 | return Collections.emptyList(); 18 | } 19 | 20 | @Override 21 | public BluetoothOscData getPayload(ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/python/receiver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Prerequisits for Ubuntu 4 | # sudo apt-get install python3-wheel 5 | # sudo pip3 install python-osc 6 | 7 | from pythonosc import dispatcher, osc_server 8 | from socket import AF_INET, SOCK_DGRAM, socket 9 | 10 | def get_ip_address(): 11 | s = socket(AF_INET, SOCK_DGRAM) 12 | s.connect(("8.8.8.8", 80)) 13 | address = s.getsockname()[0] 14 | s.close() 15 | return address 16 | 17 | def handler(addr, *message): 18 | output = '{:32}'.format(addr) 19 | for i in range(len(message)): 20 | output += ' {:8.3f}'.format(message[i]) 21 | print(output) 22 | 23 | if __name__ == "__main__": 24 | address = get_ip_address() 25 | port = 9000 26 | 27 | dispatcher = dispatcher.Dispatcher() 28 | dispatcher.map('/*', handler) 29 | 30 | server = osc_server.ThreadingOSCUDPServer((address, port), dispatcher) 31 | print('OSC server started on {}:{}'.format(address, port)) 32 | server.serve_forever() 33 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/bluetoothSensors/sensorHandlers/BaseSensorHandler.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.bluetoothSensors.sensorHandlers; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.bluetooth.BluetoothGatt; 5 | import android.os.Build; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import androidx.annotation.RequiresApi; 11 | 12 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) 13 | public abstract class BaseSensorHandler implements SensorHandler { 14 | final List gatts = new ArrayList<>(); 15 | @Override 16 | public void addGatt(BluetoothGatt gatt) { 17 | gatts.add(gatt); 18 | } 19 | 20 | @Override 21 | public void removeGatt(BluetoothGatt gatt) { 22 | gatts.remove(gatt); 23 | } 24 | 25 | @SuppressLint("MissingPermission") 26 | @Override 27 | public void disconnect() { 28 | for(BluetoothGatt gatt :gatts){ 29 | gatt.disconnect(); 30 | gatt.close(); 31 | } 32 | gatts.clear(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Settings specified in this file will override any Gradle settings 5 | # configured through the IDE. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | android.defaults.buildfeatures.buildconfig=true 20 | android.enableJetifier=true 21 | android.nonFinalResIds=false 22 | android.nonTransitiveRClass=false 23 | android.useAndroidX=true 24 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/fragments/MultiTouchFragment.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import org.sensors2.osc.R; 9 | import org.sensors2.osc.activities.StartUpActivity; 10 | 11 | import androidx.fragment.app.Fragment; 12 | 13 | public class MultiTouchFragment extends Fragment { 14 | 15 | // this is an arbitrary limit - if a device supports more than a 8 finger multi touch this could simply be increased 16 | // alternatively, this could be added as a variable to the settings activity 17 | public static final int MAX_POINTER_COUNT = 10; 18 | 19 | @Override 20 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 21 | View v = inflater.inflate(R.layout.activity_multi_touch, container, false); 22 | StartUpActivity activity = (StartUpActivity) getActivity(); 23 | v.findViewById(R.id.multi_touch_view).setOnTouchListener(activity); 24 | return v; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 35 5 | 6 | defaultConfig { 7 | applicationId "org.sensors2.osc" 8 | targetSdkVersion 35 9 | minSdkVersion 14 10 | versionCode 13 11 | versionName "0.9.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | dependenciesInfo { 21 | includeInApk false 22 | } 23 | lint { 24 | abortOnError false 25 | checkReleaseBuilds true 26 | } 27 | configurations.all { 28 | resolutionStrategy.force 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' 29 | } 30 | namespace 'org.sensors2.osc' 31 | } 32 | 33 | dependencies { 34 | implementation 'com.github.hoijui.JavaOSC:javaosc-core:javaosc-0.4' 35 | implementation 'org.apmem.tools:layouts:1.10@aar' 36 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 37 | // Do not upgrade, minSdk for >=1.7.0 must be at least 19 38 | implementation 'androidx.fragment:fragment:1.6.2' 39 | implementation 'com.github.SensorApps:Common:785223561e' 40 | implementation 'androidx.preference:preference:1.2.1' 41 | // Do not upgrade, minSdk for >=1.12.0 must be at least 19 42 | implementation 'com.google.android.material:material:1.11.0' 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/fragments/SettingsFragment.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.fragments; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.preference.PreferenceFragmentCompat; 8 | import android.view.View; 9 | 10 | import org.sensors2.osc.R; 11 | 12 | import androidx.preference.PreferenceGroupAdapter; 13 | import androidx.preference.PreferenceScreen; 14 | import androidx.preference.PreferenceViewHolder; 15 | import androidx.recyclerview.widget.RecyclerView.Adapter; 16 | 17 | public class SettingsFragment extends PreferenceFragmentCompat { 18 | @Override 19 | public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 20 | addPreferencesFromResource(org.sensors2.osc.R.xml.preferences); 21 | addPreferencesFromResource(org.sensors2.common.R.xml.common_preferences); 22 | } 23 | 24 | @NonNull 25 | @SuppressLint("RestrictedApi") 26 | @Override 27 | protected Adapter onCreateAdapter(@NonNull PreferenceScreen preferenceScreen) { 28 | return new PreferenceGroupAdapter(preferenceScreen) { 29 | @Override 30 | public void onBindViewHolder(@NonNull PreferenceViewHolder holder, int position) { 31 | super.onBindViewHolder(holder, position); 32 | View iconFrame = holder.itemView.findViewById(R.id.icon_frame); 33 | if (iconFrame != null) { 34 | iconFrame.setVisibility(View.GONE); 35 | } 36 | } 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/dispatch/OscConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.dispatch; 2 | 3 | import com.illposed.osc.OSCPortOut; 4 | 5 | import java.net.InetAddress; 6 | 7 | public class OscConfiguration { 8 | private static OscConfiguration instance; 9 | private OSCPortOut oscPort; 10 | private String host; 11 | private int port; 12 | private boolean sendAsBundle; 13 | 14 | private OscConfiguration() { 15 | this.oscPort = null; 16 | this.host = null; 17 | this.port = 0; 18 | } 19 | 20 | public static OscConfiguration getInstance() { 21 | if (instance == null) { 22 | instance = new OscConfiguration(); 23 | } 24 | return instance; 25 | } 26 | 27 | public void setHost(String host) { 28 | this.host = host; 29 | this.oscPort = null; 30 | } 31 | 32 | public void setPort(int port) { 33 | this.port = port; 34 | this.oscPort = null; 35 | } 36 | 37 | public OSCPortOut getOscPort() { 38 | if (this.oscPort == null) { 39 | try { 40 | InetAddress address = InetAddress.getByName(this.host); 41 | this.oscPort = new OSCPortOut(address, this.port); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | return this.oscPort; 47 | } 48 | 49 | public void setSendAsBundle(boolean sendAsBundle) { 50 | this.sendAsBundle = sendAsBundle; 51 | } 52 | 53 | public boolean getSendAsBundle() { 54 | return this.sendAsBundle; 55 | } 56 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Due to Github's determination to be the "world’s leading AI-powered developer platform" this project has been moved over to [Codeberg](https://codeberg.org/Residuum/Sensors2OSC)** 2 | # Sensors2OSC 3 | 4 | Android app for sending sensor data and multitouch via [Open Sound Control (OSC)](http://opensoundcontrol.org/) over network to a recipient. 5 | 6 | Typical use case is controlling a music application from your phone or tablet. 7 | 8 | Homepage 9 | 10 | ## Download 11 | 12 | 13 | Get it on F-Droid 14 | 15 | To build the app yourself, install the [Android SDK](https://developer.android.com/studio/index.html) and [Gradle](https://gradle.org/). 16 | 17 | After installation run `gradle.bat` on Windows or `./gradlew` on Mac OS X and Linux. 18 | 19 | ## Contributing 20 | 21 | If you want to contribute to this project, send a pull request. 22 | 23 | ## Translation 24 | 25 | Translation is currently coordinated via weblate. 26 | 27 | 28 | Translation state 29 | 30 | 31 | If you want to add a new language or update translations, please see the [Common](https://github.com/SensorApps/Common) library for the sensor apps. It contains additional strings. 32 | 33 | 34 | ## Example usage 35 | There are two examples included for receiving data from Sensors2OSC, that reside in `examples`, Puredata and Python3. Both listen to port 9000. 36 | -------------------------------------------------------------------------------- /app/src/main/res/xml/preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 13 | 21 | 27 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/xml-v26/preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 13 | 21 | 27 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/sensors/Settings.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.sensors; 2 | 3 | import android.content.SharedPreferences; 4 | 5 | import java.util.Objects; 6 | 7 | /** 8 | * Created by thomas on 05.11.14. 9 | */ 10 | public class Settings extends org.sensors2.common.sensors.Settings { 11 | 12 | private final String host; 13 | private final int port; 14 | private final boolean sendAsBundle; 15 | private final boolean keepScreenAlive; 16 | 17 | public Settings(SharedPreferences preferences) { 18 | super(preferences); 19 | this.host = this.setHost(preferences); 20 | this.port = this.setPort(preferences); 21 | this.sendAsBundle = this.setSendAsBundle(preferences); 22 | this.keepScreenAlive = this.setKeepScreenAlive(preferences); 23 | } 24 | 25 | public boolean getSetAsBundle() { 26 | return sendAsBundle; 27 | } 28 | 29 | private boolean setSendAsBundle(SharedPreferences preferences) { 30 | return preferences.getBoolean("pref_comm_bundle", false); 31 | } 32 | 33 | public boolean getKeepScreenAlive() { 34 | return keepScreenAlive; 35 | } 36 | 37 | private boolean setKeepScreenAlive(SharedPreferences preferences) { 38 | return preferences.getBoolean("pref_comm_screen_alive", false); 39 | } 40 | 41 | public int getPort() { 42 | return port; 43 | } 44 | 45 | private int setPort(SharedPreferences preferences) { 46 | return Integer.parseInt(Objects.requireNonNull(preferences.getString("pref_comm_port", "9000"))); 47 | } 48 | 49 | public String getHost() { 50 | return host; 51 | } 52 | 53 | private String setHost(SharedPreferences preferences) { 54 | return preferences.getString("pref_comm_host", "localhost"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/dispatch/SensorConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.dispatch; 2 | 3 | import org.sensors2.osc.sensors.Parameters; 4 | 5 | /** 6 | * Created by thomas on 11.11.14. 7 | */ 8 | public class SensorConfiguration { 9 | private final float[] currentValues = new float[Parameters.MAX_DIMENSIONS]; 10 | private boolean send; 11 | private int sensorType; 12 | private String oscParam; 13 | private boolean sendDuplicates; 14 | 15 | public SensorConfiguration() { 16 | } 17 | 18 | public boolean sendingNotNeeded(float[] values) { 19 | if (!this.send) { 20 | return true; 21 | } 22 | if (sendDuplicates) { 23 | return false; 24 | } 25 | boolean differenceDetected = false; 26 | for (int i = 0; i < values.length && i < Parameters.MAX_DIMENSIONS; i++) { 27 | if (Math.abs(values[i] - this.currentValues[i]) != 0) { 28 | differenceDetected = true; 29 | } 30 | this.currentValues[i] = values[i]; 31 | } 32 | return !differenceDetected; 33 | } 34 | 35 | public boolean getSend() { 36 | return this.send; 37 | } 38 | 39 | public void setSend(boolean send) { 40 | this.send = send; 41 | } 42 | 43 | public void setSendDuplicates(boolean sendDuplicates) { 44 | this.sendDuplicates = sendDuplicates; 45 | } 46 | 47 | public int getSensorType() { 48 | return this.sensorType; 49 | } 50 | 51 | public void setSensorType(int sensorType) { 52 | this.sensorType = sensorType; 53 | } 54 | 55 | public String getOscParam() { 56 | return this.oscParam; 57 | } 58 | 59 | public void setOscParam(String oscParam) { 60 | this.oscParam = oscParam; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Authors: 2 | Thomas Mayer 3 | Antonio Deusany de Carvalho Junior 4 | 5 | Contributors: 6 | Tal Kirshboim 7 | naofum (Japanese translation) 8 | தமிழ்நேரம் (Tamil translation) 9 | naofum (Japanese translation) 10 | 11 | Copyright (c) 2014 - 2025 Thomas Mayer, Antonio Deusany de Carvalho Junior 12 | and others. 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in 22 | all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | THE SOFTWARE. 31 | 32 | Uses the following component: 33 | JavaOSC (http://www.illposed.com/software/javaosc.html), licensed under the 34 | terms found at: https://raw.githubusercontent.com/hoijui/JavaOSC/master/LICENSE 35 | 36 | Part of the Bluetooth code is copied from OpenTracks 37 | (https://github.com/OpenTracksApp/OpenTracks) and subject to the Apache 2 License 38 | (https://github.com/OpenTracksApp/OpenTracks/blob/main/LICENSE) 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/help_sensor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 17 | 18 | 25 | 26 | 33 | 34 | 41 | 42 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/org/sensors2/osc/fragments/HelpSensorFragment.java: -------------------------------------------------------------------------------- 1 | package org.sensors2.osc.fragments; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import org.sensors2.osc.R; 11 | import org.sensors2.osc.dispatch.Bundling; 12 | 13 | import androidx.fragment.app.Fragment; 14 | 15 | /** 16 | * Created by thomas on 09.11.14. 17 | */ 18 | public class HelpSensorFragment extends Fragment { 19 | @SuppressLint("SetTextI18n") 20 | @Override 21 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 22 | Bundle args = this.getArguments(); 23 | 24 | assert args != null; 25 | String name = args.getString(Bundling.NAME); 26 | String sensorName = args.getString(Bundling.SENSOR_NAME); 27 | @SuppressLint("InflateParams") View v = inflater.inflate(R.layout.help_sensor, null); 28 | TextView groupName = v.findViewById(R.id.group_name); 29 | groupName.setText(name + " (" + sensorName + ")"); 30 | AddText(v.findViewById(R.id.osc_prefix), args.getString(Bundling.OSC_PREFIX)); 31 | AddText(v.findViewById(R.id.dimensions), args.getInt(Bundling.DIMENSIONS)); 32 | AddText(v.findViewById(R.id.range), args.getFloat(Bundling.SENSOR_RANGE)); 33 | AddText(v.findViewById(R.id.resolution), args.getFloat(Bundling.RESOLUTION)); 34 | return v; 35 | } 36 | 37 | @SuppressLint("SetTextI18n") 38 | private void AddText(TextView view, float val) { 39 | view.setText(view.getText() + ": " + val); 40 | } 41 | 42 | @SuppressLint("SetTextI18n") 43 | private void AddText(TextView view, int val) { 44 | view.setText(view.getText() + ": " + val); 45 | } 46 | 47 | @SuppressLint("SetTextI18n") 48 | private void AddText(TextView view, String val) { 49 | view.setText(view.getText() + ": " + val); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout-watch/activity_start_up.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 13 | 14 | 20 | 21 | 26 | 27 |