diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3b31f5c..4a389de 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -22,16 +39,6 @@
android:name="android.appwidget.provider"
android:resource="@xml/i_o_s_clock_widget_info" />
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/ray650128/iosclockwidget/AlarmService.kt b/app/src/main/java/com/ray650128/iosclockwidget/AlarmService.kt
new file mode 100644
index 0000000..7b37011
--- /dev/null
+++ b/app/src/main/java/com/ray650128/iosclockwidget/AlarmService.kt
@@ -0,0 +1,119 @@
+package com.ray650128.iosclockwidget
+
+import android.annotation.SuppressLint
+import android.app.*
+import android.content.Intent
+import android.os.Build
+import android.os.IBinder
+import android.os.PowerManager.WakeLock
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import java.util.*
+
+
+class AlarmService : Service() {
+
+ private val timerThread = Thread {
+ while (true) {
+ if (!isServiceRunning) break
+ val calendar = Calendar.getInstance()
+ val second = calendar[Calendar.SECOND]
+ // 計算時、分、秒的旋轉角度
+ secondAngle = (second * 360f / 60f)
+ sendWidgetIntent()
+ Thread.sleep(1000)
+ }
+ }
+
+ override fun onBind(intent: Intent): IBinder {
+ throw UnsupportedOperationException("Not yet implemented")
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ isServiceRunning = true
+
+ //RetrofitClient.init("http://192.168.0.173:8080")
+
+ startForeground()
+ }
+
+ @SuppressLint("WakelockTimeout")
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ timerThread.start()
+// return START_STICKY START_NOT_STICKY START_REDELIVER_INTENT
+ return super.onStartCommand(intent, flags, startId)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ isServiceRunning = false
+ }
+
+ //region Foreground Service 必要通知
+ private fun startForeground() {
+ //region Android 通知設定畫面 intent
+ val intent = Intent().apply {
+ action = "android.settings.APP_NOTIFICATION_SETTINGS"
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ putExtra("android.provider.extra.APP_PACKAGE", packageName)
+ }
+ val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ PendingIntent.getActivity(this.applicationContext, SERVICE_ID, intent, PendingIntent.FLAG_MUTABLE)
+ } else {
+ PendingIntent.getActivity(this.applicationContext, SERVICE_ID, intent, PendingIntent.FLAG_IMMUTABLE)
+ }
+ //endregion
+
+ val channelId = createNotificationChannel() // 建立通知頻道
+ val notification = NotificationCompat.Builder(this, channelId)
+ .setOngoing(true) // 持續顯示,不可被清除
+ .setSmallIcon(R.drawable.ic_info) // 通知 icon
+ .setPriority(NotificationManager.IMPORTANCE_NONE) // 重要性=無
+ .setCategory(Notification.CATEGORY_SERVICE) // 類型=服務
+ .setContentIntent(pendingIntent) // 點選後的跳轉 intent
+ .setContentTitle("${getString(R.string.app_name)} 執行中") // 標題
+ .setContentText("您可以在設定畫面中關閉\"背景服務\"通知") // 內容
+ .build()
+ startForeground(SERVICE_ID, notification)
+ }
+
+ private fun createNotificationChannel(): String {
+ val channel = NotificationChannel(NOTIFICATION_SERVICE_CH, "背景服務", NotificationManager.IMPORTANCE_NONE).apply {
+ enableLights(false) // 不啟用指示燈
+ enableVibration(false) // 不啟用震動
+ setSound(null, null) // 不啟用鈴聲
+ setShowBadge(false) // 不要顯示通知圓點
+ description = "背景服務常駐通知,此為必須存在的通知類型,可以將顯示通知關閉來隱藏。"
+ }
+
+ val notificationManager = NotificationManagerCompat.from(this)
+ notificationManager.createNotificationChannel(channel)
+ return NOTIFICATION_SERVICE_CH
+ }
+ //endregion
+
+ private fun sendWidgetIntent() {
+ val intent = Intent(this, IOSClockWidget::class.java).apply {
+ action = SECOND_CHANGED
+ putExtra(SECOND_ANGLE, secondAngle)
+ }
+ sendBroadcast(intent)
+ }
+
+ companion object {
+ private val TAG = AlarmService::class.java.simpleName
+
+ const val SERVICE_ID = 0x1
+
+ private const val NOTIFICATION_SERVICE_CH = "clock.service"
+
+ var isServiceRunning = false
+
+ var secondAngle = 0f
+
+ const val SECOND_CHANGED = "SECOND_CHANGED"
+ const val SECOND_ANGLE = "SECOND_ANGLE"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ray650128/iosclockwidget/IOSClockWidget.kt b/app/src/main/java/com/ray650128/iosclockwidget/IOSClockWidget.kt
index 0345da7..2fc000f 100644
--- a/app/src/main/java/com/ray650128/iosclockwidget/IOSClockWidget.kt
+++ b/app/src/main/java/com/ray650128/iosclockwidget/IOSClockWidget.kt
@@ -2,13 +2,33 @@ package com.ray650128.iosclockwidget
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
+import android.content.ComponentName
import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.Canvas
import android.widget.RemoteViews
/**
* Implementation of App Widget functionality.
*/
class IOSClockWidget : AppWidgetProvider() {
+
+ override fun onReceive(context: Context?, intent: Intent?) {
+ super.onReceive(context, intent)
+ val appWidgetManager = context?.getSystemService(Context.APPWIDGET_SERVICE) as AppWidgetManager
+ val appWidgetIds = appWidgetManager.getAppWidgetIds(ComponentName(context, IOSClockWidget::class.java))
+
+ when (intent?.action) {
+ AlarmService.SECOND_CHANGED -> {
+ for (appWidgetId in appWidgetIds) {
+ updateAppWidget(context, appWidgetManager, appWidgetId)
+ }
+ }
+ }
+ }
+
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
@@ -38,7 +58,13 @@ internal fun updateAppWidget(
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.i_o_s_clock_widget)
views.setTextViewText(R.id.appwidget_text, widgetText)
+ val bmpOriginal = BitmapFactory.decodeResource(context.applicationContext.resources, R.drawable.img_second_hand)
+ val bmpResult = Bitmap.createBitmap(285, 285, Bitmap.Config.ARGB_8888)
+ val tempCanvas = Canvas(bmpResult)
+ tempCanvas.rotate(AlarmService.secondAngle, 285 / 2.toFloat(), 285 / 2.toFloat())
+ tempCanvas.drawBitmap(bmpOriginal, 0f, 0f, null)
+ views.setImageViewBitmap(R.id.imageView, bmpResult)
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/ray650128/iosclockwidget/MainActivity.kt b/app/src/main/java/com/ray650128/iosclockwidget/MainActivity.kt
index 9fcb698..76c1444 100644
--- a/app/src/main/java/com/ray650128/iosclockwidget/MainActivity.kt
+++ b/app/src/main/java/com/ray650128/iosclockwidget/MainActivity.kt
@@ -1,5 +1,6 @@
package com.ray650128.iosclockwidget
+import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
@@ -7,5 +8,11 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
+
+ if (!AlarmService.isServiceRunning) {
+ startForegroundService(
+ Intent(this@MainActivity, AlarmService::class.java)
+ )
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-nodpi/img_second_hand.png b/app/src/main/res/drawable-nodpi/img_second_hand.png
new file mode 100644
index 0000000..8559103
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/img_second_hand.png differ
diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml
new file mode 100644
index 0000000..bdf91f9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_info.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/img_clock_dash.xml b/app/src/main/res/drawable/img_clock_dash.xml
index c3a88e6..9cb7d5f 100644
--- a/app/src/main/res/drawable/img_clock_dash.xml
+++ b/app/src/main/res/drawable/img_clock_dash.xml
@@ -1,68 +1,231 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/img_minute_hand.xml b/app/src/main/res/drawable/img_minute_hand.xml
index 427ff45..a636987 100644
--- a/app/src/main/res/drawable/img_minute_hand.xml
+++ b/app/src/main/res/drawable/img_minute_hand.xml
@@ -34,8 +34,8 @@
android:height="20dp"
android:top="132.5dp">
-
-
+
+
diff --git a/app/src/main/res/layout/i_o_s_clock_widget.xml b/app/src/main/res/layout/i_o_s_clock_widget.xml
index 43b8fc9..c4645d9 100644
--- a/app/src/main/res/layout/i_o_s_clock_widget.xml
+++ b/app/src/main/res/layout/i_o_s_clock_widget.xml
@@ -1,4 +1,5 @@
+
+