Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.22.1-beta #92

Merged
merged 20 commits into from
Jan 21, 2024
Merged
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Bluetooth Radar

<a href='https://play.google.com/store/apps/details?id=f.cking.software&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' width='200'/></a>
<a href='https://play.google.com/store/apps/details?id=f.cking.software&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://github.com/Semper-Viventem/MetaRadar/assets/18288554/dd3fc41a-9b51-4747-9a2c-57b37d4706aa' width='200'/></a>
<a href='https://f-droid.org/en/packages/f.cking.software/'><img alt='Get it on F-Droid' src='https://github.com/Semper-Viventem/MetaRadar/assets/18288554/c03a0cf2-b39a-4344-adb8-d4cde7ce4b61' width='200'/></a>

This app is a tool for analyzing Bluetooth (BLE) environments. Scans the BLE ether in the background, notifying you if the device you are looking for is near you or if some unknown device has been following you for for a long time.

Expand Down
8 changes: 6 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ android {
applicationId = "f.cking.software"
minSdk = 29
targetSdk = 34
versionCode = 1704045674
versionName = "0.21.6-beta"

// This version code will be applied only for F-Droid builds, for other builds version code will be generated by gradle dynamically
// For some reason F-Droid requires version code to be hardcoded in the build.gradle file
versionCode = 1705859013
versionName = "0.22.1-beta"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -170,6 +173,7 @@ dependencies {
debugImplementation(libs.compose.tooling)
implementation(libs.compose.tooling.preview)
implementation(libs.compose.material3)
implementation(libs.compose.animation)

// room
implementation(libs.room.runtime)
Expand Down
299 changes: 299 additions & 0 deletions app/schemas/f.cking.software.data.database.AppDatabase/12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
{
"formatVersion": 1,
"database": {
"version": 12,
"identityHash": "b77c993de166d6dbfc51ba4f526fe187",
"entities": [
{
"tableName": "device",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `name` TEXT, `last_detect_time_ms` INTEGER NOT NULL, `first_detect_time_ms` INTEGER NOT NULL, `detect_count` INTEGER NOT NULL, `custom_name` TEXT, `favorite` INTEGER NOT NULL, `manufacturer_id` INTEGER, `manufacturer_name` TEXT, `last_following_detection_ms` INTEGER, `tags` TEXT NOT NULL DEFAULT '', `last_seen_rssi` INTEGER, PRIMARY KEY(`address`))",
"fields": [
{
"fieldPath": "address",
"columnName": "address",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastDetectTimeMs",
"columnName": "last_detect_time_ms",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "firstDetectTimeMs",
"columnName": "first_detect_time_ms",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "detectCount",
"columnName": "detect_count",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "customName",
"columnName": "custom_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "favorite",
"columnName": "favorite",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "manufacturerId",
"columnName": "manufacturer_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "manufacturerName",
"columnName": "manufacturer_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastFollowingDetectionMs",
"columnName": "last_following_detection_ms",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true,
"defaultValue": "''"
},
{
"fieldPath": "lastSeenRssi",
"columnName": "last_seen_rssi",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"address"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "radar_profile",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `description` TEXT, `is_active` INTEGER NOT NULL, `detect_filter` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "description",
"columnName": "description",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isActive",
"columnName": "is_active",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "detectFilter",
"columnName": "detect_filter",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "apple_contacts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sha_256` INTEGER NOT NULL, `associated_address` TEXT NOT NULL, `first_detect_time_ms` INTEGER NOT NULL, `last_detect_time_ms` INTEGER NOT NULL, PRIMARY KEY(`sha_256`))",
"fields": [
{
"fieldPath": "sha256",
"columnName": "sha_256",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "associatedAddress",
"columnName": "associated_address",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "firstDetectTimeMs",
"columnName": "first_detect_time_ms",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastDetectTimeMs",
"columnName": "last_detect_time_ms",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"sha_256"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "location",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`time` INTEGER NOT NULL, `lat` REAL NOT NULL, `lng` REAL NOT NULL, PRIMARY KEY(`time`))",
"fields": [
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lat",
"columnName": "lat",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "lng",
"columnName": "lng",
"affinity": "REAL",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"time"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "device_to_location",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `device_address` TEXT NOT NULL, `location_time` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "deviceAddress",
"columnName": "device_address",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "locationTime",
"columnName": "location_time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "journal",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `timestamp` INTEGER NOT NULL, `reportJson` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "report",
"columnName": "reportJson",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "tag",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))",
"fields": [
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"name"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b77c993de166d6dbfc51ba4f526fe187')"
]
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/f/cking/software/data/DataMappers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ fun DeviceEntity.toDomain(appleAirDrop: AppleAirDrop?): DeviceData {
},
lastFollowingDetectionTimeMs = lastFollowingDetectionMs,
tags = tags.toSet(),
rssi = lastSeenRssi,
)
}

Expand All @@ -66,6 +67,7 @@ fun DeviceData.toData(): DeviceEntity {
manufacturerName = manufacturerInfo?.name,
lastFollowingDetectionMs = lastFollowingDetectionTimeMs,
tags = tags.toList(),
lastSeenRssi = rssi,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ import java.io.File
AutoMigration(from = 7, to = 8),
AutoMigration(from = 9, to = 10),
AutoMigration(from = 10, to = 11),
AutoMigration(from = 11, to = 12),
],
exportSchema = true,
version = 11,
version = 12,
)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package f.cking.software.data.database.dao

import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import f.cking.software.data.database.entity.DeviceEntity

@Dao
Expand All @@ -9,6 +12,12 @@ interface DeviceDao {
@Query("SELECT * FROM device")
fun getAll(): List<DeviceEntity>

@Query("SELECT * FROM device ORDER BY last_detect_time_ms DESC LIMIT :limit OFFSET :offset")
fun getPaginated(offset: Int, limit: Int): List<DeviceEntity>

@Query("SELECT * FROM device WHERE last_detect_time_ms >= :lastDetectTime ORDER BY last_detect_time_ms DESC")
fun getByLastDetectTime(lastDetectTime: Long): List<DeviceEntity>

@Query("SELECT * FROM device WHERE address LIKE :address")
fun findByAddress(address: String): DeviceEntity?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ data class DeviceEntity(
@ColumnInfo(name = "manufacturer_name") val manufacturerName: String? = null,
@ColumnInfo(name = "last_following_detection_ms") val lastFollowingDetectionMs: Long? = null,
@ColumnInfo(name = "tags", defaultValue = "") val tags: List<String>,
@ColumnInfo(name = "last_seen_rssi") val lastSeenRssi: Int? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class BleScannerHelper(
name = result.device.name,
scanTimeMs = currentScanTimeMs,
scanRecordRaw = result.scanRecord?.bytes,
rssi = result.rssi,
)

batch.put(device.address, device)
Expand Down
Loading