معماری پیشنهادی
الگو: Clean Architecture + MVVM
Copy code
presentation (UI)
domain (Business Logic)
data (Repository + DataSource)
core (Utils, Helpers)
📂 ساختار کامل فولدرها
Copy code
com.yourpackage.ramadanapp
│
├── data
│ ├── repository
│ │ └── PrayerRepositoryImpl.kt
│ │
│ ├── datasource
│ │ ├── local
│ │ │ ├── AppDatabase.kt
│ │ │ ├── CityDao.kt
│ │ │ └── SettingsDao.kt
│ │ │
│ │ └── remote (اختیاری)
│ │
│ └── model
│ ├── CityEntity.kt
│ └── SettingsEntity.kt
│
├── domain
│ ├── model
│ │ ├── PrayerTimes.kt
│ │ └── City.kt
│ │
│ ├── repository
│ │ └── PrayerRepository.kt
│ │
│ └── usecase
│ ├── GetPrayerTimesUseCase.kt
│ ├── SchedulePrayerAlarmUseCase.kt
│ └── GetCurrentCityUseCase.kt
│
├── presentation
│ ├── main
│ │ ├── MainActivity.kt
│ │ ├── MainViewModel.kt
│ │ └── MainState.kt
│ │
│ ├── settings
│ │ ├── SettingsActivity.kt
│ │ └── SettingsViewModel.kt
│ │
│ └── calendar
│ ├── RamadanCalendarActivity.kt
│ └── CalendarViewModel.kt
│
├── alarm
│ ├── PrayerAlarmReceiver.kt
│ ├── BootReceiver.kt
│ └── AlarmScheduler.kt
│
├── location
│ └── LocationProvider.kt
│
├── adhan
│ └── AdhanPlayer.kt
│
├── core
│ ├── PrayerTimeCalculator.kt
│ ├── HijriCalendarUtil.kt
│ ├── PersianCalendarUtil.kt
│ └── Constants.kt
│
└── di
└── AppModule.kt
🕌 لایه Domain
PrayerRepository.kt
Copy code
Kotlin
interface PrayerRepository {
fun getPrayerTimes(city: City, date: Date): PrayerTimes
suspend fun saveCity(city: City)
suspend fun getSavedCity(): City
}
GetPrayerTimesUseCase.kt
Copy code
Kotlin
class GetPrayerTimesUseCase(
private val repository: PrayerRepository
) {
operator fun invoke(city: City, date: Date): PrayerTimes {
return repository.getPrayerTimes(city, date)
}
}
🧠 PrayerTimeCalculator (Core)
استفاده از کتابخانه Adhan:
Copy code
Kotlin
object PrayerTimeCalculator {
fun calculate(lat: Double, lng: Double, date: Date): PrayerTimes {
val coordinates = Coordinates(lat, lng)
val params = CalculationMethod.MUSLIM_WORLD_LEAGUE.parameters
return PrayerTimes(coordinates, date, params)
}
}
⏰ سیستم آلارم
AlarmScheduler.kt
Copy code
Kotlin
class AlarmScheduler(private val context: Context) {
fun scheduleAlarm(timeInMillis: Long, requestCode: Int) {
val intent = Intent(context, PrayerAlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
context,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
timeInMillis,
pendingIntent
)
}
}
PrayerAlarmReceiver.kt
Copy code
Kotlin
class PrayerAlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
AdhanPlayer.play(context)
}
}
📢 AdhanPlayer
Copy code
Kotlin
object AdhanPlayer {
private var mediaPlayer: MediaPlayer? = null
fun play(context: Context) {
mediaPlayer = MediaPlayer.create(context, R.raw.adhan)
mediaPlayer?.start()
}
fun stop() {
mediaPlayer?.release()
mediaPlayer = null
}
}
📍 LocationProvider
Copy code
Kotlin
class LocationProvider(private val context: Context) {
private val fusedClient =
LocationServices.getFusedLocationProviderClient(context)
fun getLastLocation(onResult: (Location?) -> Unit) {
fusedClient.lastLocation.addOnSuccessListener {
onResult(it)
}
}
}
📅 تقویم شمسی و قمری
PersianCalendarUtil
برای تاریخ شمسی از کتابخانه PersianCalendar
HijriCalendarUtil
میتوانی از:
Copy code
Kotlin
val hijri = HijrahDate.now()
📱 MainViewModel
Copy code
Kotlin
class MainViewModel(
private val getPrayerTimesUseCase: GetPrayerTimesUseCase
) : ViewModel() {
private val _state = MutableStateFlow<MainState>(MainState())
val state: StateFlow<MainState> = _state
fun loadPrayerTimes(city: City) {
val times = getPrayerTimesUseCase(city, Date())
_state.value = MainState(prayerTimes = times)
}
}
🔐 AndroidManifest موارد مهم
Copy code
Xml
🛠 وابستگیهای Gradle
Copy code
Kotlin
implementation "com.google.android.gms:play-services-location:21.0.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation "androidx.room:room-runtime:2.5.2"
implementation "androidx.room:room-ktx:2.5.2"
implementation "com.batoulapps.adhan:adhan:1.2.1"
🎛 قابلیتهای حرفهای پیشنهادی
Foreground Service هنگام پخش اذان
Notification با دکمه Stop
ویجت صفحه اصلی
Material 3 UI
Dark Mode
Backup تنظیمات
چند مؤذن
🚀 نتیجه
با این ساختار:
✔ کاملاً مقیاسپذیر
✔ قابل انتشار در گوگلپلی
✔ استاندارد معماری
✔ آماده توسعه آیندهمعماری پیشنهادی
الگو: Clean Architecture + MVVM
Copy code
presentation (UI)
domain (Business Logic)
data (Repository + DataSource)
core (Utils, Helpers)
📂 ساختار کامل فولدرها
Copy code
com.yourpackage.ramadanapp
│
├── data
│ ├── repository
│ │ └── PrayerRepositoryImpl.kt
│ │
│ ├── datasource
│ │ ├── local
│ │ │ ├── AppDatabase.kt
│ │ │ ├── CityDao.kt
│ │ │ └── SettingsDao.kt
│ │ │
│ │ └── remote (اختیاری)
│ │
│ └── model
│ ├── CityEntity.kt
│ └── SettingsEntity.kt
│
├── domain
│ ├── model
│ │ ├── PrayerTimes.kt
│ │ └── City.kt
│ │
│ ├── repository
│ │ └── PrayerRepository.kt
│ │
│ └── usecase
│ ├── GetPrayerTimesUseCase.kt
│ ├── SchedulePrayerAlarmUseCase.kt
│ └── GetCurrentCityUseCase.kt
│
├── presentation
│ ├── main
│ │ ├── MainActivity.kt
│ │ ├── MainViewModel.kt
│ │ └── MainState.kt
│ │
│ ├── settings
│ │ ├── SettingsActivity.kt
│ │ └── SettingsViewModel.kt
│ │
│ └── calendar
│ ├── RamadanCalendarActivity.kt
│ └── CalendarViewModel.kt
│
├── alarm
│ ├── PrayerAlarmReceiver.kt
│ ├── BootReceiver.kt
│ └── AlarmScheduler.kt
│
├── location
│ └── LocationProvider.kt
│
├── adhan
│ └── AdhanPlayer.kt
│
├── core
│ ├── PrayerTimeCalculator.kt
│ ├── HijriCalendarUtil.kt
│ ├── PersianCalendarUtil.kt
│ └── Constants.kt
│
└── di
└── AppModule.kt
🕌 لایه Domain
PrayerRepository.kt
Copy code
Kotlin
interface PrayerRepository {
fun getPrayerTimes(city: City, date: Date): PrayerTimes
suspend fun saveCity(city: City)
suspend fun getSavedCity(): City
}
GetPrayerTimesUseCase.kt
Copy code
Kotlin
class GetPrayerTimesUseCase(
private val repository: PrayerRepository
) {
operator fun invoke(city: City, date: Date): PrayerTimes {
return repository.getPrayerTimes(city, date)
}
}
🧠 PrayerTimeCalculator (Core)
استفاده از کتابخانه Adhan:
Copy code
Kotlin
object PrayerTimeCalculator {
fun calculate(lat: Double, lng: Double, date: Date): PrayerTimes {
val coordinates = Coordinates(lat, lng)
val params = CalculationMethod.MUSLIM_WORLD_LEAGUE.parameters
return PrayerTimes(coordinates, date, params)
}
}
⏰ سیستم آلارم
AlarmScheduler.kt
Copy code
Kotlin
class AlarmScheduler(private val context: Context) {
fun scheduleAlarm(timeInMillis: Long, requestCode: Int) {
val intent = Intent(context, PrayerAlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
context,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
timeInMillis,
pendingIntent
)
}
}
PrayerAlarmReceiver.kt
Copy code
Kotlin
class PrayerAlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
AdhanPlayer.play(context)
}
}
📢 AdhanPlayer
Copy code
Kotlin
object AdhanPlayer {
private var mediaPlayer: MediaPlayer? = null
fun play(context: Context) {
mediaPlayer = MediaPlayer.create(context, R.raw.adhan)
mediaPlayer?.start()
}
fun stop() {
mediaPlayer?.release()
mediaPlayer = null
}
}
📍 LocationProvider
Copy code
Kotlin
class LocationProvider(private val context: Context) {
private val fusedClient =
LocationServices.getFusedLocationProviderClient(context)
fun getLastLocation(onResult: (Location?) -> Unit) {
fusedClient.lastLocation.addOnSuccessListener {
onResult(it)
}
}
}
📅 تقویم شمسی و قمری
PersianCalendarUtil
برای تاریخ شمسی از کتابخانه PersianCalendar
HijriCalendarUtil
میتوانی از:
Copy code
Kotlin
val hijri = HijrahDate.now()
📱 MainViewModel
Copy code
Kotlin
class MainViewModel(
private val getPrayerTimesUseCase: GetPrayerTimesUseCase
) : ViewModel() {
private val _state = MutableStateFlow<MainState>(MainState())
val state: StateFlow<MainState> = _state
fun loadPrayerTimes(city: City) {
val times = getPrayerTimesUseCase(city, Date())
_state.value = MainState(prayerTimes = times)
}
}
🔐 AndroidManifest موارد مهم
Copy code
Xml
🛠 وابستگیهای Gradle
Copy code
Kotlin
implementation "com.google.android.gms:play-services-location:21.0.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation "androidx.room:room-runtime:2.5.2"
implementation "androidx.room:room-ktx:2.5.2"
implementation "com.batoulapps.adhan:adhan:1.2.1"
🎛 قابلیتهای حرفهای پیشنهادی
Foreground Service هنگام پخش اذان
Notification با دکمه Stop
ویجت صفحه اصلی
Material 3 UI
Dark Mode
Backup تنظیمات
چند مؤذن
🚀 نتیجه
با این ساختار:
✔ کاملاً مقیاسپذیر
✔ قابل انتشار در گوگلپلی
✔ استاندارد معماری
✔ آماده توسعه آینده
معماری پیشنهادی
الگو: Clean Architecture + MVVM
Copy code
presentation (UI)
domain (Business Logic)
data (Repository + DataSource)
core (Utils, Helpers)
📂 ساختار کامل فولدرها
Copy code
com.yourpackage.ramadanapp
│
├── data
│ ├── repository
│ │ └── PrayerRepositoryImpl.kt
│ │
│ ├── datasource
│ │ ├── local
│ │ │ ├── AppDatabase.kt
│ │ │ ├── CityDao.kt
│ │ │ └── SettingsDao.kt
│ │ │
│ │ └── remote (اختیاری)
│ │
│ └── model
│ ├── CityEntity.kt
│ └── SettingsEntity.kt
│
├── domain
│ ├── model
│ │ ├── PrayerTimes.kt
│ │ └── City.kt
│ │
│ ├── repository
│ │ └── PrayerRepository.kt
│ │
│ └── usecase
│ ├── GetPrayerTimesUseCase.kt
│ ├── SchedulePrayerAlarmUseCase.kt
│ └── GetCurrentCityUseCase.kt
│
├── presentation
│ ├── main
│ │ ├── MainActivity.kt
│ │ ├── MainViewModel.kt
│ │ └── MainState.kt
│ │
│ ├── settings
│ │ ├── SettingsActivity.kt
│ │ └── SettingsViewModel.kt
│ │
│ └── calendar
│ ├── RamadanCalendarActivity.kt
│ └── CalendarViewModel.kt
│
├── alarm
│ ├── PrayerAlarmReceiver.kt
│ ├── BootReceiver.kt
│ └── AlarmScheduler.kt
│
├── location
│ └── LocationProvider.kt
│
├── adhan
│ └── AdhanPlayer.kt
│
├── core
│ ├── PrayerTimeCalculator.kt
│ ├── HijriCalendarUtil.kt
│ ├── PersianCalendarUtil.kt
│ └── Constants.kt
│
└── di
└── AppModule.kt
🕌 لایه Domain
PrayerRepository.kt
Copy code
Kotlin
interface PrayerRepository {
fun getPrayerTimes(city: City, date: Date): PrayerTimes
suspend fun saveCity(city: City)
suspend fun getSavedCity(): City
}
GetPrayerTimesUseCase.kt
Copy code
Kotlin
class GetPrayerTimesUseCase(
private val repository: PrayerRepository
) {
operator fun invoke(city: City, date: Date): PrayerTimes {
return repository.getPrayerTimes(city, date)
}
}
🧠 PrayerTimeCalculator (Core)
استفاده از کتابخانه Adhan:
Copy code
Kotlin
object PrayerTimeCalculator {
}
⏰ سیستم آلارم
AlarmScheduler.kt
Copy code
Kotlin
class AlarmScheduler(private val context: Context) {
}
PrayerAlarmReceiver.kt
Copy code
Kotlin
class PrayerAlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
AdhanPlayer.play(context)
}
}
📢 AdhanPlayer
Copy code
Kotlin
object AdhanPlayer {
}
📍 LocationProvider
Copy code
Kotlin
class LocationProvider(private val context: Context) {
}
📅 تقویم شمسی و قمری
PersianCalendarUtil
برای تاریخ شمسی از کتابخانه PersianCalendar
HijriCalendarUtil
میتوانی از:
Copy code
Kotlin
val hijri = HijrahDate.now()
📱 MainViewModel
Copy code
Kotlin
class MainViewModel(
private val getPrayerTimesUseCase: GetPrayerTimesUseCase
) : ViewModel() {
}
🛠 وابستگیهای Gradle Copy code Kotlin implementation "com.google.android.gms:play-services-location:21.0.1" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1" implementation "androidx.room:room-runtime:2.5.2" implementation "androidx.room:room-ktx:2.5.2" implementation "com.batoulapps.adhan:adhan:1.2.1" 🎛 قابلیتهای حرفهای پیشنهادی Foreground Service هنگام پخش اذان Notification با دکمه Stop ویجت صفحه اصلی Material 3 UI Dark Mode Backup تنظیمات چند مؤذن 🚀 نتیجه با این ساختار: ✔ کاملاً مقیاسپذیر ✔ قابل انتشار در گوگلپلی ✔ استاندارد معماری ✔ آماده توسعه آیندهمعماری پیشنهادی الگو: Clean Architecture + MVVM Copy code🔐 AndroidManifest موارد مهم
Copy code
Xml
presentation (UI)
domain (Business Logic)
data (Repository + DataSource)
core (Utils, Helpers)
📂 ساختار کامل فولدرها
Copy code
com.yourpackage.ramadanapp
│
├── data
│ ├── repository
│ │ └── PrayerRepositoryImpl.kt
│ │
│ ├── datasource
│ │ ├── local
│ │ │ ├── AppDatabase.kt
│ │ │ ├── CityDao.kt
│ │ │ └── SettingsDao.kt
│ │ │
│ │ └── remote (اختیاری)
│ │
│ └── model
│ ├── CityEntity.kt
│ └── SettingsEntity.kt
│
├── domain
│ ├── model
│ │ ├── PrayerTimes.kt
│ │ └── City.kt
│ │
│ ├── repository
│ │ └── PrayerRepository.kt
│ │
│ └── usecase
│ ├── GetPrayerTimesUseCase.kt
│ ├── SchedulePrayerAlarmUseCase.kt
│ └── GetCurrentCityUseCase.kt
│
├── presentation
│ ├── main
│ │ ├── MainActivity.kt
│ │ ├── MainViewModel.kt
│ │ └── MainState.kt
│ │
│ ├── settings
│ │ ├── SettingsActivity.kt
│ │ └── SettingsViewModel.kt
│ │
│ └── calendar
│ ├── RamadanCalendarActivity.kt
│ └── CalendarViewModel.kt
│
├── alarm
│ ├── PrayerAlarmReceiver.kt
│ ├── BootReceiver.kt
│ └── AlarmScheduler.kt
│
├── location
│ └── LocationProvider.kt
│
├── adhan
│ └── AdhanPlayer.kt
│
├── core
│ ├── PrayerTimeCalculator.kt
│ ├── HijriCalendarUtil.kt
│ ├── PersianCalendarUtil.kt
│ └── Constants.kt
│
└── di
└── AppModule.kt
🕌 لایه Domain
PrayerRepository.kt
Copy code
Kotlin
interface PrayerRepository {
fun getPrayerTimes(city: City, date: Date): PrayerTimes
suspend fun saveCity(city: City)
suspend fun getSavedCity(): City
}
GetPrayerTimesUseCase.kt
Copy code
Kotlin
class GetPrayerTimesUseCase(
private val repository: PrayerRepository
) {
operator fun invoke(city: City, date: Date): PrayerTimes {
return repository.getPrayerTimes(city, date)
}
}
🧠 PrayerTimeCalculator (Core)
استفاده از کتابخانه Adhan:
Copy code
Kotlin
object PrayerTimeCalculator {
}
⏰ سیستم آلارم
AlarmScheduler.kt
Copy code
Kotlin
class AlarmScheduler(private val context: Context) {
}
PrayerAlarmReceiver.kt
Copy code
Kotlin
class PrayerAlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
AdhanPlayer.play(context)
}
}
📢 AdhanPlayer
Copy code
Kotlin
object AdhanPlayer {
}
📍 LocationProvider
Copy code
Kotlin
class LocationProvider(private val context: Context) {
}
📅 تقویم شمسی و قمری
PersianCalendarUtil
برای تاریخ شمسی از کتابخانه PersianCalendar
HijriCalendarUtil
میتوانی از:
Copy code
Kotlin
val hijri = HijrahDate.now()
📱 MainViewModel
Copy code
Kotlin
class MainViewModel(
private val getPrayerTimesUseCase: GetPrayerTimesUseCase
) : ViewModel() {
}
🛠 وابستگیهای Gradle Copy code Kotlin implementation "com.google.android.gms:play-services-location:21.0.1" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1" implementation "androidx.room:room-runtime:2.5.2" implementation "androidx.room:room-ktx:2.5.2" implementation "com.batoulapps.adhan:adhan:1.2.1" 🎛 قابلیتهای حرفهای پیشنهادی Foreground Service هنگام پخش اذان Notification با دکمه Stop ویجت صفحه اصلی Material 3 UI Dark Mode Backup تنظیمات چند مؤذن 🚀 نتیجه با این ساختار: ✔ کاملاً مقیاسپذیر ✔ قابل انتشار در گوگلپلی ✔ استاندارد معماری ✔ آماده توسعه آینده🔐 AndroidManifest موارد مهم
Copy code
Xml