Merge branch '100-change-timetrack-account' into 'master'
Resolve "Change timetrack account" Closes #100 See merge request marcel.schwarz/2020ss-qbc-geofence-timetracking!76
This commit is contained in:
commit
d1910ea10d
@ -7,19 +7,17 @@ import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.ActivityCompat.requestPermissions
|
||||
import com.google.android.gms.location.*
|
||||
import de.hft.geotracker.GeofenceBroadcastReceiver
|
||||
import de.hft.geotracker.R
|
||||
import de.hft.geotracker.retrofit.AuthenticationInterceptor
|
||||
import de.hft.geotracker.retrofit.GeofenceService
|
||||
import de.hft.geotracker.retrofit.ValuesUser
|
||||
import de.hft.geotracker.retrofit.*
|
||||
import kotlinx.android.synthetic.main.activity_home.*
|
||||
import kotlinx.android.synthetic.main.dropdown_menu.*
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
@ -35,6 +33,8 @@ class MainActivity : AppCompatActivity() {
|
||||
lateinit var geofence: Geofence
|
||||
lateinit var actionButton: TextView
|
||||
var running = false
|
||||
var accName: String? = null
|
||||
lateinit var accounts: ValuesTimetrackAccounts
|
||||
lateinit var service: GeofenceService
|
||||
lateinit var locationRequest: LocationRequest
|
||||
lateinit var fusedLocationClient: FusedLocationProviderClient
|
||||
@ -80,22 +80,6 @@ class MainActivity : AppCompatActivity() {
|
||||
button_start_stop.isEnabled = btnState
|
||||
}
|
||||
|
||||
//Setup geofence
|
||||
geofencingClient = LocationServices.getGeofencingClient(this)
|
||||
geofence = Geofence.Builder().setRequestId("Test")
|
||||
.setCircularRegion(48.3575, 8.9745, 50F)
|
||||
.setExpirationDuration(Geofence.NEVER_EXPIRE)
|
||||
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT)
|
||||
.build()
|
||||
geofencingClient.addGeofences(getGeofencingRequest(), geofencePendingIntent)?.run {
|
||||
addOnSuccessListener {
|
||||
println("Geofence added")
|
||||
}
|
||||
addOnFailureListener {
|
||||
println("Error: " + it.stackTrace.forEach { println(it.toString()) })
|
||||
}
|
||||
}
|
||||
|
||||
//JWToken lesen
|
||||
val fis = openFileInput("JWToken")
|
||||
val isr = InputStreamReader(fis)
|
||||
@ -119,17 +103,31 @@ class MainActivity : AppCompatActivity() {
|
||||
service = retrofit.create(GeofenceService::class.java)
|
||||
showUsername()
|
||||
|
||||
val spinner: Spinner = findViewById(R.id.account_spinner)
|
||||
// Create an ArrayAdapter using the string array and a default spinner layout
|
||||
ArrayAdapter.createFromResource(
|
||||
this,
|
||||
R.array.accounts, android.R.layout.simple_spinner_item
|
||||
).also { adapter ->
|
||||
// Specify the layout to use when the list of choices appears
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
// Apply the adapter to the spinner
|
||||
spinner.adapter = adapter
|
||||
//Get Timetrack Accounts
|
||||
val accountNames = mutableListOf<String>()
|
||||
// accountNames.add("None")
|
||||
val call = service.getAccounts()
|
||||
call.enqueue(object: Callback<EmbeddedAccounts> {
|
||||
override fun onResponse(
|
||||
call: Call<EmbeddedAccounts>,
|
||||
response: Response<EmbeddedAccounts>
|
||||
) {
|
||||
if (response.isSuccessful) {
|
||||
accounts = response.body()!!.accounts
|
||||
accounts.entries.forEach {
|
||||
accountNames.add(it.name + "")
|
||||
}
|
||||
initializeDropdown(accountNames)
|
||||
}
|
||||
}
|
||||
override fun onFailure(call: Call<EmbeddedAccounts>, t: Throwable) {
|
||||
accountNames.add("None")
|
||||
initializeDropdown(accountNames)
|
||||
Toast.makeText(this@MainActivity, "You dont have any Timetrack Accounts ", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
})
|
||||
|
||||
actionButton = findViewById(R.id.button_start_stop)
|
||||
actionButton.setOnClickListener {
|
||||
callStartStop()
|
||||
@ -155,6 +153,24 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
private fun callStartStop() {
|
||||
running = !running
|
||||
if (running) {
|
||||
account_spinner.visibility = View.GONE
|
||||
} else {
|
||||
account_spinner.visibility = View.VISIBLE
|
||||
}
|
||||
if (!accName.isNullOrEmpty()) {
|
||||
val call = service.triggerTracking(accName!!)
|
||||
call.enqueue(object : Callback<ValuesTracking> {
|
||||
override fun onResponse(call: Call<ValuesTracking>, response: Response<ValuesTracking>) {
|
||||
latitude.text = response.body()?.startdate
|
||||
longitude.text = response.body()?.enddate
|
||||
println("Tracking event successful!")
|
||||
}
|
||||
override fun onFailure(call: Call<ValuesTracking>, t: Throwable) {
|
||||
println("Problem at start tracking: " + t.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
println("StartStop pressed: $running")
|
||||
//ToDO call /track Endpoint
|
||||
}
|
||||
@ -165,18 +181,71 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onResponse(call: Call<ValuesUser>, response: Response<ValuesUser>) {
|
||||
if (response.isSuccessful) {
|
||||
val firstname = response.body()?.firstname
|
||||
val location = response.body()?.location
|
||||
lbl_username.text = "Hello " + firstname
|
||||
println("Body: " + firstname)
|
||||
if (location?.latitude == null) {
|
||||
Toast.makeText(this@MainActivity, "No geofence set for you", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
} else {
|
||||
initializeGeofence(location?.latitude, location?.longitude, location?.radius)
|
||||
}
|
||||
} else {
|
||||
println("Response not successful: ${response.code()}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<ValuesUser>, t: Throwable) {
|
||||
println("Response 'whoami' failed")
|
||||
println("Response 'whoami' failed. " + t.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
private fun initializeDropdown(accountNames: MutableList<String>) {
|
||||
val spinner: Spinner = findViewById(R.id.account_spinner)
|
||||
// Create an ArrayAdapter using the string array and a default spinner layout
|
||||
val arrayAdapter = ArrayAdapter<String>(this, R.layout.spinner_layout, accountNames)
|
||||
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = arrayAdapter
|
||||
spinner.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>?,
|
||||
view: View?,
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
if (!accountNames.get(0).equals("None")) {
|
||||
accName = accounts.entries.get(position).name
|
||||
display_description.setText(accounts.entries.get(position).description)
|
||||
display_revenue.setText(accounts.entries.get(position).revenue.toString())
|
||||
} else {
|
||||
display_description.visibility = View.GONE
|
||||
display_description_layout.visibility = View.GONE
|
||||
display_revenue.visibility = View.GONE
|
||||
display_revenue_layout.visibility = View.GONE
|
||||
}
|
||||
println("Selected: " + accountNames.get(position))
|
||||
}
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
println("Nothing selected")
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun initializeGeofence(lat: Double, long: Double, rad: Float) {
|
||||
geofencingClient = LocationServices.getGeofencingClient(this)
|
||||
geofence = Geofence.Builder().setRequestId("Test")
|
||||
.setCircularRegion(lat, long, rad)
|
||||
.setExpirationDuration(Geofence.NEVER_EXPIRE)
|
||||
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT)
|
||||
.build()
|
||||
geofencingClient.addGeofences(getGeofencingRequest(), geofencePendingIntent)?.run {
|
||||
addOnSuccessListener {
|
||||
println("Geofence added with: latitude: $lat longitude: $long radius: $rad")
|
||||
}
|
||||
addOnFailureListener {
|
||||
println("Error: " + it.stackTrace.forEach { println(it.toString()) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGeofencingRequest(): GeofencingRequest {
|
||||
return GeofencingRequest.Builder().apply {
|
||||
|
@ -0,0 +1,8 @@
|
||||
package de.hft.geotracker.retrofit
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class EmbeddedAccounts(accounts: ValuesTimetrackAccounts) {
|
||||
@SerializedName("_embedded")
|
||||
var accounts = accounts
|
||||
}
|
@ -4,6 +4,7 @@ import retrofit2.Call
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface GeofenceService {
|
||||
@POST("/login")
|
||||
@ -11,4 +12,10 @@ interface GeofenceService {
|
||||
|
||||
@GET("whoami")
|
||||
fun getUser(): Call<ValuesUser>
|
||||
|
||||
@GET("accounts")
|
||||
fun getAccounts(): Call<EmbeddedAccounts>
|
||||
|
||||
@GET("track")
|
||||
fun triggerTracking(@Query("account") account: String): Call<ValuesTracking>
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package de.hft.geotracker.retrofit
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class ValuesLocation(
|
||||
latitude: Double,
|
||||
longitude: Double,
|
||||
radius: Int
|
||||
) {
|
||||
|
||||
@SerializedName("latitude")
|
||||
var latitude = latitude
|
||||
|
||||
@SerializedName("longitude")
|
||||
var longitude = longitude
|
||||
|
||||
@SerializedName("radius")
|
||||
var radius = radius.toFloat()
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package de.hft.geotracker.retrofit
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class ValuesTimetrackAccounts(entries: Array<ValuesTimetrackAccountsEntries>) {
|
||||
@SerializedName("accounts")
|
||||
var entries = entries
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package de.hft.geotracker.retrofit
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class ValuesTimetrackAccountsEntries(
|
||||
revenue: Double,
|
||||
name: String,
|
||||
description: String
|
||||
) {
|
||||
|
||||
@SerializedName("revenue")
|
||||
var revenue = revenue
|
||||
|
||||
@SerializedName("name")
|
||||
var name = name
|
||||
|
||||
@SerializedName("description")
|
||||
var description = description
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package de.hft.geotracker.retrofit
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class ValuesTracking(
|
||||
duration: Int,
|
||||
start: String,
|
||||
end: String,
|
||||
account: String,
|
||||
user: String,
|
||||
type: String
|
||||
) {
|
||||
@SerializedName("duration")
|
||||
var duration = duration
|
||||
|
||||
@SerializedName("startdate")
|
||||
var startdate = start
|
||||
|
||||
@SerializedName("enddate")
|
||||
var enddate = end
|
||||
|
||||
@SerializedName("account")
|
||||
var account = account
|
||||
|
||||
@SerializedName("username")
|
||||
var username = user
|
||||
|
||||
@SerializedName("type")
|
||||
var type = type
|
||||
}
|
@ -7,7 +7,7 @@ class ValuesUser(
|
||||
firstname: String,
|
||||
lastname: String,
|
||||
username: String,
|
||||
location: String,
|
||||
location: ValuesLocation,
|
||||
id: Int
|
||||
) {
|
||||
|
||||
|
@ -55,16 +55,18 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="@dimen/margin16"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:fontFamily="@font/montserrat"
|
||||
android:text="@string/timetrack_account"
|
||||
android:textAppearance="@style/text_style"
|
||||
android:textColor="@color/logo_white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/account_spinner"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/appBarLayout"
|
||||
app:layout_constraintVertical_bias="0.19" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider2"
|
||||
app:layout_constraintVertical_bias="0.0" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/button_start_stop"
|
||||
@ -91,36 +93,109 @@
|
||||
android:id="@+id/account_spinner"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/margin16"
|
||||
android:background="@color/logo_white"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@color/colorPrimary"
|
||||
android:foreground="@android:drawable/arrow_down_float"
|
||||
android:foregroundGravity="right|center_horizontal"
|
||||
android:textAlignment="textEnd"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/selected_acc"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/selected_acc" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/display_description_layout"
|
||||
style="@style/LoginTextInputLayoutStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin16"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="@dimen/margin16"
|
||||
android:colorControlNormal="@color/logo_blue"
|
||||
android:hint="Description"
|
||||
android:textColorHint="@color/logo_white"
|
||||
app:boxBackgroundColor="@color/common_google_signin_btn_text_dark_disabled"
|
||||
app:boxBackgroundMode="outline"
|
||||
app:boxCornerRadiusBottomEnd="0dp"
|
||||
app:boxCornerRadiusBottomStart="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/display_revenue_layout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/selected_acc"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_constraintVertical_chainStyle="packed">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/display_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:inputType="textPersonName"
|
||||
android:lineSpacingExtra="8sp"
|
||||
android:textAppearance="@style/text_style"
|
||||
android:textColor="@color/logo_white"
|
||||
android:textColorHint="@color/logo_white"
|
||||
android:textSize="14sp" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/display_revenue_layout"
|
||||
style="@style/LoginTextInputLayoutStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin16"
|
||||
android:layout_marginEnd="@dimen/margin16"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:colorControlNormal="@color/logo_blue"
|
||||
android:hint="Revenue"
|
||||
android:textColorHint="@color/logo_white"
|
||||
app:boxBackgroundColor="@color/common_google_signin_btn_text_dark_disabled"
|
||||
app:boxBackgroundMode="outline"
|
||||
app:boxCornerRadiusTopEnd="0dp"
|
||||
app:boxCornerRadiusTopStart="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/latitude"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/display_description_layout"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_constraintVertical_chainStyle="packed">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/display_revenue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:inputType="textPersonName"
|
||||
android:lineSpacingExtra="8sp"
|
||||
android:textAppearance="@style/text_style"
|
||||
android:textColor="@color/logo_white"
|
||||
android:textColorHint="@color/logo_white"
|
||||
android:textSize="14sp" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/altitude"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="dummy"
|
||||
android:textAppearance="@style/text_style"
|
||||
app:layout_constraintBottom_toTopOf="@+id/button_start_stop"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/longitude" />
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/latitude"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="dummy"
|
||||
android:textAppearance="@style/text_style"
|
||||
android:textColor="@color/logo_white"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/selected_acc" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/display_revenue_layout" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/longitude"
|
||||
|
@ -1,12 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.textfield.TextInputLayout style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="100dp"
|
||||
android:hint="@string/no_account"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/filled_exposed_dropdown"
|
||||
|
Loading…
Reference in New Issue
Block a user