Skip to content

Commit

Permalink
opt.: display err if home widget fails
Browse files Browse the repository at this point in the history
Fixes #614
  • Loading branch information
lollipopkit committed Dec 15, 2024
1 parent 2f6db29 commit d8ea0b8
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 174 deletions.
2 changes: 2 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ android {

debug {
applicationIdSuffix '.debug'
resValue "string", "app_name", "SrvBxD"
}

profile {
applicationIdSuffix '.debug'
resValue "string", "app_name", "SrvBxP"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<application
android:label="ServerBox"
android:label="@string/app_name"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
Expand Down
10 changes: 9 additions & 1 deletion android/app/src/main/kotlin/tech/lolli/toolbox/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import androidx.core.content.ContextCompat
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.appwidget.AppWidgetManager
import tech.lolli.toolbox.widget.HomeWidget

class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
val binaryMessenger = flutterEngine.dartExecutor.binaryMessenger

MethodChannel(binaryMessenger, "tech.lolli.toolbox/app_retain").apply {
MethodChannel(binaryMessenger, "tech.lolli.toolbox/main_chan").apply {
setMethodCallHandler { method, result ->
when (method.method) {
"sendToBackground" -> {
Expand All @@ -36,6 +38,12 @@ class MainActivity: FlutterFragmentActivity() {
stopService(serviceIntent)
result.success(null)
}
"updateHomeWidget" -> {
val intent = Intent(this@MainActivity, HomeWidget::class.java)
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
sendBroadcast(intent)
result.success(null)
}
else -> {
result.notImplemented()
}
Expand Down
91 changes: 49 additions & 42 deletions android/app/src/main/kotlin/tech/lolli/toolbox/widget/HomeWidget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import android.view.View
import android.widget.RemoteViews
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import tech.lolli.toolbox.R
import java.net.URL
import java.net.HttpURLConnection
import java.io.FileNotFoundException

class HomeWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
Expand All @@ -23,7 +26,6 @@ class HomeWidget : AppWidgetProvider() {
}
}

@OptIn(DelicateCoroutinesApi::class)
private fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
val views = RemoteViews(context.packageName, R.layout.home_widget)
val sp = context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE)
Expand All @@ -36,6 +38,10 @@ class HomeWidget : AppWidgetProvider() {
url = gUrl
}

if (url.isNullOrEmpty()) {
Log.e("HomeWidget", "未找到 URL")
}

val intentUpdate = Intent(context, HomeWidget::class.java)
intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
val ids = intArrayOf(appWidgetId)
Expand All @@ -54,11 +60,11 @@ class HomeWidget : AppWidgetProvider() {
views.setOnClickPendingIntent(R.id.widget_container, pendingUpdate)

if (url.isNullOrEmpty()) {
views.setViewVisibility(R.id.widget_cpu_label, View.INVISIBLE)
views.setViewVisibility(R.id.widget_mem_label, View.INVISIBLE)
views.setViewVisibility(R.id.widget_disk_label, View.INVISIBLE)
views.setViewVisibility(R.id.widget_net_label, View.INVISIBLE)
views.setTextViewText(R.id.widget_name, "ID: $appWidgetId")
views.setTextViewText(R.id.widget_name, "No URL")
// Update the widget to display a message for missing URL
views.setViewVisibility(R.id.error_message, View.VISIBLE)
views.setTextViewText(R.id.error_message, "Please configure the widget URL.")
views.setViewVisibility(R.id.widget_content, View.GONE)
appWidgetManager.updateAppWidget(appWidgetId, views)
return
} else {
Expand All @@ -68,44 +74,45 @@ class HomeWidget : AppWidgetProvider() {
views.setViewVisibility(R.id.widget_net_label, View.VISIBLE)
}

GlobalScope.launch(Dispatchers.IO) {
CoroutineScope(Dispatchers.IO).launch {
try {
val jsonStr = URL(url).readText()
val jsonObject = JSONObject(jsonStr)
val data = jsonObject.getJSONObject("data")
val server = data.getString("name")
val cpu = data.getString("cpu")
val mem = data.getString("mem")
val disk = data.getString("disk")
val net = data.getString("net")

GlobalScope.launch(Dispatchers.Main) main@ {
// mem or disk is empty -> get status failed
// (cpu | net) isEmpty -> data is not ready
if (mem.isEmpty() || disk.isEmpty()) {
return@main
val connection = URL(url).openConnection() as HttpURLConnection
connection.requestMethod = "GET"
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
val jsonStr = connection.inputStream.bufferedReader().use { it.readText() }
val jsonObject = JSONObject(jsonStr)
val data = jsonObject.getJSONObject("data")
val server = data.getString("name")
val cpu = data.getString("cpu")
val mem = data.getString("mem")
val disk = data.getString("disk")
val net = data.getString("net")
withContext(Dispatchers.Main) {
if (mem.isEmpty() || disk.isEmpty()) {
Log.e("HomeWidget", "获取状态失败:内存或磁盘信息为空")
return@withContext
}
views.setTextViewText(R.id.widget_name, server)
views.setTextViewText(R.id.widget_cpu, cpu)
views.setTextViewText(R.id.widget_mem, mem)
views.setTextViewText(R.id.widget_disk, disk)
views.setTextViewText(R.id.widget_net, net)
val timeStr = android.text.format.DateFormat.format("HH:mm", java.util.Date()).toString()
views.setTextViewText(R.id.widget_time, timeStr)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
views.setTextViewText(R.id.widget_name, server)

views.setTextViewText(R.id.widget_cpu, cpu)
views.setTextViewText(R.id.widget_mem, mem)
views.setTextViewText(R.id.widget_disk, disk)
views.setTextViewText(R.id.widget_net, net)

val timeStr = android.text.format.DateFormat.format("HH:mm", java.util.Date()).toString()
views.setTextViewText(R.id.widget_time, timeStr)

appWidgetManager.updateAppWidget(appWidgetId, views)
} else {
throw FileNotFoundException("HTTP response code: $responseCode")
}
} catch (e: Exception) {
println("ServerBoxHomeWidget: ${e.localizedMessage}")
GlobalScope.launch(Dispatchers.Main) main@ {
views.setViewVisibility(R.id.widget_cpu_label, View.INVISIBLE)
views.setViewVisibility(R.id.widget_mem_label, View.INVISIBLE)
views.setViewVisibility(R.id.widget_disk_label, View.INVISIBLE)
views.setViewVisibility(R.id.widget_net_label, View.INVISIBLE)
views.setTextViewText(R.id.widget_name, "ID: $appWidgetId")
views.setTextViewText(R.id.widget_mem, e.localizedMessage)
Log.e("HomeWidget", "更新小部件时出错:${e.localizedMessage}", e)
withContext(Dispatchers.Main) {
views.setTextViewText(R.id.widget_name, "Error")
// Update the widget to display a message for data retrieval failure
views.setViewVisibility(R.id.error_message, View.VISIBLE)
views.setTextViewText(R.id.error_message, "Failed to retrieve data.")
views.setViewVisibility(R.id.widget_content, View.GONE)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
Expand Down
Loading

0 comments on commit d8ea0b8

Please sign in to comment.