Skip to content

Commit

Permalink
Merge pull request #141 from YAPP-Github/develop
Browse files Browse the repository at this point in the history
[TEST] 릴리즈 데모앱 배포를 진행합니다.
  • Loading branch information
MoonsuKang authored Feb 15, 2025
2 parents bbde9ae + fbdf1f3 commit 7f05e78
Show file tree
Hide file tree
Showing 233 changed files with 6,130 additions and 1,720 deletions.
7 changes: 7 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ dependencies {
implementation(projects.core.network)
implementation(projects.core.designsystem)
implementation(projects.core.datastore)
implementation(projects.core.alarm)
implementation(projects.core.media)
implementation(projects.data)
implementation(projects.domain)
implementation(projects.feature.onboarding)
implementation(projects.feature.home)
implementation(projects.feature.alarmInteraction)
implementation(projects.feature.fortune)
implementation(projects.feature.mission)
implementation(projects.feature.setting)
implementation(projects.feature.navigator)
}
56 changes: 56 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

<application
android:name=".OrbitApplication"
Expand All @@ -18,5 +23,56 @@
android:theme="@style/Theme.Orbit"
android:usesCleartextTraffic="true"
tools:targetApi="31">

<activity
android:name="com.yapp.navigator.MainActivity"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Orbit">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

<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:scheme="orbitapp"
android:host="mission"/>
</intent-filter>
</activity>

<activity
android:name="com.yapp.alarm.interaction.AlarmInteractionActivity"
android:exported="true"
android:launchMode="singleTop"
android:showOnLockScreen="true"
android:turnScreenOn="true"
android:theme="@style/Theme.Orbit">
<intent-filter>
<action android:name="com.yapp.alarm.interaction.ACTION_ALARM_INTERACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<receiver
android:name="com.yapp.alarm.receivers.AlarmReceiver"
android:exported="true" />

<receiver
android:name="com.yapp.alarm.receivers.RescheduleAlarmReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

<service
android:name="com.yapp.alarm.services.AlarmService"
android:foregroundServiceType="mediaPlayback" />
</application>
</manifest>
4 changes: 2 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<resources>
<string name="app_name">Orbit</string>
</resources>
<string name="app_name">오르비 알람</string>
</resources>
7 changes: 5 additions & 2 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Orbit" parent="android:Theme.Material.Light.NoActionBar" />
</resources>
<style name="Base.Theme.Orbit" parent="android:Theme.Material.Light.NoActionBar" />
<style name="Theme.Orbit" parent="Base.Theme.Orbit">
<item name="android:windowIsTranslucent">true</item>
</style>
</resources>
1 change: 1 addition & 0 deletions core/alarm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
17 changes: 17 additions & 0 deletions core/alarm/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import com.yapp.convention.setNamespace

plugins {
id("orbit.android.library")
id("orbit.android.hilt")
}

android {
setNamespace("core.alarm")
}

dependencies {
implementation(projects.core.datastore)
implementation(projects.core.designsystem)
implementation(projects.core.media)
implementation(projects.domain)
}
File renamed without changes.
21 changes: 21 additions & 0 deletions core/alarm/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 core/alarm/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>

</manifest>
15 changes: 15 additions & 0 deletions core/alarm/src/main/java/com/yapp/alarm/AlarmConstants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.yapp.alarm

object AlarmConstants {
const val ACTION_ALARM_TRIGGERED = "com.yapp.orbit.ACTION_TRIGGERED"
const val ACTION_ALARM_DISMISSED = "com.yapp.orbit.ACTION_DISMISSED"
const val ACTION_ALARM_SNOOZED = "com.yapp.orbit.ACTION_SNOOZED"
const val ACTION_ALARM_INTERACTION_ACTIVITY_CLOSE = "com.yapp.orbit.ACTION_ALERT_INTERACTION_CLOSE"

const val EXTRA_NOTIFICATION_ID = "com.yapp.orbit.EXTRA_NOTIFICATION_ID"

const val EXTRA_ALARM = "com.yapp.orbit.EXTRA_ALARM"

const val EXTRA_IS_SNOOZED = "com.yapp.orbit.EXTRA_IS_SNOOZED"
const val EXTRA_IS_DISMISS = "com.yapp.orbit.EXTRA_IS_DISMISS"
}
117 changes: 117 additions & 0 deletions core/alarm/src/main/java/com/yapp/alarm/AlarmHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.yapp.alarm

import android.app.AlarmManager
import android.app.Application
import android.content.Intent
import android.util.Log
import com.yapp.alarm.pendingIntent.schedule.createAlarmReceiverPendingIntentForSchedule
import com.yapp.alarm.pendingIntent.schedule.createAlarmReceiverPendingIntentForUnSchedule
import com.yapp.alarm.services.AlarmService
import com.yapp.domain.model.Alarm
import com.yapp.domain.model.AlarmDay
import com.yapp.domain.model.toAlarmDays
import com.yapp.domain.model.toDayOfWeek
import java.time.LocalDateTime
import java.time.ZoneId
import javax.inject.Inject

