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
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@

# :cyclone: Android Beacon Scanner #

A simple android beacon scanner that can recognize iBeacons, AltBeacons, Eddystone beacons (UID and URL, with or without TLM) and RuuviTags [available on Google Play](https://play.google.com/store/apps/details?id=com.bridou_n.beaconscanner).
Forked from "A simple [android beacon scanner](https://github.com/Bridouille/android-beacon-scanner) that can recognize iBeacons, AltBeacons, Eddystone beacons (UID and URL, with or without TLM) and RuuviTags [available on Google Play](https://play.google.com/store/apps/details?id=com.bridou_n.beaconscanner)."

<img src="screenshots/screen-1.png" width="25%" /> <img src="screenshots/screen-2.png" width="25%" /> <img src="screenshots/screen-3.png" width="25%" />

## :key: Modified features ##
The forked project has the following new features:

* White list: white can help doing experiment without manualy blocking a lot of beacons; (this is helpful if there are a lot of beacons in the experiment enviroment);
* (TODO): dump the db to local csv files;

Available for android 5.0+ and smartphones with Bluetooth LE.

* Original app visualization:

<img src="screenshots/screen-1.png" width="25%" /> <img src="screenshots/screen-2.png" width="25%" /> <img src="screenshots/screen-3.png" width="25%" />

* White list part: (new feature, under developing)

<img src="screenshots/white_list_vis_1.png" width="25%" /> <img src="screenshots/white_list_vis_2.png" width="25%" />



## :key: Features ##

This app will scan for beacons near you! :v:
Expand Down
18 changes: 9 additions & 9 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ android {
multiDexEnabled true
}

signingConfigs {
release {
keyAlias 'BeaconScannerKey'
keyPassword beacon_scanner_key_password
storeFile file(beacon_scanner_store_file)
storePassword beacon_scanner_store_password
}
}
// signingConfigs {
// release {
// keyAlias 'BeaconScannerKey'
//// keyPassword beacon_scanner_key_password
// storeFile file(beacon_scanner_store_file)
// storePassword beacon_scanner_store_password
// }
// }

buildTypes {
release {
minifyEnabled true
resValue "string", "app_name", "Beacon Scanner"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
// signingConfig signingConfigs.release
}

debug {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ interface BeaconsDao {
@Query("SELECT * FROM $TABLE_NAME WHERE is_blocked = :blocked")
fun getBeacons(blocked: Boolean = false) : Flowable<List<BeaconSaved>>


@Query("SELECT * FROM $TABLE_NAME WHERE is_white = :whited")
fun getWhiteBeacons(whited: Boolean = true) : Flowable<List<BeaconSaved>>

@Query("SELECT * FROM $TABLE_NAME WHERE hashcode = :hashcode")
fun getBeaconById(hashcode: Int) : Single<BeaconSaved>

Expand All @@ -28,6 +32,9 @@ interface BeaconsDao {
@Insert(onConflict = REPLACE)
fun insertBeacon(beacon: BeaconSaved)

// @Update("")
// fun update

@Delete
fun deleteBeacon(beacon: BeaconSaved)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,5 @@ interface AppComponent {
fun inject(activity: BeaconListActivity)
fun inject(activity: SettingsActivity)
fun inject(activity: BlockedActivity)

fun inject(bs: ControlsBottomSheetDialog)
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.bottom_sheet_controls.*
import org.altbeacon.beacon.Beacon
import org.altbeacon.beacon.BeaconConsumer
import org.altbeacon.beacon.BeaconManager
import org.altbeacon.beacon.Region
import timber.log.Timber
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList

class BeaconListActivity : AppCompatActivity(), BeaconConsumer {

Expand Down Expand Up @@ -83,9 +85,11 @@ class BeaconListActivity : AppCompatActivity(), BeaconConsumer {
private var loggingRequests = CompositeDisposable()

private var isScanning = false

private var isWhiting = false

private val rvAdapter = BeaconsRecyclerViewAdapter { beacon ->
ControlsBottomSheetDialog.newInstance(beacon.hashcode).apply {
ControlsBottomSheetDialog.newInstance(beacon.hashcode,false,beacon.isWhite).apply {
show(supportFragmentManager)
}
}
Expand All @@ -109,6 +113,10 @@ class BeaconListActivity : AppCompatActivity(), BeaconConsumer {
scan_fab.setOnClickListener {
toggleScan()
}

white_fab.setOnClickListener({
toogleWhite()
})
}

private fun toggleScan() {
Expand Down Expand Up @@ -148,8 +156,25 @@ class BeaconListActivity : AppCompatActivity(), BeaconConsumer {
keepScreenOn(false)
isScanning = false
}


private fun toogleWhite(){
val ori_name = getString(if (isScanning()) R.string.scanning_for_beacons else R.string.app_name)
if (!isWhiting()){
tracker.logEvent("start_whiting_clicked",null)
isWhiting = true
toolbar.title = ori_name + " (whitelist)"
}
else{
isWhiting = false
toolbar.title = ori_name
}
white_fab.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(this, if (isWhiting) R.color.colorPauseFab else R.color.colorSecondary))
}

fun isScanning() = isScanning

fun isWhiting() = isWhiting

private fun unbindBeaconManager() {
if (beaconManager?.isBound(this) == true) {
Expand Down Expand Up @@ -192,14 +217,29 @@ class BeaconListActivity : AppCompatActivity(), BeaconConsumer {
beaconManager = component().providesBeaconManager()

observeBluetoothState()
listQuery = db.beaconsDao().getBeacons(blocked = false)
.subscribeOn(Schedulers.io())
.map { list ->
if (list.isEmpty()) {
listOf(BeaconRow.EmptyState)
} else {
list.map { BeaconRow.Beacon(it) }

// val listQuery = db.beaconsDao()
// here not possible to change the white setting:

listQuery = db.beaconsDao().getBeacons(blocked = false).subscribeOn(Schedulers.io())
.map { list ->
if(!isWhiting){
if (list.isEmpty()) {
listOf(BeaconRow.EmptyState)
} else {
list.map { when(it.isWhite){
true -> BeaconRow.BeaconWhite(it)
else -> BeaconRow.Beacon(it)
} }
}
}else{
if (list.filter{it.isWhite}.isEmpty()) {
listOf(BeaconRow.EmptyState)
} else {
list.filter{it.isWhite}.map { BeaconRow.BeaconWhite(it) }
}
}

}
.doOnSubscribe { rvAdapter.submitList(listOf(BeaconRow.Loading)) }
.observeOn(AndroidSchedulers.mainThread())
Expand Down Expand Up @@ -283,8 +323,8 @@ class BeaconListActivity : AppCompatActivity(), BeaconConsumer {
} catch (e: EmptyResultSetException) {
null
}

BeaconSaved.createFromBeacon(it, isBlocked = beaconInDb?.isBlocked ?: false)
Timber.d(it.toString())
BeaconSaved.createFromBeacon(it, isBlocked = beaconInDb?.isBlocked ?: false, isWhite= beaconInDb?.isWhite?:false)
}
.doOnNext {
db.beaconsDao().insertBeacon(it)
Expand Down Expand Up @@ -419,6 +459,11 @@ class BeaconListActivity : AppCompatActivity(), BeaconConsumer {
tracker.log("action_settings")
startActivity(Intent(this, SettingsActivity::class.java))
}

R.id.action_save -> {
tracker.log("white_lists")
}

else -> return super.onOptionsItemSelected(item)
}
return true
Expand Down
Loading