诸君安好,此乃吾初度著文。亦初试撰文之事。
今且略叙己志。
吾名Давран,乃安卓匠人也,八载研习,制诸般掌中器。
吾之履历:
今朝,吾欲以安卓机柜为题,开吾之述怀。
初见,安卓之亭台应用,似简:但求将客囚于屏之一隅。
然实践之,事颇繁复。
吾于Pai之项目,既营平板之应用,复撰启动器(虽后知非启动器也)。
*亭台者何?
亭台应用者,此乃限权之应用,用户不得越出此应用之外.
此等方案,多用于终端、POS系统、信息亭及自助服务之设备.
其要求
初期,所求似简,吾有少许撰作安卓启动器之验,遂以为此识及若干GitHub上之小试足矣解此题。
然吾心中多惑,遂引吾求此域之文牍(链接__JHSNS_SEG_f8fbe380_17__)
总之所需者:
- 用户不能出应用
- 应用须随设备启动而自启
- 不可授系统设置与界面之权
实现之方
所需者,惟些许文牍,数段代码而已
所本之策,乃Device Owner与Lock Task Mode也
既而,当入于代码之实矣...
售货机控制器
首事,当习设备策略管理器API
简言之,此乃设备管理员之API,使吾辈得行诸事(如管理应用、管理设备之设置等)
然为此,吾辈需二者之一,或得所需权限,或具管理员之权柄(此非设备之越狱也)
继而,吾辈当习知KeyguardManager API
此API,吾辈用以操弄设备之锁屏,尤以监听其状态为要
且,吾辈亦需立DeviceAdminReceiver 以获取吾等应用之既设配置
1 - 吾辈需立应用白名单,俾其得以于自助模式运行,故当构制包名数组:
private val WHITE_LIST_PACKAGES = arrayOf(
"your.package.name",
"dev.firebase.appdistribution",
"com.android.settings"
)
2 - 吾辈构制 KioskController 之典,并立系服务之引
private val dpm = context.getSystemService(DevicePolicyManager::class.java)
private val keyguard = context.getSystemService(KeyguardManager::class.java)
private val admin = ComponentName(context, AdminReceiver::class.java)
3 - 主要工作将由我们DevicePolicyManager完成
而第一行魔法代码是
dpm.setLockTaskPackages(admin, arrayOf(WHITE_LIST_PACKAGES))
此命令向系统发送白名单应用列表,可在自助服务模式下打开
第二行魔法代码
dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_NONE
)
此命令将关闭所有在自助模式下设置的UI元素(状态栏、导航栏,简言之,在自助模式下,系统所有外部UI均被关闭)
我所发现的唯一缺点是新API的曲折,因标志
DevicePolicyManager.LOCK_TASK_FEATURE_NONE将关闭所有
然无全选之旗,故须合用诸旗,方得返于自助模式
dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_HOME or
DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW or
DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS or
DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
)
及至出口,得二函数
fun enterAdminMode() {
if (!isDeviceOwner()) return
dpm.setLockTaskFeatures(
admin,
DevicePolicyManager.LOCK_TASK_FEATURE_HOME or
DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW or
DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS or
DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
)
}
fun exitAdminMode() {
if (!isDeviceOwner()) return
dpm.setLockTaskFeatures(admin, DevicePolicyManager.LOCK_TASK_FEATURE_NONE)
}
尚有辅助
fun canStartLockTask(): Boolean {
if (!isDeviceOwner()) return false
if (!dpm.isLockTaskPermitted(context.packageName)) return false
return !keyguard.isDeviceLocked
}
isLockTaskPermitted__——此乃验应用得入机柜之权
fun isDeviceOwner(): Boolean = dpm.isDeviceOwnerApp(context.packageName)
验设备管理员之权
DevicePolicyManager亦具添制限之能
者,可令器物有开关之能:
- 此为保险箱
- 重置出厂设置
- 连接外置USB
- 添设账户于器上
- 蓝牙之设
复有他事多多。__JHSNS_SEG_f8fbe380_77__变量admin者,即DeviceAdminReceiver也。
者,助系统辨明诸此设定之施行处也。
*安装应用
控制器之设既成,当复将设备归诸出厂之态,启USB调试,许以USB安装,且勿于设备上立帐亦勿认帐。
吾置吾之應用於設備,啟終端,執行命命。
設置設備擁有者
adb shell dpm set-device-owner "your.package.name/com.example.AdminReceiver
移除设备主人
adb shell dpm remove-active-admin "your.package.name/com.example.AdminReceiver
吾等当指明吾等之AdminReceiver(此乃吾等于KioskController中所创之DeviceAdminReceiver)之路径
class AdminReceiver : DeviceAdminReceiver()
于此,吾等所余者,惟将吾等之应用设为设备之主屏启动器耳,且贺君,君今为设备之主于机柜模式矣。
P.S - 吾以 SingleActivity 之架构,增一隐秘之键,俾启 AdminScreen。
输入管理员密码,脱出平板配置之模式。
若尔欲闻其详,吾可细述之。
























