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
111 changes: 111 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Android foundation

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: android-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
host:
name: Build, lint and unit tests
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '21'
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
- name: Install isolated Android SDK
shell: bash
run: |
set -euo pipefail
sdk_dir="$RUNNER_TEMP/acetimetracker-sdk"
cli_zip="$RUNNER_TEMP/android-commandlinetools.zip"
curl --fail --location --retry 3 \
https://dl.google.com/android/repository/commandlinetools-linux-16111833_latest.zip \
-o "$cli_zip"
echo "e025545c62a8e64c7559119566a569fb1dec5f60 $cli_zip" | sha1sum --check --strict
mkdir -p "$sdk_dir/cmdline-tools"
unzip -q "$cli_zip" -d "$RUNNER_TEMP/android-cli"
mv "$RUNNER_TEMP/android-cli/cmdline-tools" "$sdk_dir/cmdline-tools/23.0"
export ANDROID_HOME="$sdk_dir"
export ANDROID_SDK_ROOT="$sdk_dir"
manager="$sdk_dir/cmdline-tools/23.0/bin/sdkmanager"
# yes can receive SIGPIPE once sdkmanager has accepted all licenses.
set +o pipefail
yes | "$manager" --sdk_root="$sdk_dir" --licenses >/dev/null
set -o pipefail
"$manager" --sdk_root="$sdk_dir" 'platforms;android-37.0' 'build-tools;36.0.0' platform-tools
echo "ANDROID_HOME=$sdk_dir" >> "$GITHUB_ENV"
echo "ANDROID_SDK_ROOT=$sdk_dir" >> "$GITHUB_ENV"
echo "$sdk_dir/cmdline-tools/23.0/bin" >> "$GITHUB_PATH"
echo "$sdk_dir/platform-tools" >> "$GITHUB_PATH"
- name: Verify toolchain
run: ./gradlew --version
- name: Host acceptance checks
run: >-
./gradlew --no-daemon --stacktrace
:app:checkDebugAarMetadata :app:assembleDebug :app:assembleDebugAndroidTest
:app:lintDebug :app:testDebugUnitTest

api27:
name: API 27 package smoke
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '21'
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
- name: Install isolated Android SDK
shell: bash
run: |
set -euo pipefail
sdk_dir="$RUNNER_TEMP/acetimetracker-sdk"
cli_zip="$RUNNER_TEMP/android-commandlinetools.zip"
curl --fail --location --retry 3 \
https://dl.google.com/android/repository/commandlinetools-linux-16111833_latest.zip \
-o "$cli_zip"
echo "e025545c62a8e64c7559119566a569fb1dec5f60 $cli_zip" | sha1sum --check --strict
mkdir -p "$sdk_dir/cmdline-tools"
unzip -q "$cli_zip" -d "$RUNNER_TEMP/android-cli"
mv "$RUNNER_TEMP/android-cli/cmdline-tools" "$sdk_dir/cmdline-tools/23.0"
export ANDROID_HOME="$sdk_dir"
export ANDROID_SDK_ROOT="$sdk_dir"
manager="$sdk_dir/cmdline-tools/23.0/bin/sdkmanager"
# yes can receive SIGPIPE once sdkmanager has accepted all licenses.
set +o pipefail
yes | "$manager" --sdk_root="$sdk_dir" --licenses >/dev/null
set -o pipefail
"$manager" --sdk_root="$sdk_dir" 'platforms;android-37.0' 'build-tools;36.0.0' platform-tools
echo "ANDROID_HOME=$sdk_dir" >> "$GITHUB_ENV"
echo "ANDROID_SDK_ROOT=$sdk_dir" >> "$GITHUB_ENV"
echo "$sdk_dir/cmdline-tools/23.0/bin" >> "$GITHUB_PATH"
echo "$sdk_dir/platform-tools" >> "$GITHUB_PATH"
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Package instrumentation on clean API 27
uses: ReactiveCircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2
with:
api-level: 27
target: default
arch: x86_64
avd-name: foundation-api27
force-avd-creation: true
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -wipe-data
script: ./gradlew --no-daemon --stacktrace :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.acetimetracker.ExampleInstrumentedTest
86 changes: 48 additions & 38 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
alias(libs.plugins.android.application)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.google.services)
}

android {
namespace = "com.example.acetimetracker"
compileSdk = 34
compileSdk = 37

defaultConfig {
applicationId = "com.example.acetimetracker"
minSdk = 27
// Task 2 owns the target-36 system-bar and Back compatibility change.
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

Expand All @@ -28,46 +30,54 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
compose = true
}
}

