iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Software Development

Android 工具箱開發系列 第 8 篇

Day 8 把 Shizuku 接進專案

  • 分享至 

  • xImage
  •  

昨天 App 終於跑起來了
今天先完成一個很樸實的功能:確認 Shizuku 到底有沒有活著

不用急著刪 App,先確認工具人有來上班

加入 Manifest

Shizuku 透過 ShizukuProvider 把 Binder 傳進我們的 App,所以 Manifest 要加:

<uses-permission
    android:name="android.permission.QUERY_ALL_PACKAGES"
    tools:ignore="QueryAllPackagesPermission" />

<uses-permission
    android:name="moe.shizuku.manager.permission.API_V23" />

<provider
    android:name="rikka.shizuku.ShizukuProvider"
    android:authorities="${applicationId}.shizuku"
    android:enabled="true"
    android:exported="true"
    android:multiprocess="false"
    android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />

exported 要是 true,不然 Shizuku 進不來
multiprocess 要是 false,不然 Provider 到處分身,事情會開始變玄學

QUERY_ALL_PACKAGES 則是因為我們之後要看見手機裡所有 App
套件管理工具如果看不到套件,跟近視的驗光師差不多

確認 Shizuku 狀態

最直接的方法是:

Shizuku.pingBinder()

回傳 true 代表服務有在跑,但還不代表已經授權
有來公司,不代表願意做事

先定義三種狀態:

sealed interface ShizukuState {
    data object NotInstalled : ShizukuState
    data object NotRunning : ShizukuState
    data object Ready : ShizukuState
}

再包進 ShizukuManager:

class ShizukuManager(private val context: Context) {

    private val _state =
        MutableStateFlow<ShizukuState>(ShizukuState.NotRunning)

    val state = _state.asStateFlow()

    fun refresh() {
        val alive = runCatching {
            Shizuku.pingBinder()
        }.getOrDefault(false)

        _state.value = when {
            alive -> ShizukuState.Ready
            isInstalled() -> ShizukuState.NotRunning
            else -> ShizukuState.NotInstalled
        }
    }

    private fun isInstalled() = runCatching {
        context.packageManager.getPackageInfo(
            "moe.shizuku.privileged.api",
            0
        )
        true
    }.getOrDefault(false)
}

判斷時要先 pingBinder(),再檢查有沒有安裝 Shizuku
因為使用 Sui 的手機可能沒有 Shizuku App,但服務照樣活得很好

世界很複雜,不能只看戶口名簿

回到畫面要更新

使用者可能切出去啟動 Shizuku,再回到我們的 App,所以記得:

override fun onResume() {
    super.onResume()
    container.shizuku.refresh()
}

不加這段,畫面會一直顯示「沒有執行」
然後使用者會覺得 App 壞了

通常他是對的,但這次不是

現在畫面已經能分辨 Shizuku 沒安裝、沒啟動或已就緒

明天再補授權和狀態監聽,讓它不要每次都要人類提醒才更新


上一篇
Day 7 終於打開 Android Studio
下一篇
Day 9 處理 Shizuku 授權和生死
系列文
Android 工具箱開發 共 9 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言