save
This commit is contained in:
parent
cde29a9feb
commit
c16e47476d
@ -13,8 +13,6 @@
|
|||||||
<application
|
<application
|
||||||
android:name=".YumeeApp"
|
android:name=".YumeeApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
@ -49,6 +47,19 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:name=".widget.MonitorWidget"
|
||||||
|
android:exported="true"
|
||||||
|
android:label="Yumee Panels Status">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
<action android:name="com.yumee.panels.UPDATE_WIDGET" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data
|
||||||
|
android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/widget_info" />
|
||||||
|
</receiver>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package com.yumee.panels
|
package com.yumee.panels
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.room.Room
|
|
||||||
import com.yumee.panels.data.local.YumeeDatabase
|
import com.yumee.panels.data.local.YumeeDatabase
|
||||||
|
|
||||||
class YumeeApp : Application() {
|
class YumeeApp : Application() {
|
||||||
@ -11,8 +10,6 @@ class YumeeApp : Application() {
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
database = Room.databaseBuilder(this, YumeeDatabase::class.java, "yumee_db")
|
database = YumeeDatabase.getDatabase(this)
|
||||||
.fallbackToDestructiveMigration()
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.yumee.panels.data.local
|
package com.yumee.panels.data.local
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@ -8,6 +9,9 @@ interface MonitorDao {
|
|||||||
@Query("SELECT * FROM monitors")
|
@Query("SELECT * FROM monitors")
|
||||||
fun getAllMonitors(): Flow<List<Monitor>>
|
fun getAllMonitors(): Flow<List<Monitor>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM monitors")
|
||||||
|
suspend fun getAllMonitorsSync(): List<Monitor>
|
||||||
|
|
||||||
@Query("SELECT * FROM monitors WHERE isActive = 1")
|
@Query("SELECT * FROM monitors WHERE isActive = 1")
|
||||||
suspend fun getActiveMonitors(): List<Monitor>
|
suspend fun getActiveMonitors(): List<Monitor>
|
||||||
|
|
||||||
@ -36,4 +40,21 @@ interface MonitorDao {
|
|||||||
@Database(entities = [Monitor::class, MonitorLog::class], version = 1)
|
@Database(entities = [Monitor::class, MonitorLog::class], version = 1)
|
||||||
abstract class YumeeDatabase : RoomDatabase() {
|
abstract class YumeeDatabase : RoomDatabase() {
|
||||||
abstract fun monitorDao(): MonitorDao
|
abstract fun monitorDao(): MonitorDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: YumeeDatabase? = null
|
||||||
|
|
||||||
|
fun getDatabase(context: Context): YumeeDatabase {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
val instance = Room.databaseBuilder(
|
||||||
|
context.applicationContext,
|
||||||
|
YumeeDatabase::class.java,
|
||||||
|
"yumee_database"
|
||||||
|
).build()
|
||||||
|
INSTANCE = instance
|
||||||
|
instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2,10 +2,8 @@ package com.yumee.panels.service
|
|||||||
|
|
||||||
import android.app.*
|
import android.app.*
|
||||||
import android.content.*
|
import android.content.*
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.room.Room
|
|
||||||
import com.yumee.panels.MainActivity
|
import com.yumee.panels.MainActivity
|
||||||
import com.yumee.panels.R
|
import com.yumee.panels.R
|
||||||
import com.yumee.panels.data.local.*
|
import com.yumee.panels.data.local.*
|
||||||
@ -32,7 +30,7 @@ class MonitorService : Service() {
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
db = Room.databaseBuilder(applicationContext, YumeeDatabase::class.java, "yumee_db").build()
|
db = YumeeDatabase.getDatabase(applicationContext)
|
||||||
createNotificationChannel()
|
createNotificationChannel()
|
||||||
acquireWakeLock()
|
acquireWakeLock()
|
||||||
}
|
}
|
||||||
@ -49,18 +47,27 @@ class MonitorService : Service() {
|
|||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
val monitors = db.monitorDao().getActiveMonitors()
|
val monitors = db.monitorDao().getActiveMonitors()
|
||||||
|
var updated = false
|
||||||
monitors.forEach { monitor ->
|
monitors.forEach { monitor ->
|
||||||
// Simplified: In a real app, track individual interval timers
|
|
||||||
// Here we check if it's time to ping based on lastChecked
|
|
||||||
if (System.currentTimeMillis() - monitor.lastChecked >= monitor.intervalSeconds * 1000) {
|
if (System.currentTimeMillis() - monitor.lastChecked >= monitor.intervalSeconds * 1000) {
|
||||||
launch { pingMonitor(monitor) }
|
pingMonitor(monitor)
|
||||||
|
updated = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delay(1000) // check every second
|
if (updated) {
|
||||||
|
updateWidget()
|
||||||
|
}
|
||||||
|
delay(1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateWidget() {
|
||||||
|
val intent = Intent("com.yumee.panels.UPDATE_WIDGET")
|
||||||
|
intent.setPackage(packageName)
|
||||||
|
sendBroadcast(intent)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun pingMonitor(monitor: Monitor) {
|
private suspend fun pingMonitor(monitor: Monitor) {
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
var isOnline = false
|
var isOnline = false
|
||||||
@ -81,7 +88,6 @@ class MonitorService : Service() {
|
|||||||
responseTime = System.currentTimeMillis() - startTime
|
responseTime = System.currentTimeMillis() - startTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update database
|
|
||||||
val updatedMonitor = monitor.copy(
|
val updatedMonitor = monitor.copy(
|
||||||
lastStatusCode = statusCode,
|
lastStatusCode = statusCode,
|
||||||
lastResponseTime = responseTime,
|
lastResponseTime = responseTime,
|
||||||
@ -107,7 +113,7 @@ class MonitorService : Service() {
|
|||||||
private fun sendAlert(name: String, message: String) {
|
private fun sendAlert(name: String, message: String) {
|
||||||
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
val alertNotification = NotificationCompat.Builder(this, CHANNEL_ID)
|
val alertNotification = NotificationCompat.Builder(this, CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.ic_launcher_foreground) // Placeholder
|
.setSmallIcon(R.mipmap.ic_launcher)
|
||||||
.setContentTitle("Alert: $name")
|
.setContentTitle("Alert: $name")
|
||||||
.setContentText(message)
|
.setContentText(message)
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
@ -122,7 +128,7 @@ class MonitorService : Service() {
|
|||||||
return NotificationCompat.Builder(this, CHANNEL_ID)
|
return NotificationCompat.Builder(this, CHANNEL_ID)
|
||||||
.setContentTitle("Yumee Panels")
|
.setContentTitle("Yumee Panels")
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
.setSmallIcon(R.drawable.ic_launcher_foreground) // Placeholder
|
.setSmallIcon(R.mipmap.ic_launcher)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.yumee.panels.widget
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.appwidget.AppWidgetProvider
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import com.yumee.panels.MainActivity
|
||||||
|
import com.yumee.panels.R
|
||||||
|
import com.yumee.panels.data.local.YumeeDatabase
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
|
class MonitorWidget : AppWidgetProvider() {
|
||||||
|
|
||||||
|
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||||
|
for (appWidgetId in appWidgetIds) {
|
||||||
|
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
super.onReceive(context, intent)
|
||||||
|
if (intent.action == "com.yumee.panels.UPDATE_WIDGET") {
|
||||||
|
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
|
val appWidgetIds = appWidgetManager.getAppWidgetIds(ComponentName(context, MonitorWidget::class.java))
|
||||||
|
for (appWidgetId in appWidgetIds) {
|
||||||
|
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
|
||||||
|
val views = RemoteViews(context.packageName, R.layout.widget_layout)
|
||||||
|
|
||||||
|
// Launch app on click
|
||||||
|
val intent = Intent(context, MainActivity::class.java)
|
||||||
|
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_title, pendingIntent)
|
||||||
|
|
||||||
|
// Fetch counts from DB
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
val db = YumeeDatabase.getDatabase(context)
|
||||||
|
val allMonitors = db.monitorDao().getAllMonitorsSync()
|
||||||
|
val onlineCount = allMonitors.count { it.isOnline }
|
||||||
|
val offlineCount = allMonitors.count { !it.isOnline }
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
views.setTextViewText(R.id.widget_online_count, "Online: $onlineCount")
|
||||||
|
views.setTextViewText(R.id.widget_offline_count, "Offline: $offlineCount")
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#1A2130" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
<stroke android:width="2dp" android:color="#FFFFFF" />
|
||||||
|
</shape>
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/widget_background"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Yumee Panels"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_online_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Online: 0"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:shadowColor="#FFFFFF"
|
||||||
|
android:shadowDx="0"
|
||||||
|
android:shadowDy="0"
|
||||||
|
android:shadowRadius="5" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/widget_offline_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Offline: 0"
|
||||||
|
android:textColor="#FF4444"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/widget_refresh"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@android:drawable/stat_notify_sync"
|
||||||
|
android:contentDescription="Refresh" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:minWidth="110dp"
|
||||||
|
android:minHeight="40dp"
|
||||||
|
android:updatePeriodMillis="1800000"
|
||||||
|
android:initialLayout="@layout/widget_layout"
|
||||||
|
android:resizeMode="horizontal|vertical"
|
||||||
|
android:widgetCategory="home_screen">
|
||||||
|
</appwidget-provider>
|
||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user