You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过编程方式开启/关闭Screen Pinning?替代手动操作实现方法问询

嘿,我来帮你搞定Android上的Screen Pinning编程控制问题,完全不用用户去设置里折腾!

应用内控制Screen Pinning的实现方案

一、编程方式开启/关闭Screen Pinning

首先明确:Screen Pinning是Android 5.0(API 21)引入的功能,所以先确保你的应用目标API不低于21。

开启Screen Pinning的步骤:

  1. 声明权限:在AndroidManifest.xml里添加必要权限:
<uses-permission android:name="android.permission.REQUEST_PIN_APP" />
  1. 发起固定请求:通过系统弹窗让用户确认(不用跳设置页面),用户同意后即可固定当前页面。推荐用AndroidX的ActivityResultContracts处理回调:
// 在Activity中初始化请求回调
private val requestPinApp = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // 用户确认后,执行固定操作
        startLockTask()
    } else {
        // 用户拒绝,可做相应提示
        Toast.makeText(this, "未开启屏幕固定", Toast.LENGTH_SHORT).show()
    }
}

// 触发固定请求的方法
fun requestScreenPinning() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        val intent = Intent(DevicePolicyManager.ACTION_REQUEST_PIN_APP).apply {
            putExtra(DevicePolicyManager.EXTRA_PACKAGE_NAME, packageName)
            // API23+可选:设置后用户无法通过返回键退出固定
            putExtra(DevicePolicyManager.EXTRA_PINNING_FLAGS, DevicePolicyManager.PINNING_FLAG_NO_UNPIN)
        }
        requestPinApp.launch(intent)
    } else {
        Toast.makeText(this, "设备不支持屏幕固定功能", Toast.LENGTH_SHORT).show()
    }
}
  1. 特殊场景:如果你的应用是设备所有者应用(比如企业管理类应用),可以跳过用户确认,直接调用startLockTask(),但这种场景比较小众。

关闭Screen Pinning的步骤:

只有当前被固定的应用或设备所有者应用才能执行关闭操作,代码非常简单:

fun stopScreenPinning() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && isLockTaskModeActive()) {
        stopLockTask()
    }
}

可以用isLockTaskModeActive()判断当前是否处于固定状态。

二、应用内按钮或Tile Service实现控制

1. 应用内按钮实现

直接在Activity中添加按钮,绑定点击事件结合上述方法即可:

// 示例:绑定按钮点击事件
binding.btnTogglePinning.setOnClickListener {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (isLockTaskModeActive()) {
            stopScreenPinning()
            binding.btnTogglePinning.text = "开启屏幕固定"
        } else {
            requestScreenPinning()
            binding.btnTogglePinning.text = "关闭屏幕固定"
        }
    } else {
        Toast.makeText(this, "设备不支持该功能", Toast.LENGTH_SHORT).show()
    }
}

用户点击按钮就能切换固定状态,全程不用离开你的应用。

2. 快速设置Tile Service实现

如果想让用户从下拉状态栏快速控制,可以实现一个Tile Service:

  1. 创建Tile Service类
class ScreenPinningTileService : TileService() {
    override fun onClick() {
        super.onClick()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
            val intent = Intent(this, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
                // 传递操作类型
                putExtra("ACTION_TYPE", if (activityManager.isLockTaskModeActive) "STOP" else "REQUEST")
            }
            startActivity(intent)
        }
    }

    override fun onStartListening() {
        super.onStartListening()
        // 更新Tile的显示状态
        val tile = qsTile ?: return
        val isActive = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            (getSystemService(ACTIVITY_SERVICE) as ActivityManager).isLockTaskModeActive
        } else {
            false
        }
        tile.state = if (isActive) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
        tile.updateTile()
    }
}
  1. 在Manifest中注册Tile Service
<service
    android:name=".ScreenPinningTileService"
    android:label="屏幕固定"
    android:icon="@drawable/ic_pin"
    android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
    <intent-filter>
        <action android:name="android.service.quicksettings.action.QS_TILE" />
    </intent-filter>
</service>
  1. 在MainActivity中处理Tile传递的意图
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...
    intent.extras?.let {
        when (it.getString("ACTION_TYPE")) {
            "REQUEST" -> requestScreenPinning()
            "STOP" -> {
                stopScreenPinning()
                finish() // 处理完关闭Activity,回到原界面
            }
        }
    }
}

用户把Tile添加到快速设置栏后,点击就能切换固定状态,非常便捷。

注意事项

  • Android 12及以上版本,ACTION_REQUEST_PIN_APP的Intent必须正确设置EXTRA_PACKAGE_NAME为你的应用包名,否则请求会失败。
  • 普通应用只能固定自己,无法强制固定其他应用。
  • 如果用户在系统设置中关闭了Screen Pinning功能,你的应用请求会被拒绝,建议在请求前先检查功能可用性。

内容的提问来源于stack exchange,提问作者hamid reza

火山引擎 最新活动