Skip to content

Commit

Permalink
Merge pull request #33 from Team-HMH/feat/usagestatusmanager
Browse files Browse the repository at this point in the history
[Feat/usagestatusmanager] : 이용시간 통계 뷰 구현
  • Loading branch information
kez-lab authored Jan 4, 2024
2 parents 7a44c64 + e8a97ea commit 0c717a6
Show file tree
Hide file tree
Showing 55 changed files with 1,015 additions and 53 deletions.
12 changes: 12 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ android {

dependencies {

// Feature
implementation(projects.feature.statistics)

// Domain
implementation(projects.domain.usagestats)

// Data
implementation(projects.data.usagestats)

// Core
implementation(projects.core.common)

// Firebase
implementation(platform(libs.firebase))
implementation(libs.bundles.firebase)
Expand Down
19 changes: 12 additions & 7 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@

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

<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />


<application
android:name=".HMHApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -17,13 +26,10 @@
<activity
android:name=".SampleActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.App.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>
</activity>

Expand All @@ -32,15 +38,14 @@
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:host="oauth"
<data
android:host="oauth"
android:scheme="kakao${kakaoApiKey}" />
</intent-filter>
</activity>


</application>

</manifest>
9 changes: 9 additions & 0 deletions app/src/main/java/com/hmh/hamyeonham/HMHApplication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.hmh.hamyeonham

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class HMHApplication : Application() {

}
21 changes: 7 additions & 14 deletions app/src/main/java/com/hmh/hamyeonham/SampleActivity.kt
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
package com.hmh.hamyeonham

import android.content.Intent
import android.os.Bundle
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.hmh.hamyeonham.feature.login.LoginActivity
import com.kakao.sdk.common.KakaoSdk
import com.hmh.hamyeonham.feature.main.MainActivity
import com.hmh.hamyeonham.common.view.viewBinding
import com.hmh.hamyeonham.databinding.ActivitySampleBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class SampleActivity : AppCompatActivity() {
private val binding by viewBinding(ActivitySampleBinding::inflate)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val splashScreen = installSplashScreen()
initSplashAnimation(splashScreen)

setContentView(R.layout.activity_sample)

initKakaoSdk()
Intent(this, LoginActivity::class.java).let(::startActivity)
}

private fun initKakaoSdk() {
KakaoSdk.init(this, BuildConfig.KAKAO_API_KEY)
setContentView(binding.root)
}

private fun initSplashAnimation(splashScreen: SplashScreen) {
Expand Down
13 changes: 1 addition & 12 deletions app/src/main/res/layout/activity_sample.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:background="@color/white">

</androidx.constraintlayout.widget.ConstraintLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<resources>
<string name="app_name">HMH-Android</string>
<string name="usagestat_total_title">목표시간</string>
</resources>
1 change: 1 addition & 0 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="Theme.HMHAndroid" parent="Theme.Material3.Light.NoActionBar" />

<style name="Theme.App.Starting" parent="Theme.SplashScreen">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.hmh.hamyeonham.common.context

import android.app.Dialog
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Point
import android.graphics.drawable.Drawable
import android.os.Build
import android.view.View
import android.view.WindowInsets
Expand All @@ -13,6 +15,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar
import com.hmh.hamyeonham.common.R

fun Context.toast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
Expand All @@ -22,17 +25,29 @@ fun Context.longToast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show()
}

fun Context.snackBar(anchorView: View, message: () -> String) {
fun Context.snackBar(
anchorView: View,
message: () -> String,
) {
Snackbar.make(anchorView, message(), Snackbar.LENGTH_SHORT).show()
}

fun Context.stringOf(@StringRes resId: Int) = getString(resId)
fun Context.stringOf(
@StringRes resId: Int,
) = getString(resId)

fun Context.colorOf(@ColorRes resId: Int) = ContextCompat.getColor(this, resId)
fun Context.colorOf(
@ColorRes resId: Int,
) = ContextCompat.getColor(this, resId)

fun Context.drawableOf(@DrawableRes resId: Int) = ContextCompat.getDrawable(this, resId)
fun Context.drawableOf(
@DrawableRes resId: Int,
) = ContextCompat.getDrawable(this, resId)

fun Context.dialogWidthPercent(dialog: Dialog?, percent: Double = 0.8) {
fun Context.dialogWidthPercent(
dialog: Dialog?,
percent: Double = 0.8,
) {
val deviceSize = getDeviceSize()
dialog?.window?.run {
val params = attributes
Expand All @@ -48,9 +63,10 @@ fun Context.getDeviceSize(): IntArray {
val windowMetrics = windowManager.currentWindowMetrics
val windowInsets = windowMetrics.windowInsets

val insets = windowInsets.getInsetsIgnoringVisibility(
WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout()
)
val insets =
windowInsets.getInsetsIgnoringVisibility(
WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout(),
)
val insetsWidth = insets.right + insets.left
val insetsHeight = insets.top + insets.bottom

Expand All @@ -66,3 +82,21 @@ fun Context.getDeviceSize(): IntArray {
return intArrayOf(size.x, size.y)
}
}

fun Context.getAppNameFromPackageName(packageName: String): String =
try {
val appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
packageManager.getApplicationLabel(appInfo).toString()
} catch (e: PackageManager.NameNotFoundException) {
"Unknown"
}

fun Context.getAppIconFromPackageName(packageName: String): Drawable? {
try {
val appInfo = packageManager.getApplicationInfo(packageName, 0)
return appInfo.loadIcon(packageManager)
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return ContextCompat.getDrawable(this, R.drawable.ic_launcher_foreground)
}
56 changes: 44 additions & 12 deletions core/common/src/main/java/com/hmh/hamyeonham/common/time/TimeExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,58 @@ import android.text.format.DateUtils
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
import java.util.concurrent.TimeUnit

fun Instant.Companion.systemNow(): Instant = Clock.System.now()

fun Instant.toDefaultLocalDate(): LocalDate = toLocalDateTime(TimeZone.currentSystemDefault()).date

fun Long.formatDate(context: Context): String = DateUtils.formatDateTime(
context,
this,
DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_SHOW_DATE
)
fun Long.formatDate(context: Context): String =
DateUtils.formatDateTime(
context,
this,
DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_SHOW_DATE,
)

fun Instant.formatDate(context: Context): String = toEpochMilliseconds().formatDate(context)

fun Long.formatNumericDate(context: Context): String = DateUtils.formatDateTime(
context,
this,
DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NUMERIC_DATE
)
fun Long.formatNumericDate(context: Context): String =
DateUtils.formatDateTime(
context,
this,
DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NUMERIC_DATE,
)

fun Instant.formatNumericDate(context: Context): String =
toEpochMilliseconds().formatNumericDate(context)
fun Instant.formatNumericDate(context: Context): String = toEpochMilliseconds().formatNumericDate(context)

// LocalDate의 확장 함수로 해당 날짜의 시작 시간과 종료 시간을 LocalDateTime으로 반환
fun LocalDate.toStartOfDay(): LocalDateTime = LocalDateTime(year, monthNumber, dayOfMonth, 0, 0)

fun LocalDate.toEndOfDay(): LocalDateTime = LocalDateTime(year, monthNumber, dayOfMonth, 23, 59, 59)

// LocalDateTime의 확장 함수로 해당 시간을 Epoch 밀리초로 변환
fun LocalDateTime.toEpochMilliseconds(timeZone: TimeZone): Long = toInstant(timeZone).toEpochMilliseconds()

// 현재 날짜의 시작 시간과 종료 시간을 Epoch 밀리초로 반환하는 함수
fun getCurrentDayStartEndEpochMillis(): Pair<Long, Long> {
val timeZone = TimeZone.currentSystemDefault()
val currentDate = Clock.System.now().toLocalDateTime(timeZone).date
val startOfDay = currentDate.toStartOfDay().toEpochMilliseconds(timeZone)
val endOfDay = currentDate.toEndOfDay().toEpochMilliseconds(timeZone)
return Pair(startOfDay, endOfDay)
}

fun convertMillisecondsToMinute(ms: Long) = TimeUnit.MILLISECONDS.toMinutes(ms)

fun convertTimeToString(time: Long): String {
val hour = convertMillisecondsToMinute(time) / 60
val min = convertMillisecondsToMinute(time) % 60
var result = ""
if (hour > 0) result = result.plus("$hour" + "시간")
if (min >= 0) result = result.plus("$min" + "")
return result
}
30 changes: 30 additions & 0 deletions core/common/src/main/res/drawable/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
1 change: 1 addition & 0 deletions data/usagestats/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
12 changes: 12 additions & 0 deletions data/usagestats/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
hmh("feature")
}

android {
namespace = "com.hmh.hamyeonham.data.usagestats"
}

dependencies {
implementation(projects.domain.usagestats)
}
Empty file.
21 changes: 21 additions & 0 deletions data/usagestats/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
4 changes: 4 additions & 0 deletions data/usagestats/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Loading

0 comments on commit 0c717a6

Please sign in to comment.