Commit 4deaa028 authored by nk2's avatar nk2 🙃

final

parent 69551af9
......@@ -73,6 +73,7 @@ dependencies {
compile "io.reactivex.rxjava2:rxandroid:$rxandroid_version"
compile "io.reactivex.rxjava2:rxjava:$rxjava_version"
compile "com.evernote:android-job:$job_version"
compile "com.github.ivbaranov:rxbluetooth2:$bluetooth_version"
//View
compile "com.jakewharton:butterknife:$butterknife_version"
......@@ -92,17 +93,11 @@ dependencies {
compile "com.google.dagger:dagger-android-support:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
//Json
compile "com.squareup.moshi:moshi:$moshi_version"
compile "com.squareup.moshi:moshi-kotlin:$moshi_version"
//Data
compile "com.pixplicity.easyprefs:library:$easyprefs_version"
//Perms
compile "com.github.karanchuri:PermissionManager:$perms_version"
}
kotlin {
......
......@@ -3,6 +3,11 @@
xmlns:tools="http://schemas.android.com/tools"
package="ga.nk2ishere.dev.musclecar">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:name=".App"
tools:replace="android:allowBackup"
......@@ -28,8 +33,7 @@
</activity>
<service
android:name=".features.pulse.PulseCatchService"
android:enabled="true"/>
android:name=".features.pulse.PulseBTService"
android:enabled="true" />
</application>
</manifest>
......@@ -10,7 +10,7 @@ import android.view.ViewGroup
*/
abstract class AbstractAdapter<ITEM> constructor(
protected var itemList: List<ITEM>,
var itemList: List<ITEM>,
private val layoutResId: Int)
: RecyclerView.Adapter<AbstractAdapter.Holder>() {
......
......@@ -6,12 +6,11 @@ import android.content.Intent
import android.support.v4.app.NotificationCompat
import ga.nk2ishere.dev.musclecar.R
import ga.nk2ishere.dev.musclecar.features.pulse.PulseActivity
import ga.nk2ishere.dev.musclecar.features.pulse.PulseCatchService
/**
* Created by nk2 on 11/02/2018.
*/
fun Service.sendNotification(id: Int, ticker: String, title: String, text: String) {
fun Service.sendNotification(id: Int, shortName: String, title: String, text: String) {
//These three lines makes Notification to open main activity after clicking on it
val notificationIntent = Intent(this, PulseActivity::class.java)
......@@ -24,7 +23,7 @@ fun Service.sendNotification(id: Int, ticker: String, title: String, text: Strin
builder.setContentIntent(contentIntent)
.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(ticker)
.setTicker(shortName)
.setContentTitle(title)
.setContentText(text)
.setWhen(System.currentTimeMillis())
......
......@@ -5,17 +5,13 @@ import android.content.Intent
import com.arellomobile.mvp.InjectViewState
import com.arellomobile.mvp.MvpPresenter
import ga.nk2ishere.dev.musclecar.App
import ga.nk2ishere.dev.musclecar.common.libs.applySchedulers
import ga.nk2ishere.dev.musclecar.features.calibration.data.repositories.ThresholdRepository
import ga.nk2ishere.dev.musclecar.features.pulse.PulseCatchService
import ga.nk2ishere.dev.musclecar.features.pulse.PulseBTService
import kotlinx.coroutines.experimental.android.UI
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import android.media.RingtoneManager
import android.media.Ringtone
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.android.schedulers.AndroidSchedulers.mainThread
import io.reactivex.schedulers.Schedulers
/**
......@@ -31,22 +27,22 @@ class CalibrationPresenter: MvpPresenter<CalibrationView>() {
fun onInit(context: Activity) {
App.appComponent.inject(this)
this.context = context
if(!PulseCatchService.started)
context.startService(Intent(context, PulseCatchService::class.java))
PulseCatchService.observer
if(!PulseBTService.started)
context.startService(Intent(context, PulseBTService::class.java))
PulseBTService.observer
.delay(1, TimeUnit.SECONDS, mainThread())
.subscribe({ with(UI) {onPulseUpdate(it)} })
}
private var counter = 1 ; private var iterCounter = 1 ; private var overallSum = 0 ; private var average = 0
private var counter = 0 ; private var iterCounter = 0 ; private var overallSum = 0 ; private var average = 0
private fun onPulseUpdate(pulse: Int) {
if (counter <= 15) { counter++
if (counter <= 15) { counter++; overallSum += pulse; iterCounter++
if(counter % 4 == 0) {
RingtoneManager.getRingtone(context, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)).play()
}
if(counter % 5 == 0) {
average = overallSum / iterCounter; iterCounter = 0; overallSum = 0
viewState.addCalibratedValue(average)
iterCounter++; overallSum += pulse; average = overallSum / iterCounter
}
} else {
viewState.showDoneButton()
......@@ -62,7 +58,7 @@ class CalibrationPresenter: MvpPresenter<CalibrationView>() {
}
fun onRetryButtonClick() {
counter = 1; iterCounter = 1; overallSum = 0; average = 0
counter = 0; iterCounter = 0; overallSum = 0; average = 0
viewState.hideDoneButton()
viewState.hideRetryButton()
viewState.resetCalibratedValues()
......
......@@ -16,8 +16,10 @@ import kotlinx.android.synthetic.main.activity_pulse.*
import org.jetbrains.anko.sdk25.coroutines.onClick
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.content.pm.PackageManager
import android.support.annotation.NonNull
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
/**
......@@ -69,4 +71,5 @@ class PulseActivity : MvpAppCompatActivity(), PulseView {
colorAnimation.addUpdateListener { animator -> topPanel.setBackgroundColor(animator.animatedValue as Int) }
colorAnimation.start()
}
}
\ No newline at end of file
package ga.nk2ishere.dev.musclecar.features.pulse
import android.app.Activity
import android.app.Service
import android.bluetooth.BluetoothSocket
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.util.Log
import com.github.ivbaranov.rxbluetooth.BluetoothConnection
import ga.nk2ishere.dev.musclecar.common.libs.applySchedulers
import ga.nk2ishere.dev.musclecar.common.libs.random
import ga.nk2ishere.dev.musclecar.common.libs.sendNotification
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
import org.jetbrains.anko.notificationManager
import java.lang.Thread.sleep
import kotlin.concurrent.thread
import com.github.ivbaranov.rxbluetooth.RxBluetooth
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import org.jetbrains.anko.toast
import java.util.*
/**
* Created by nk2 on 06/02/2018.
*/
class PulseBTService : Service() {
companion object {
private val TAG = "BluetoothService"
val uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
val name = "HC-05"
val observer = PublishSubject.create<Int>()
var started = false
private set
lateinit var pconnection: BluetoothConnection
}
private var rxBluetooth: RxBluetooth? = null
private val compositeDisposable = CompositeDisposable()
override fun onCreate() {
super.onCreate()
Log.d(TAG, "BluetoothService started!")
rxBluetooth = RxBluetooth(this)
if (!rxBluetooth!!.isBluetoothAvailable) {
// handle the lack of bluetooth support
Log.d(TAG, "Bluetooth is not supported!")
} else {
// check if bluetooth is currently enabled and ready for use
if (!rxBluetooth!!.isBluetoothEnabled) {
Log.d(TAG, "Bluetooth should be enabled first!")
} else {
compositeDisposable.add(rxBluetooth!!.observeDevices()
.observeOn(Schedulers.computation())
.subscribeOn(Schedulers.computation())
.subscribe { bluetoothDevice ->
if(bluetoothDevice.name == name) {
started = true
rxBluetooth!!.cancelDiscovery()
val socket = rxBluetooth!!.observeConnectDevice(bluetoothDevice, uuid).blockingFirst()
connectionManage(BluetoothConnection(socket))
socket.outputStream.write(1)
}
})
rxBluetooth!!.startDiscovery()
}
}
}
private fun connectionManage(connection: BluetoothConnection) {
pconnection = connection
connection.observeStringStream(';'.toInt()).subscribe({
if(!it.isNullOrBlank())
observer.onNext(it.toInt())
}, { it.printStackTrace() })
}
override fun onDestroy() {
compositeDisposable.dispose()
started = false
super.onDestroy()
Log.d(TAG, "BluetoothService stopped!")
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
\ No newline at end of file
package ga.nk2ishere.dev.musclecar.features.pulse
import android.app.Notification
import android.app.Service
import android.content.Intent
import android.os.IBinder
import ga.nk2ishere.dev.musclecar.R.mipmap.ic_launcher
import android.app.PendingIntent
import android.app.NotificationManager
import android.support.v4.app.NotificationCompat
import ga.nk2ishere.dev.musclecar.R
import ga.nk2ishere.dev.musclecar.common.libs.applySchedulers
import ga.nk2ishere.dev.musclecar.common.libs.random
import ga.nk2ishere.dev.musclecar.common.libs.sendNotification
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
import org.jetbrains.anko.notificationManager
import java.lang.Thread.sleep
import kotlin.concurrent.thread
/**
* Created by nk2 on 06/02/2018.
*/
class PulseCatchService : Service() {
companion object {
val observer: Subject<Int> = PublishSubject.create()
val DEFAULT_NOTIFICATION_ID = 101
var started = false
private set
}
val worker = thread(false) {
//Task
while (started) {
//TODO BLUETOOTH SEX
observer.onNext((-1000..1000).random())
sleep(500)
}
}
override fun onCreate() {
super.onCreate()
started = true
worker.start()
observer.applySchedulers()
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
sendNotification(DEFAULT_NOTIFICATION_ID, "Ticker", "MuscleCar", "Linstening")
return Service.START_REDELIVER_INTENT
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onDestroy() {
super.onDestroy()
started = false
worker.interrupt()
notificationManager.cancel(DEFAULT_NOTIFICATION_ID)
stopSelf()
}
}
\ No newline at end of file
package ga.nk2ishere.dev.musclecar.features.pulse
import android.animation.ArgbEvaluator
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
......@@ -12,37 +11,26 @@ import com.arellomobile.mvp.InjectViewState
import com.arellomobile.mvp.MvpPresenter
import ga.nk2ishere.dev.musclecar.App
import ga.nk2ishere.dev.musclecar.R
import ga.nk2ishere.dev.musclecar.common.libs.applySchedulers
import ga.nk2ishere.dev.musclecar.common.libs.setUp
import ga.nk2ishere.dev.musclecar.features.calibration.CalibrationActivity
import ga.nk2ishere.dev.musclecar.features.calibration.data.ThresholdData
import ga.nk2ishere.dev.musclecar.features.calibration.data.repositories.ThresholdRepository
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.android.schedulers.AndroidSchedulers.mainThread
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.experimental.android.UI
import org.jetbrains.anko.sdk25.coroutines.onClick
import org.jetbrains.anko.toast
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import android.content.DialogInterface
import android.text.Editable
import android.view.View
import android.widget.EditText
import android.widget.TextView
import com.pixplicity.easyprefs.library.Prefs
import org.jetbrains.anko.AlertBuilder
import android.animation.ObjectAnimator
import android.graphics.Color
import android.support.v4.content.res.ResourcesCompat
import ga.nk2ishere.dev.musclecar.common.libs.Kadapter
import ga.nk2ishere.dev.musclecar.common.libs.toColor
import ga.nk2ishere.dev.musclecar.features.pulse.data.DailydoneData
import ga.nk2ishere.dev.musclecar.features.pulse.data.repositories.DailydoneRepository
import ga.nk2ishere.dev.musclecar.features.pulse.misc.DailydoneAdapter
import org.jetbrains.anko.find
import org.joda.time.DateTime
import org.joda.time.DateTime.now
import org.w3c.dom.Text
/**
......@@ -61,9 +49,9 @@ class PulsePresenter: MvpPresenter<PulseView>() {
fun onInit(context: Activity) {
App.appComponent.inject(this)
this.context = context
if(!PulseCatchService.started)
context.startService(Intent(context, PulseCatchService::class.java))
PulseCatchService.observer
if(!PulseBTService.started)
context.startService(Intent(context, PulseBTService::class.java))
PulseBTService.observer
.delay(1, TimeUnit.SECONDS, mainThread())
.subscribe({ with(UI) { onPulseUpdate(it) } })
thresholdRepository.findCurrent().subscribe({
......@@ -91,8 +79,7 @@ class PulsePresenter: MvpPresenter<PulseView>() {
ResourcesCompat.getColor(context.resources, R.color.colorPrimary, null).toColor(),
ResourcesCompat.getColor(context.resources, R.color.colorAccent, null).toColor())
counter = 0
//TODO drive!
PulseBTService.pconnection.send(1)
updateCurrentDailydone(1)
}
}
......@@ -100,6 +87,7 @@ class PulsePresenter: MvpPresenter<PulseView>() {
}
counter == 3 -> {
counter = -1
PulseBTService.pconnection.send(0)
viewState.changeBackgroundColor(
ResourcesCompat.getColor(context.resources, R.color.colorAccent, null).toColor(),
ResourcesCompat.getColor(context.resources, R.color.colorPrimary, null).toColor())
......@@ -138,11 +126,15 @@ class PulsePresenter: MvpPresenter<PulseView>() {
.setView(textView)
.setTitle("Calibration")
.setMessage("Enter title of threhold")
.setPositiveButton("Yes", { _, _ ->
thresholdRepository.add(ThresholdData(textView.text.toString(), data.extras.getInt("threshold"))).subscribe({
.setCancelable(false)
.setNegativeButton("No") { _, _ -> }
.setPositiveButton("Yes") { _, _ ->
current = ThresholdData(textView.text.toString(), data.extras.getInt("threshold"))
thresholdRepository.add(current!!).subscribe({
viewState.hideBottomSheet(bottomSheet!!)
onSettingsUpdate()
updateCurrentThreshold()
}, { it.printStackTrace() }) })
}, { it.printStackTrace() }) }
.show()
}
......@@ -175,6 +167,15 @@ class PulsePresenter: MvpPresenter<PulseView>() {
}
fun onSettingsUpdate() {
bottomSheet?.findViewById<RecyclerView>(R.id.thresholdList)?.let { view ->
thresholdRepository.findAll().subscribe({
(view.adapter as Kadapter<ThresholdData>).itemList = it
view.adapter.notifyDataSetChanged()
}, { it.printStackTrace() })
}
}
fun onDailyViewCreate(recyclerView: RecyclerView) {
dailydoneRepository.findAll().subscribe({
recyclerView.adapter = DailydoneAdapter(context, it)
......
......@@ -34,7 +34,7 @@ class DailydoneAdapter(val context: Context, val list: List<DailydoneData>): Rec
}
class DailydoneViewHolder(view: View, viewType: Int): RecyclerView.ViewHolder(view) {
val timelineView: TimelineView = view.findViewById(R.id.timeLine)
private val timelineView: TimelineView = view.findViewById(R.id.timeLine)
init {
timelineView.initLine(viewType)
}
......
......@@ -68,7 +68,7 @@
android:id="@+id/currentPulse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="231"
android:text="0"
android:textColor="#ffffff"
android:textSize="24sp" />
......@@ -166,7 +166,7 @@
android:textColor="#ffffff"
android:textSize="16sp"
android:textStyle="bold"
android:text="4" />
android:text="0" />
</LinearLayout>
<ImageView
......
......@@ -20,3 +20,4 @@ constraintlayout_version=1.1.0-beta4
snakeview_version=1.0
timelineview_version=1.0.6
butterknife_version=8.8.1
bluetooth_version=2.0.1
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment