Skip to content

Commit

Permalink
Working
Browse files Browse the repository at this point in the history
  • Loading branch information
devrath committed Jan 4, 2024
1 parent 50daef5 commit 9fbe701
Show file tree
Hide file tree
Showing 3 changed files with 317 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -1,88 +1,76 @@
package com.istudio.app

import android.Manifest
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.app.ActivityCompat
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.istudio.app.service.StopwatchService
import com.istudio.app.ui.theme.StopWatchServiceAppTheme
import dagger.hilt.android.AndroidEntryPoint

@OptIn(ExperimentalAnimationApi::class)
@ExperimentalAnimationApi
@AndroidEntryPoint
class MainActivity : ComponentActivity() {

private var isBound by mutableStateOf(false)
private lateinit var stopwatchService: StopwatchService
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as StopwatchService.StopwatchBinder
stopwatchService = binder.getService()
isBound = true
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
override fun onServiceDisconnected(arg0: ComponentName) {
isBound = false
}
}

if (Build.VERSION.SDK_INT >= (Build.VERSION_CODES.TIRAMISU)) {
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0
)
override fun onStart() {
super.onStart()
Intent(this, StopwatchService::class.java).also { intent ->
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
StopWatchServiceAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
CurrentScreen()
if (isBound) {
MainScreen(stopwatchService = stopwatchService)
}
}
}
requestPermissions(Manifest.permission.POST_NOTIFICATIONS)
}
}


@Composable
fun CurrentScreen() {

val context = LocalContext.current

Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button(onClick = {
Intent(context,StopwatchService::class.java).also {
it.action = StopwatchService.Actions.START.toString()
context.startService(it)
private fun requestPermissions(vararg permissions: String) {
val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { result ->
result.entries.forEach {
Log.d("MainActivity", "${it.key} = ${it.value}")
}
}) {
Text(text = "Start Service")
}
Button(onClick = {
Intent(context,StopwatchService::class.java).also {
it.action = StopwatchService.Actions.STOP.toString()
context.startService(it)
}
}) {
Text(text = "Stop Service")
}
requestPermissionLauncher.launch(permissions.asList().toTypedArray())
}
}


@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
StopWatchServiceAppTheme {
CurrentScreen()
override fun onStop() {
super.onStop()
unbindService(connection)
isBound = false
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,133 @@
package com.istudio.app

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable
import android.annotation.SuppressLint
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.animation.ContentTransform
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.with
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import com.istudio.app.service.ServiceHelper
import com.istudio.app.service.StopwatchService
import com.istudio.app.util.Constants.ACTION_SERVICE_CANCEL
import com.istudio.app.util.Constants.ACTION_SERVICE_START
import com.istudio.app.util.Constants.ACTION_SERVICE_STOP
import com.istudio.app.util.StopwatchState

@SuppressLint("UnusedContentLambdaTargetStateParameter")
@ExperimentalAnimationApi
@Composable
fun MainScreen(stopwatchService: StopwatchService) {

val context = LocalContext.current
val hours by stopwatchService.hours
val minutes by stopwatchService.minutes
val seconds by stopwatchService.seconds
val currentState by stopwatchService.currentState

Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surface)
.padding(30.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(
modifier = Modifier.weight(weight = 9f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
AnimatedContent(targetState = hours, transitionSpec = { addAnimation() }, label = "") {
Text(
text = hours,
style = TextStyle(
fontSize = MaterialTheme.typography.titleLarge.fontSize,
fontWeight = FontWeight.Bold,
color = if (hours == "00") Color.White else Color.Blue
)
)
}
AnimatedContent(targetState = minutes, transitionSpec = { addAnimation() }, label = "") {
Text(
text = minutes, style = TextStyle(
fontSize = MaterialTheme.typography.titleLarge.fontSize,
fontWeight = FontWeight.Bold,
color = if (hours == "00") Color.White else Color.Blue
)
)
}
AnimatedContent(targetState = seconds, transitionSpec = { addAnimation() }, label = "") {
Text(
text = seconds, style = TextStyle(
fontSize = MaterialTheme.typography.titleLarge.fontSize,
fontWeight = FontWeight.Bold,
color = if (hours == "00") Color.White else Color.Blue
)
)
}
}
Row(modifier = Modifier.weight(weight = 1f)) {
Button(
modifier = Modifier
.weight(1f)
.fillMaxHeight(0.8f),
onClick = {
ServiceHelper.triggerForegroundService(
context = context,
action = if (currentState == StopwatchState.Started) ACTION_SERVICE_STOP
else ACTION_SERVICE_START
)
}, colors = ButtonDefaults.buttonColors(
containerColor = if (currentState == StopwatchState.Started) Color.Red else Color.Blue,
contentColor = Color.White
)
) {
Text(
text = if (currentState == StopwatchState.Started) "Stop"
else if ((currentState == StopwatchState.Stopped)) "Resume"
else "Start"
)
}
Spacer(modifier = Modifier.width(30.dp))
Button(
modifier = Modifier
.weight(1f)
.fillMaxHeight(0.8f),
onClick = {
ServiceHelper.triggerForegroundService(
context = context, action = ACTION_SERVICE_CANCEL
)
},
enabled = seconds != "00" && currentState != StopwatchState.Started,
colors = ButtonDefaults.buttonColors(containerColor = Color.Gray)
) {
Text(text = "Cancel")
}
}
}
}


@ExperimentalAnimationApi
fun addAnimation(duration: Int = 600): ContentTransform {
return slideInVertically(animationSpec = tween(durationMillis = duration)) { height -> height } + fadeIn(
animationSpec = tween(durationMillis = duration)
) with slideOutVertically(animationSpec = tween(durationMillis = duration)) { height -> height } + fadeOut(
animationSpec = tween(durationMillis = duration)
)
}
Loading

0 comments on commit 9fbe701

Please sign in to comment.