An Android app for Astro Malaysia direct-TV subscribers. Browse the channel lineup, mark favourites, and explore a paginated TV guide of currently airing and upcoming programmes across all channels.
- Displays the full Astro channel list with channel ID and channel title.
- Sort all channels by name (ascending/descending) or channel number (ascending/descending).
- Favourites: tap the heart icon to mark or unmark a channel. Favourites appear in a dedicated section above the full list.
- Google Sign-In (Firebase Authentication) is required to manage favourites. If a guest taps the heart icon, the sign-in flow is launched first.
- Persisted preferences: when signed in, favourites and sort order are stored in Firebase Realtime Database and restored on the next login.
- Navigate to the TV Guide from the overflow menu.
- Shows programmes currently on air (and upcoming) across all channels loaded from the home screen.
- Grid layout (2 columns) with programme banner image, title, channel name, and channel ID.
- Sort by channel name or channel number (ascending/descending).
- Pagination / lazy load: scroll to the bottom to fetch the next time window. Each page covers a 30-minute slot; scrolling continues until roughly 7 days of schedule data have been loaded.
- Programme images are loaded with Glide.
| Data | Firebase path | When synced |
|---|---|---|
| Favourite channels | /favourites/{channelId} |
On toggle (signed-in users only) |
| Sort order | /sort_order |
When user changes sort from the menu |
The app follows MVVM with a Repository pattern and Hilt dependency injection.
flowchart TB
subgraph UI
MA[MainActivity]
TV[TvGuideActivity]
MAC[MainActivityCompose - WIP]
end
subgraph ViewModel
CV[ChannelsListViewModel]
GV[TvGuideViewModel]
end
subgraph Repository
CR[ChannelsRepository]
TR[TvGuideRepository]
end
subgraph Data
API[Astro AMS API]
FB[(Firebase Realtime DB)]
AUTH[Firebase Auth]
end
MA --> CV
TV --> GV
MAC --> CV
CV --> CR
GV --> TR
CR --> API
CR --> FB
TR --> API
MA --> AUTH
| Layer | Package | Role |
|---|---|---|
| View | view/, ui/ |
Activities, XML data-binding layouts, RecyclerView adapters. A Jetpack Compose variant (MainActivityCompose) exists but is not registered as the launcher. |
| ViewModel | viewmodel/ |
Exposes LiveData to the UI; survives configuration changes. Annotated with @HiltViewModel. |
| Repository | repository/ |
Single source of truth: fetches from Retrofit or Firebase, returns LiveData. @Singleton via Hilt. |
| Network | webhelper/, di/ |
Retrofit AstroAPi interface and NetworkModule (OkHttp + Gson). |
| Model | model/ |
Gson-deserializable POJOs. ChannelsListModel.Channel extends BaseObservable for data binding. |
| DI | di/ |
Hilt NetworkModule provides OkHttpClient, Retrofit, and AstroAPi. |
| App | AstroApplication |
@HiltAndroidApp entry point. |
MainActivityobtainsChannelsListViewModelviaViewModelProvider.- ViewModel delegates to
ChannelsRepository.getChannelList(). - Repository calls
GET http://ams-api.astro.com.my/ams/v3/getChannelListthrough Retrofit. - Response is posted to
MutableLiveData<ChannelsListModel>; the Activity observes and binds toRecyclerViewadapters. - Favourites and sort order are observed separately from Firebase Realtime Database listeners.
MainActivitypasses all channel IDs toTvGuideActivityvia intent extra (BundleKeys.CHANNELS_LIST).TvGuideViewModelasksTvGuideRepositoryforperiodStart/periodEndtime windows.- First page:
periodStart= now,periodEnd= now + 30 minutes. - Subsequent pages:
periodStart= previousperiodEnd+ 1 second,periodEnd= +30 minutes. - API call:
GET ams/v3/getEvents/?periodStart=…&periodEnd=…&channelId=1,2,3,… RecyclerView.OnScrollListenertriggersloadMoreItems()when the user reaches the bottom.
| Setting | Value |
|---|---|
| Base URL | http://ams-api.astro.com.my/ (configured in gradle.properties → BuildConfig.URL) |
| Required header | city_id: 10 (added by NetworkModule OkHttp interceptor) |
| Channel list | GET /ams/v3/getChannelList |
| TV guide events | GET /ams/v3/getEvents/?periodStart&periodEnd&channelId |
The app uses HTTP (cleartext); android:usesCleartextTraffic="true" is set in the manifest.
- Authentication — Google Sign-In via Firebase UI Auth (
AuthUI.IdpConfig.GoogleBuilder). - Realtime Database — stores favourites and sort order per authenticated user.
| Category | Libraries |
|---|---|
| Language | Java (primary UI), Kotlin (Compose UI — in progress) |
| Min / Target SDK | 21 / 34 |
| Architecture | MVVM, LiveData, Repository |
| DI | Dagger Hilt |
| Networking | Retrofit 2.9, OkHttp 4.12, Gson |
| UI | XML + Data Binding, RecyclerView, Material Components |
| UI (WIP) | Jetpack Compose, Material 3 |
| Images | Glide 4.16 |
| Backend | Firebase Auth, Firebase Realtime Database, Firebase UI Auth |
| Build | Gradle 8.2, AGP 8.1.4, Version Catalog (gradle/libs.versions.toml) |
app/src/main/java/com/mukeshteckwani/astro/astroapp/
├── AstroApplication.java # Hilt application class
├── adapter/ # RecyclerView adapters + data-binding adapters
├── di/NetworkModule.java # Retrofit / OkHttp wiring
├── model/ # ChannelsListModel, TvGuideModel
├── repository/ # ChannelsRepository, TvGuideRepository
├── view/ # MainActivity, TvGuideActivity, MainActivityCompose
├── viewmodel/ # ChannelsListViewModel, TvGuideViewModel
├── webhelper/ # AstroAPi Retrofit interface
├── ui/ # Compose screens, components, theme (WIP)
└── utils/ # Constants, date helpers, item decorations
- JDK 17
- Android SDK (API 34, build-tools 34.0.0)
local.propertieswithsdk.dirpointing to your Android SDK
./gradlew assembleDebug # Build debug APK
./gradlew installDebug # Install on connected device/emulator
./gradlew build # Full CI build (compile + tests + lint)To enable Google Sign-In on your own Firebase project:
- Create a project in the Firebase Console.
- Enable Firebase Authentication (Google provider).
- Enable Firebase Realtime Database.
- Register your debug SHA-1 fingerprint in the Firebase project settings.
- Download a new
google-services.jsonand replaceapp/google-services.json.
GitHub Actions workflow (.github/workflows/android.yml) runs ./gradlew build on push/PR to master with JDK 17 and Android SDK 34.