dependencies {

implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("pl.droidsonroids.gif:android-gif-drawable:1.2.28")
implementation("com.google.firebase:firebase-auth:23.0.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.1")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
implementation("androidx.annotation:annotation:1.7.1")
implementation("com.google.firebase:firebase-database:21.0.0")
implementation("com.google.firebase:firebase-firestore:25.0.0")
implementation("com.google.firebase:firebase-storage:21.0.0")
implementation ("com.github.bumptech.glide:glide:4.16.0")
implementation ("com.github.PhilJay:MPAndroidChart:v3.1.0")
implementation ("com.airbnb.android:lottie:5.2.0")
dependencies {
implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13")
// To use constraintlayout in compose

implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13")
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

dependencies {
implementation(libs.androidx.core)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.constraintlayout)
implementation(libs.gif)
implementation(libs.androidx.lifecycle.livedata)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.navigation.ui)
implementation(libs.androidx.annotation)
implementation(libs.glide)
implementation(libs.mpandroidchart)
implementation(libs.lottie)

implementation(platform(libs.firebase.bom))
implementation(libs.firebase.auth)
implementation(libs.firebase.database)
implementation(libs.firebase.firestore)
implementation(libs.firebase.storage)

}
implementation(platform(libs.compose.bom))
implementation(libs.androidx.activity.compose)
implementation(libs.compose.ui)
implementation(libs.compose.material3)
debugImplementation(libs.compose.ui.tooling.preview)
debugImplementation(libs.compose.ui.tooling)
debugImplementation(libs.compose.ui.test.manifest)

testImplementation(libs.junit)
androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.compose.ui.test.junit4)
androidTestImplementation(libs.android.test.runner)
androidTestImplementation(libs.android.test.junit)
androidTestImplementation(libs.espresso.core)
}
17 changes: 17 additions & 0 deletions app/src/debug/java/com/example/acetimetracker/FoundationPreview.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.acetimetracker

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

@Preview
@Composable
internal fun FoundationPreview() {
MaterialTheme {
Surface {
Text("AceTimeTracker")
}
}
}
8 changes: 1 addition & 7 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.acetimetracker">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Expand Down Expand Up @@ -42,11 +41,6 @@
<activity
android:name=".settings"
android:exported="false" />
<activity
android:name=".timetracker"
android:exported="false"
android:label="@string/title_activity_timetracker"
android:theme="@style/Widget.AppCompat.PopupMenu" />
<activity
android:name=".Registration"
android:exported="false" />
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/example/acetimetracker/Login.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import com.google.firebase.auth.auth
import com.google.firebase.Firebase

class Login : AppCompatActivity() {

Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/example/acetimetracker/TimeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ object TimeUtils {
val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())

return try {
val startDate = timeFormat.parse(startTime)
val endDate = timeFormat.parse(endTime)
val startDate = requireNotNull(timeFormat.parse(startTime))
val endDate = requireNotNull(timeFormat.parse(endTime))

// Calculate the difference in milliseconds
val difference = endDate.time - startDate.time
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/example/acetimetracker/Timesheet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ class Timesheet : AppCompatActivity() {
private fun calculateTimeSpent(startTime: String, endTime: String): Long {
val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
return try {
val startDate = timeFormat.parse(startTime)
val endDate = timeFormat.parse(endTime)
val startDate = requireNotNull(timeFormat.parse(startTime))
val endDate = requireNotNull(timeFormat.parse(endTime))
endDate.time - startDate.time
} catch (e: Exception) {
Log.e("TimesheetActivity", "Error calculating time spent", e)
Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
It aims to provide a user-friendly interface for tracking time and managing tasks efficiently.
This application is developed by Mpho Ndlela.
We hope it helps you study better and ACE IT!!.</string>
We hope it helps you study better and ACE IT !!
<string name="btn_upload_image">Upload Image</string>
<string name="enter_end_date">Enter End Date</string>
<string name="enter_end_time">Enter End Time</string>
Expand Down
14 changes: 8 additions & 6 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
buildscript {
dependencies {
classpath("com.google.gms:google-services:4.4.1")
// AGP's built-in Kotlin runtime must match the catalog's Compose compiler.
// The bootstrap classpath is resolved before catalog accessors are available.
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.4.21")
}
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {

id("com.android.application") version "8.1.4" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.google.services) apply false
}
Loading