A ready-to-use Android starter application with bottom sheet login, Material Design components, and Volley for network requests.
- ✅ Bottom Sheet Login Screen
- ✅ Material Design 3 Components
- ✅ Volley Network Library Integration
- ✅ Utility Helpers for common Android tasks
- ✅ Session Management
- ✅ Network Status Checking
- ✅ Form Validation
- ✅ Easy Customization
app/src/main/java/ug/global/temp/
├── MainActivity.kt # Main activity with bottom sheet login
└── util/
├── URLS.kt # API endpoints and app configuration
├── Helpers.kt # Common Android utility functions
└── VolleyHelper.kt # Simplified Volley network requests
Option A: Using Android Studio (Recommended)
- Right-click on the package name
ug.global.tempin the project tree - Select
Refactor→Rename - Choose "Rename package"
- Enter your new package name (e.g.,
com.yourcompany.yourapp) - Click "Refactor"
- Update the following files manually:
app/build.gradle.kts→ UpdatenamespaceandapplicationIdURLS.kt→ UpdateAppConfig.PACKAGE_NAME
Option B: Manual Method
-
Update package in
app/build.gradle.kts:android { namespace = "com.yourcompany.yourapp" defaultConfig { applicationId = "com.yourcompany.yourapp" } } -
Rename package directories:
app/src/main/java/ug/global/temp → app/src/main/java/com/yourcompany/yourapp -
Update package declarations in all
.ktfiles:package com.yourcompany.yourapp
-
Update imports:
import com.yourcompany.yourapp.util.* import com.yourcompany.yourapp.databinding.*
-
Update
app/src/main/res/values/strings.xml:<string name="app_name">Your App Name</string>
-
Update
URLS.kt:const val APP_NAME = "Your App Name"
Edit app/src/main/java/ug/global/temp/util/URLS.kt:
// Update base URL
private const val BASE_URL = "https://your-api.com/api/v1/"
// Add your endpoints
const val YOUR_ENDPOINT = "${CURRENT_BASE_URL}your/endpoint"In URLS.kt, change:
const val CURRENT_BASE_URL = DEV_URL // or STAGING_URL or BASE_URLThe app uses VolleyHelper for simplified network requests:
VolleyHelper.get(
context = this,
url = URLS.YOUR_ENDPOINT,
onSuccess = { response ->
// Handle success
},
onError = { error ->
// Handle error
}
)val data = JSONObject().apply {
put("key", "value")
}
VolleyHelper.post(
context = this,
url = URLS.YOUR_ENDPOINT,
data = data,
onSuccess = { response ->
// Handle success
},
onError = { error ->
// Handle error
}
)onError = { error ->
// Handle error
}
)
## Bluetooth Printing
The app includes a flexible Bluetooth printing architecture that supports both generic Bluetooth printers (via SPP/RfComm) and specific Woosim printers (via provided JAR).
### Architecture
The printing logic is abstracted behind the `PrinterService` interface:
```kotlin
interface PrinterService {
fun connect(device: BluetoothDevice, onConnected: () -> Unit, onError: (String) -> Unit)
fun disconnect()
fun printText(text: String)
fun printImage(imagePath: String)
fun isConnected(): Boolean
}
- GenericBluetoothPrinterService: Uses standard Android
BluetoothSocketto communicate using SPP (Serial Port Profile). This works with most thermal printers. - WoosimPrinterImpl: Wraps the proprietary
WoosimLibfor specific Woosim printer features.
You can switch between the generic and proprietary implementations in PrinterModule.kt.
To use Generic Printing (Default):
@Module
@InstallIn(SingletonComponent::class)
object PrinterModule {
@Provides
@Singleton
fun providePrinterService(impl: GenericBluetoothPrinterService): PrinterService {
return impl
}
}To use Woosim Printing:
- Open
PrinterModule.kt. - Change the provider to return
WoosimPrinterImpl. Note: WoosimImpl requires aHandler, so you may need to update the module to provide one.
Inject PrinterService into your classes (Activities, ViewModels, etc.) using Hilt:
@HiltViewModel
class MyViewModel @Inject constructor(
private val printerService: PrinterService
) : ViewModel() {
fun printReceipt(device: BluetoothDevice) {
printerService.connect(device,
onConnected = {
printerService.printText("Hello World\n\n\n")
},
onError = { error ->
// Handle connection error
}
)
}
}The Helpers object provides many useful functions:
Helpers.showToast(context, "Message")
Helpers.showSnackbar(view, "Message")Helpers.showAlertDialog(context, "Title", "Message")
Helpers.showConfirmationDialog(context, "Title", "Message",
onConfirm = { /* action */ })Helpers.saveString(context, "key", "value")
val value = Helpers.getString(context, "key")if (Helpers.isNetworkAvailable(context)) {
// Make network request
}Helpers.isValidEmail(email)
Helpers.isValidPassword(password)Helpers.saveAuthToken(context, token)
Helpers.isLoggedIn(context)
Helpers.logout(context)This starter app uses:
- Material Components - Modern UI design
- Volley - Network requests
- ViewBinding - Type-safe view access
- ConstraintLayout - Flexible layouts
- Open the project in Android Studio
- Sync Gradle files
- Run the app on an emulator or device
- minSdk: 33 (Android 13)
- targetSdk: 36
- Kotlin: 1.9+
- Java: 11
The login bottom sheet is defined in:
- Layout:
app/src/main/res/layout/bottom_sheet_login.xml - Logic:
MainActivity.kt→showLoginBottomSheet()
To customize:
- Edit the layout file to add/remove fields
- Update validation logic in
validateLoginForm() - Modify the login API call in
performLogin()
The app expects a JSON response like:
{
"token": "your_auth_token",
"user_id": "123",
"email": "[email protected]"
}Customize in handleLoginSuccess() if your API returns different fields.
- Create additional activities/fragments for your app
- Add more API endpoints in
URLS.kt - Implement forgot password functionality
- Add registration screen
- Customize the theme in
res/values/themes.xml - Update app icon and splash screen
This is a starter template - feel free to use it for any project!
For issues or questions, refer to the Android documentation: