Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
.cxx
local.properties
/.idea/
secrets.properties
55 changes: 21 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,32 @@
**PositionMe** is an indoor positioning data collection application initially developed for the University of Edinburgh's Embedded Wireless course. The application now includes enhanced features, including **trajectory playback**, improved UI design, and comprehensive location tracking.

## Features

- **Real-time Sensor Data Collection**: Captures sensor, location, and GNSS data.
- **Trajectory Playback**: Simulates recorded movement from previously saved trajectory files (Trajectory proto files).
- **Interactive Map Display**:
- Visualizes the user's **PDR trajectory/path**.
- Displays **received GNSS locations**.
- Supports **floor changes and indoor maps** for a seamless experience.
- **Playback Controls**:
- **Play/Pause, Exit, Restart, Jump to End**.
- **Progress bar for tracking playback status**.
- **Redesigned UI**: Modern and user-friendly interface for enhanced usability.
# PositionMe
Indoor poistioning data collection application created for the University of Edinburgh's Embedded Wireless course.

## Requirements

- **Android Studio 4.2** or later
- **Android SDK 30** or later
- Android Studio 4.2 or later
- Android SDK 30 or later

## Installation

1. **Clone the repository.**
2. **Open the project in Android Studio**.
1. Clone the repository.
2. Open the project in Android Studio.
3. Add your own API key for Google Maps in AndroidManifest.xml
4. Set the website where you want to send your data. The application was built for use with [openpositioning.org](http://openpositioning.org/).
5. **Build and run the project on your Android device**.
4. Set the website where you want to send your data. The application was built for use with openpositioning.org.
5. Build and run the project on your device.

## Usage

1. **Install the application** using Android Studio.
2. **Launch the application** on your Android device.
3. **Grant necessary permissions** when prompted:
- Sensor access
- Location services
- Internet connectivity
4. **Collect real-time positioning data**:
- Follow on-screen instructions to record sensor data.
5. **Replay previously recorded trajectories**:
- Navigate to the **Files** section.
- Select a saved trajectory and press **Play**.
- The recorded trajectory will be simulated and displayed on the map.
6. **Control playback**:
- Pause, restart, or jump to the end using playback controls.
1. Install the application on a compatible device using Android Studio.
2. Launch the application on your device.
3. Allow sensor, location and internet permissions when asked.
4. Follow the instructions on the screen to start collecting sensor data.

## Creators

### Original contributors ([CloudWalk](https://github.com/openpositioning/DataCollectionTeam6))
- Virginia Cangelosi (virginia-cangelosi)
- Michal Dvorak (dvoramicha)
- Mate Stodulka (stodimp)

### New contributors
- Francisco Zampella (fzampella-huawei)
77 changes: 37 additions & 40 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,34 @@ plugins {
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}

// (Optional) load local secrets file:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('secrets.properties')
if (localPropertiesFile.exists()) {
localProperties.load(new FileInputStream(localPropertiesFile))
}

android {
namespace "com.openpositioning.PositionMe"
compileSdk 34
namespace ="com.openpositioning.PositionMe" //fix Namespace not specified problem
compileSdk 33

defaultConfig {
applicationId "com.openpositioning.PositionMe"
minSdk 28
targetSdk 34
targetSdk 33
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

// Example of referencing secrets (if you use secrets.properties):
buildConfigField "String", "MAPS_API_KEY",
"\"${localProperties['MAPS_API_KEY'] ?: ''}\""

buildConfigField "String", "OPENPOSITIONING_API_KEY",
"\"${localProperties['OPENPOSITIONING_API_KEY'] ?: ''}\""

buildConfigField "String", "OPENPOSITIONING_MASTER_KEY",
"\"${localProperties['OPENPOSITIONING_MASTER_KEY'] ?: ''}\""
}

buildFeatures {
// For example:
// compose true // if you want Jetpack Compose
// viewBinding true
}

buildFeatures {
buildConfig true
}
Expand All @@ -48,48 +41,52 @@ android {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'


}
}


}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
// Core AndroidX
implementation 'androidx.appcompat:appcompat:1.7.0-alpha03' // or stable: 1.6.1
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
implementation 'androidx.preference:preference:1.2.1'

implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.6.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.android.volley:volley:1.2.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'

// Material Components (Material 3 support is in 1.12.0+)
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
implementation 'com.google.android.material:material:1.12.0'

testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'com.google.protobuf:protobuf-java:3.0.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation "com.google.protobuf:protobuf-java-util:3.0.0"
implementation "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava"
implementation 'com.google.android.gms:play-services-maps:19.0.0'

implementation 'com.google.android.gms:play-services-maps:18.1.0'
// Navigation components
def nav_version = "2.8.6"
def nav_version = "2.5.3"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

// Optional: Jetpack Compose (Material 3)
// implementation "androidx.compose.material3:material3:1.3.1"
// implementation "androidx.activity:activity-compose:1.7.2"

// Testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'org.ejml:ejml-all:0.43'
}

//secrets {
// // Optionally specify a different file name containing your secrets.
// // The plugin defaults to "local.properties"
// propertiesFileName = "secrets.properties"
//
// // A properties file containing default secret values. This file can be
// // checked in version control.
// defaultPropertiesFileName = "local.defaults.properties"
//
// // Configure which keys should be ignored by the plugin by providing regular expressions.
// // "sdk.dir" is ignored by default.
// ignoreList.add("keyToIgnore") // Ignore the key "keyToIgnore"
// ignoreList.add("sdk.*") // Ignore all keys matching the regexp "sdk.*"
//}
103 changes: 24 additions & 79 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,101 +2,46 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.openpositioning.PositionMe">

<!--
1. Hardware features.
If you truly require these sensors, keep `required="true"`. Otherwise,
consider marking them as `required="false"`.
-->
<uses-feature android:name="android.hardware.sensor.stepdetector" android:required="true"/>
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true"/>
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true"/>

<!--
2. Permissions.
a) For Android 10 and above, if your app needs to do background location,
you should also add:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
b) If you want to continue reading/writing files outside of your
app-specific directory, you must set `requestLegacyExternalStorage="true"`.
(See the <application> tag below.)
-->

<!-- Wake lock -->
<!-- Wake -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

<!-- Physical activity / Step detection (Android 10+ requires runtime permission) -->
<!-- Activity -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>

<!-- Wi-Fi and network state (note that setWifiEnabled() no longer works on Android 10+ if you target 29+) -->
<!-- WiFi -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!-- Location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<!-- Internet -->
<uses-permission android:name="android.permission.INTERNET"/>

<!-- Storage - Deprecated in Android 10+ (use scoped storage instead)
If you plan to adopt scoped storage fully and store only within your app-specific directories
(or MediaStore for shared media), consider removing READ/WRITE_EXTERNAL_STORAGE eventually.
If you still need broad file access (for example, to migrate existing user data), keep them
short-term but note that starting with Android 11 (API 30), they don’t allow the same broad file access.
-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Required if your app needs to access images or photos that other apps created. -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

<!-- Required if your app needs to access videos that other apps created. -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<!-- Required if your app needs to access audio files that other apps created. -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />


<!--
3. requestLegacyExternalStorage:
- Required on Android 10 if you need to maintain legacy external storage behavior.
- This flag is ignored on Android 11 (API 30) and higher for new app installs,
but it does help in migration scenarios (e.g. for existing user upgrades).
-->
<!-- Storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher_icon_map"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_icon_map_round"
android:supportsRtl="true"
android:theme="@style/Theme.Material3.DayNight.NoActionBar"
android:requestLegacyExternalStorage="true"
>

<activity
android:name=".presentation.activity.ReplayActivity"
android:exported="false" />
<activity
android:name=".presentation.activity.RecordingActivity"
android:exported="false" />

<!-- Google Maps API key metadata -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key"/>

<activity
android:name="com.openpositioning.PositionMe.presentation.activity.MainActivity"
android:exported="true"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>

</manifest>
android:theme="@style/Theme.Cloud">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyDLSxWBibRSFlYWjKmatxy-kqwG_xcS-w4"/>
<activity
android:name="com.openpositioning.PositionMe.MainActivity"
android:exported="true"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

</manifest>
Loading