QSTileService.kt 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package com.v2ray.ang.service
  2. import android.content.BroadcastReceiver
  3. import android.content.Context
  4. import android.content.Intent
  5. import android.content.IntentFilter
  6. import android.graphics.drawable.Icon
  7. import android.os.Build
  8. import android.service.quicksettings.Tile
  9. import android.service.quicksettings.TileService
  10. import android.util.Log
  11. import androidx.annotation.RequiresApi
  12. import androidx.core.content.ContextCompat
  13. import com.v2ray.ang.AppConfig
  14. import com.v2ray.ang.R
  15. import com.v2ray.ang.handler.V2RayServiceManager
  16. import com.v2ray.ang.util.MessageUtil
  17. import com.v2ray.ang.util.Utils
  18. import java.lang.ref.SoftReference
  19. @RequiresApi(Build.VERSION_CODES.N)
  20. class QSTileService : TileService() {
  21. /**
  22. * Sets the state of the tile.
  23. * @param state The state to set.
  24. */
  25. fun setState(state: Int) {
  26. qsTile?.icon = Icon.createWithResource(applicationContext, R.drawable.ic_stat_name)
  27. if (state == Tile.STATE_INACTIVE) {
  28. qsTile?.state = Tile.STATE_INACTIVE
  29. qsTile?.label = getString(R.string.app_name)
  30. } else if (state == Tile.STATE_ACTIVE) {
  31. qsTile?.state = Tile.STATE_ACTIVE
  32. qsTile?.label = V2RayServiceManager.getRunningServerName()
  33. }
  34. qsTile?.updateTile()
  35. }
  36. /**
  37. * Refer to the official documentation for [registerReceiver](https://developer.android.com/reference/androidx/core/content/ContextCompat#registerReceiver(android.content.Context,android.content.BroadcastReceiver,android.content.IntentFilter,int):
  38. * `registerReceiver(Context, BroadcastReceiver, IntentFilter, int)`.
  39. */
  40. override fun onStartListening() {
  41. super.onStartListening()
  42. if (V2RayServiceManager.isRunning()) {
  43. setState(Tile.STATE_ACTIVE)
  44. } else {
  45. setState(Tile.STATE_INACTIVE)
  46. }
  47. mMsgReceive = ReceiveMessageHandler(this)
  48. val mFilter = IntentFilter(AppConfig.BROADCAST_ACTION_ACTIVITY)
  49. ContextCompat.registerReceiver(applicationContext, mMsgReceive, mFilter, Utils.receiverFlags())
  50. MessageUtil.sendMsg2Service(this, AppConfig.MSG_REGISTER_CLIENT, "")
  51. }
  52. /**
  53. * Called when the tile stops listening.
  54. */
  55. override fun onStopListening() {
  56. super.onStopListening()
  57. try {
  58. applicationContext.unregisterReceiver(mMsgReceive)
  59. mMsgReceive = null
  60. } catch (e: Exception) {
  61. Log.e(AppConfig.TAG, "Failed to unregister receiver", e)
  62. }
  63. }
  64. /**
  65. * Called when the tile is clicked.
  66. */
  67. override fun onClick() {
  68. super.onClick()
  69. when (qsTile.state) {
  70. Tile.STATE_INACTIVE -> {
  71. V2RayServiceManager.startVServiceFromToggle(this)
  72. }
  73. Tile.STATE_ACTIVE -> {
  74. V2RayServiceManager.stopVService(this)
  75. }
  76. }
  77. }
  78. private var mMsgReceive: BroadcastReceiver? = null
  79. private class ReceiveMessageHandler(context: QSTileService) : BroadcastReceiver() {
  80. var mReference: SoftReference<QSTileService> = SoftReference(context)
  81. override fun onReceive(ctx: Context?, intent: Intent?) {
  82. val context = mReference.get()
  83. when (intent?.getIntExtra("key", 0)) {
  84. AppConfig.MSG_STATE_RUNNING -> {
  85. context?.setState(Tile.STATE_ACTIVE)
  86. }
  87. AppConfig.MSG_STATE_NOT_RUNNING -> {
  88. context?.setState(Tile.STATE_INACTIVE)
  89. }
  90. AppConfig.MSG_STATE_START_SUCCESS -> {
  91. context?.setState(Tile.STATE_ACTIVE)
  92. }
  93. AppConfig.MSG_STATE_START_FAILURE -> {
  94. context?.setState(Tile.STATE_INACTIVE)
  95. }
  96. AppConfig.MSG_STATE_STOP_SUCCESS -> {
  97. context?.setState(Tile.STATE_INACTIVE)
  98. }
  99. }
  100. }
  101. }
  102. }