5

I'm using a TileService as a shortcut to open my app's Activity. It does only that, and has no state.

It looks like this:


class QuickAccessTileService : TileService() {

    override fun onClick() {
        super.onClick()

        val intent = Intent(this, SlideOverActivity::class.java)
            .addFlags(FLAG_ACTIVITY_NEW_TASK)

        startActivityAndCollapse(intent)
    }
}

and it's declared in AndroidManifest as:

<service
    android:name=".service.QuickAccessTileService"
    android:icon="@drawable/ic_home"
    android:label="@string/tile_label"
    android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">

    <intent-filter>
        <action android:name="android.service.quicksettings.action.QS_TILE" />
    </intent-filter>
</service>

As it stands, this works. However, when my application is stopped, the next time I try to open it via the quick settings panel, it takes several seconds to start the activity.

Here's what I know:

The Activity in itself isn't slow to start. Trying to open it via the launcher instead makes it quite clear.

The Service seems to be what's taking a while to start before onClick is even executed. It makes sense; the Service is probably not kept running in the background doing nothing while the app isn't running. However, this means that when the system detects a click on my Tile, the Service has to be recreated first, which takes way too long.

I'm not sure where to go from here — if my guesses are even right.

EDIT: As an important addition, I can reproduce this on a OnePlus 7 Pro running on Android Pie. This might be a OnePlus-specific issue as I cannot reproduce it on an emulator.

  • If you have not done so already, override `onCreate()` and `onBind()` in `QuickAccessTileService`, chaining to the superclass and logging the times they were called. Also log the time that `onClick()` was called. That will hopefully give you some clue as to what step of the process is the slow one: slow to create the service, slow to bind after creation, slow to call `onClick()` after binding, or slow to respond to your `startActivityAndCollapse()` by actually showing the activity. – CommonsWare Jul 09 '19 at 20:55
  • `onCreate`, `onBind` and `onClick` are called only a few milliseconds from each other. Most of the waiting happens before `onCreate` is even called, which is just puzzling to me. – Baptiste Candellier Jul 09 '19 at 21:13
  • 1
    Agreed. Is this reproducible across multiple devices and OS versions? – CommonsWare Jul 09 '19 at 21:15
  • 2
    Currently, I can reproduce this on a OnePlus 7 Pro API 27. I could have sworn this also happened on the emulator a few weeks ago; either I'm remembering it wrong or I fixed it by accident, because I cannot for the life of me reproduce it there on any Android version. So this might be a OnePlus issue after all. :/ – Baptiste Candellier Jul 10 '19 at 18:13
  • 1
    @CommonsWare, I can reproduce this on a Huawei API 26, Not only onClick, onStartListening is delayed, or even not executed at all. – zhongshu Aug 02 '19 at 03:54
  • 1
    @zhongshu: My best guess is that this is a manufacturer-specific issue, where they messed with the way the notification shade works in a way that interferes with third-party tiles. – CommonsWare Aug 02 '19 at 10:53

1 Answers1

0
@RequiresApi(Build.VERSION_CODES.N)
class TileSettingClass : TileService() {

    override fun onClick() {

        super.onClick()

        val tile = qsTile
        if (tile.state == Tile.STATE_INACTIVE) {
            tile.state = Tile.STATE_ACTIVE
            val intent = Intent(this.applicationContext, YourActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.action = "yourAction"
            applicationContext.startActivity(intent)
        } else {
            tile.state = Tile.STATE_INACTIVE
        }
        tile.updateTile()
    }
}

Manifests

<service
    android:name=".main.service.TileSettingClass"
    android:icon="@drawable/ic_tile_setting"
    android:label="@string/milliy"
    android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
    >
    <intent-filter>
        <action android:name="android.service.quicksettings.action.QS_TILE" />
    </intent-filter>
</service>
David Buck
  • 3,752
  • 35
  • 31
  • 35