class AlarmHelper @Inject constructor(
private val app: Application,
private val alarmManager: AlarmManager,
) {
fun scheduleAlarm(alarm: Alarm) {
val selectedDays = alarm.repeatDays.toAlarmDays()

if (selectedDays.isEmpty()) {
setNonRepeatingAlarm(alarm)
} else {
selectedDays.forEach { day ->
setRepeatingAlarm(day, alarm)
}
}
}

fun unScheduleAlarm(alarm: Alarm) {
val selectedDays = alarm.repeatDays.toAlarmDays()

if (selectedDays.isEmpty()) {
val pendingIntent = createAlarmReceiverPendingIntentForUnSchedule(
app,
alarm,
null,
)
alarmManager.cancel(pendingIntent)
} else {
selectedDays.forEach { day ->
val pendingIntent = createAlarmReceiverPendingIntentForUnSchedule(
app,
alarm,
day,
)
alarmManager.cancel(pendingIntent)
}
}
}

fun stopAlarm() {
app.stopService(Intent(app, AlarmService::class.java))
}

private fun setRepeatingAlarm(day: AlarmDay, alarm: Alarm) {
val alarmReceiverPendingIntent =
createAlarmReceiverPendingIntentForSchedule(app, alarm, day)
val firstAlarmTriggerMillis = getNextAlarmTimeMillis(alarm, day)

Log.d("AlarmHelper", "Setting repeating alarm at: $firstAlarmTriggerMillis")

alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
firstAlarmTriggerMillis,
alarmReceiverPendingIntent,
)
}

private fun setNonRepeatingAlarm(alarm: Alarm) {
val alarmReceiverPendingIntent =
createAlarmReceiverPendingIntentForSchedule(app, alarm)

val triggerMillis = getNextAlarmTimeMillis(alarm, null)

Log.d("AlarmHelper", "Setting one-time alarm at: $triggerMillis")

alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
triggerMillis,
alarmReceiverPendingIntent,
)
}

private fun getNextAlarmTimeMillis(alarm: Alarm, day: AlarmDay?): Long {
val now = LocalDateTime.now().withNano(0) // 밀리초 제거하여 정확한 초 기준 설정

val alarmHour = when {
alarm.isAm && alarm.hour == 12 -> 0
!alarm.isAm && alarm.hour != 12 -> alarm.hour + 12
else -> alarm.hour
}

var alarmDateTime = now.withHour(alarmHour).withMinute(alarm.minute).withSecond(alarm.second)

if (day != null) {
val targetDayOfWeek = day.toDayOfWeek()
while (alarmDateTime.dayOfWeek != targetDayOfWeek || alarmDateTime.isBefore(now)) {
alarmDateTime = alarmDateTime.plusDays(1)
}
} else {
if (alarmDateTime.isBefore(now)) {
alarmDateTime = alarmDateTime.plusDays(1)
}
}

val epochMillis = alarmDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()

Log.d("AlarmHelper", "Alarm scheduled at: $alarmDateTime (epochMillis=$epochMillis)")

return epochMillis
}
}
21 changes: 21 additions & 0 deletions core/alarm/src/main/java/com/yapp/alarm/AlarmModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.yapp.alarm

import android.app.AlarmManager
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AlarmModule {

@Provides
@Singleton
fun provideAlarmManager(@ApplicationContext context: Context): AlarmManager {
return context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.yapp.alarm.pendingIntent.interaction

import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.content.Context
import android.content.Intent
import com.yapp.alarm.AlarmConstants
import com.yapp.domain.model.Alarm

fun createAlarmAlertPendingIntent(
context: Context,
alarm: Alarm,
): PendingIntent {
val alarmAlertIntent = createAlarmAlertIntent(
alarm.id,
alarm,
)
return PendingIntent.getActivity(
context,
alarm.id.toInt(),
alarmAlertIntent,
PendingIntent.FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE,
)
}

private fun createAlarmAlertIntent(
notificationId: Long,
alarm: Alarm,
): Intent {
return Intent("com.yapp.alarm.interaction.ACTION_ALARM_INTERACTION").apply {
putExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, notificationId)
putExtra(AlarmConstants.EXTRA_ALARM, alarm)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.yapp.alarm.pendingIntent.interaction

import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
import android.content.Intent
import com.yapp.alarm.AlarmConstants
import com.yapp.alarm.receivers.AlarmReceiver

fun createAlarmDismissPendingIntent(
applicationContext: Context,
pendingIntentId: Long,
): PendingIntent {
val alarmDismissIntent = createAlarmDismissIntent(applicationContext, pendingIntentId)
return PendingIntent.getBroadcast(
applicationContext,
pendingIntentId.toInt(),
alarmDismissIntent,
FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE,
)
}

fun createAlarmDismissIntent(
context: Context,
notificationId: Long,
): Intent {
return Intent(AlarmConstants.ACTION_ALARM_DISMISSED).apply {
setClass(context, AlarmReceiver::class.java)
putExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, notificationId)
}
}
Loading

0 comments on commit 7f05e78

Please sign in to comment.