在Android上启用Kiosk模式
我们的云帆机器人(上面运行的安卓程序)有一个线下场景是商场,由于商场人多,总会遇到一些用户在我们的app里乱点,然后会跳出程序进入到系统设置的一些界面,这样很不友好。
比如程序中有一些需要输入文字的地方,弹出了输入法,有的用户就去故意点输入法的设置,结果就能进入到安卓的系统设置,商场的用户用的是我们机器人程序而不是手机,并且机器人上本来就屏蔽了多任务和返回等虚拟按键,结果无法返回原来的程序。
一种解决方式是自己在程序里去实现一个中文的输入法,但这代价也太大了。
另外一种方式就是使用安卓的Kiosk模式。这个模式直译的话是贩售亭,但实际上的意思是屏幕固定功能,也就是我们想要将用户看到的屏幕固定到我们的app中的意思。
介绍url https://www.sureshjoshi.com/mobile/android-kiosk-mode-without-root/
源码展示区:https://github.com/sureshjoshi/android-kiosk-example
中文介绍 https://juejin.im/entry/578f873dd342d30058e99c51
只看代码可能不太明白,于是我对着代码自己重新写了一个demo。其中遇到的问题如下:
1.写好了后运行代码,并不能锁住,主要原因是没有admin的权限,这个需要到设置--系统安全--设备管理 中找到这个程序并选中才可以。
2.另外就是有了admin权限后还是不能锁定,debug后发现是判断isDeviceOwnerApp的时候为false,这个是因为一个系统只能有一个OwnerApp,需要使用adb命令设置对应的recevier。命令是:
adb shell dpm set-device-owner com.honghe.screenlocktest/.AdminReceiver
3.注意这个功能只能安卓5.1之后可用
代码如下
MainActivity
1 package com.honghe.screenlocktest; 2 3 import android.app.admin.DevicePolicyManager; 4 import android.content.ComponentName; 5 import android.content.Context; 6 import android.os.Build; 7 import android.support.annotation.RequiresApi; 8 import android.support.v7.app.AppCompatActivity; 9 import android.os.Bundle; 10 import android.util.Log; 11 import android.view.View; 12 13 import java.io.BufferedReader; 14 import java.io.DataOutputStream; 15 import java.io.InputStream; 16 import java.io.InputStreamReader; 17 18 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 19 public class MainActivity extends AppCompatActivity { 20 private static final String TAG = MainActivity.class.getName(); 21 private DevicePolicyManager dpm; 22 private boolean inKioskMode; 23 private ComponentName deviceAdmin; 24 private Process process = null; 25 private DataOutputStream os = null; 26 27 @Override 28 protected void onCreate(Bundle savedInstanceState) { 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.activity_main); 31 findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 32 @Override 33 public void onClick(View v) { 34 lockScreen(); 35 } 36 }); 37 findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() { 38 @Override 39 public void onClick(View v) { 40 dislockScreen(); 41 } 42 }); 43 } 44 45 46 private boolean doLockScreen() { 47 if (dpm.isLockTaskPermitted(this.getPackageName())) { 48 Log.i("yunji.HotelAPP", "start lock screen"); 49 startLockTask(); 50 inKioskMode = true; 51 Log.i("yunji.HotelAPP", "lock screen success"); 52 return true; 53 } 54 Log.w("yunji.HotelAPP", "cannot lock screen"); 55 return false; 56 } 57 58 private void lockScreen() { 59 try { 60 if (!inKioskMode) { 61 dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); 62 deviceAdmin = new ComponentName(this, AdminReceiver.class); 63 Log.e(TAG, "isAdminActive: " + dpm.isAdminActive(deviceAdmin) + "\tisDeviceOwnerApp: " + dpm.isDeviceOwnerApp(getPackageName())); 64 if (dpm.isDeviceOwnerApp(getPackageName())) { 65 //如果这里失效,请使用adb shell命令设置deviceOwnerAPP为当前app $ adb shell dpm set-device-owner com.honghe.screenlocktest/.AdminReceiver 66 //参考 https://juejin.im/entry/578f873dd342d30058e99c51 67 dpm.setLockTaskPackages(deviceAdmin, 68 new String[]{getPackageName()}); 69 Log.e(TAG, "setLockTaskPackages: "); 70 } 71 doLockScreen(); 72 } 73 } catch (Exception e) { 74 Log.e("yunji.HotelAPP", "Exception: " + e); 75 } 76 } 77 78 private void dislockScreen() { 79 80 try { 81 if (inKioskMode) { 82 stopLockTask(); 83 inKioskMode = false; 84 } 85 } catch (Exception e) { 86 Log.e("yunji.HotelAPP", "Exception: " + e); 87 } 88 } 89 }
activity_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8 tools:context=".MainActivity"> 9 10 <TextView 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content" 13 android:text="Hello World!" 14 app:layout_constraintBottom_toBottomOf="parent" 15 app:layout_constraintLeft_toLeftOf="parent" 16 app:layout_constraintRight_toRightOf="parent" 17 app:layout_constraintTop_toTopOf="parent" /> 18 19 <Button 20 android:id="@+id/button" 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:text="锁定" /> 24 25 <Button 26 android:id="@+id/button2" 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:text="解锁" /> 30 31 <EditText 32 android:id="@+id/editText" 33 android:layout_width="match_parent" 34 android:layout_height="wrap_content" 35 android:ems="10" 36 android:inputType="textPersonName" 37 android:text="Name" /> 38 39 </LinearLayout>
AdminReceiver.java
1 package com.honghe.screenlocktest; 2 import android.app.admin.DeviceAdminReceiver; 3 import android.content.Context; 4 import android.content.Intent; 5 6 7 /** 8 * Created by zkzhou on 7/15/16. 9 */ 10 public class AdminReceiver extends DeviceAdminReceiver { 11 @Override 12 public void onEnabled(Context context, Intent intent) { 13 } 14 15 @Override 16 public CharSequence onDisableRequested(Context context, Intent intent) { 17 return "Warning: Device Admin is going to be disabled."; 18 } 19 20 @Override 21 public void onDisabled(Context context, Intent intent) { 22 } 23 24 @Override 25 public void onLockTaskModeEntering(Context context, Intent intent, 26 String pkg) { 27 } 28 29 @Override 30 public void onLockTaskModeExiting(Context context, Intent intent) { 31 } 32 }
androidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.honghe.screenlocktest"> 4 5 <application 6 android:allowBackup="true" 7 android:icon="@mipmap/ic_launcher" 8 android:label="@string/app_name" 9 android:roundIcon="@mipmap/ic_launcher_round" 10 android:supportsRtl="true" 11 android:theme="@style/AppTheme"> 12 <activity android:name=".MainActivity"> 13 <intent-filter> 14 <action android:name="android.intent.action.MAIN" /> 15 16 <category android:name="android.intent.category.LAUNCHER" /> 17 </intent-filter> 18 </activity> 19 <receiver 20 android:name=".AdminReceiver" 21 android:label="@string/app_name" 22 android:permission="android.permission.BIND_DEVICE_ADMIN"> 23 <meta-data 24 android:name="android.app.device_admin" 25 android:resource="@xml/device_admin" /> 26 27 <intent-filter> 28 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> 29 </intent-filter> 30 </receiver> 31 </application> 32 33 34 </manifest>
xml/device_admin.xml
1 <device-admin xmlns:android="http://schemas.android.com/apk/res/android"> 2 <uses-policies> 3 <force-lock/> 4 <watch-login/> 5 <disable-camera/> 6 <disable-keyguard-features/> 7 <encrypted-storage/> 8 <expire-password/> 9 <limit-password/> 10 <reset-password/> 11 <set-global-proxy/> 12 <wipe-data/> 13 </uses-policies> 14 </device-admin>
转载于:https://www.cnblogs.com/dongweiq/p/10250180.html
在Android上启用Kiosk模式相关推荐
- 如何在Schlage Connect Smart Lock上启用休假模式
If you're going on vacation and will be away from home for any significant amount of time, it might ...
- 在Android手机或平板电脑上启用开发者模式选项
这是两个步骤的过程,第一步是在Android手机或平板启用开发模式选项和第二是交换机上的USB调试的设备.让我们看看如何在下面的教程中完成这两个活动. 第1步:启用开发人员选项 1)点击主菜单图标. ...
- android机上没有usb调试模式吗,如何在Android上启用USB调试
Android系统的手机以及平板电脑占有巨大的市场份额,当使用USB数据线完成电脑端与安卓手机端数据传输时,需要将安卓手机开启USB调试模式. 什么是USB调试?USB调试是一种模式,允许Androi ...
- android单手操作系统,生命不息,折腾不止:在 Android 上自制单手模式
手机屏幕做大,在视觉体验上带来的提升是非常明显的,但也因为屏幕变大,单手操作已不再那么现实.针对这种情况,各大厂商都相继推出了相应的解决方案,Android 阵营比较有代表性的有魅族.锤子的下拉悬停和 ...
- android mvp模式鸿洋,Android上的MVP模式
什么是MVP? MVP模式可以分离显示层和逻辑层,所以功能接口如何工作与功能的展示可以实现分离,MVP模式理想化地可以实现同一份逻辑代码搭配不同的显示界面.首先要澄清就是MVP不是一个结构化的模式,它 ...
- 如何在 Chromebook 上启用开发者模式
写在前面的话: 版权声明:本文为博主原创文章,转载请注明出处! 博主是一个小菜鸟,并且非常玻璃心!如果文中有什么问题,请友好地指出来,博主查证后会进行更正,啾咪~~ 每篇文章都是博主现阶段的理解,如果 ...
- android启用hdcp_如何在Android上启用优先收件箱(和设置仅重要通知)
android启用hdcp Yesterday Google released an updated Gmail application for Android 2.2 phones that sup ...
- Android自动启用夜间模式,Android – 切换夜间模式
什么是夜间主题以及如何在ANDROID中使用它? Support Library 23.2(应用于API14+)推出了适合Android Apps的DayNight主题,它将根据时间和用户最后一次提供 ...
- android 判断 飞行模式,如何在Android上检测飞行模式?
叮当猫咪 通过扩展Alex的答案以包括SDK版本检查,我们可以:/** * Gets the state of Airplane Mode. * * @param context * @return ...
- android java 8_四个库,让你在 Android 中启用 Java 8 功能
Java 8 的推出引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时简化了各种设计模式的实现方式,是 Java 有史以来最重要的更新. 自 Android N 之后,由于 J ...
最新文章
- 关于做Android+J2ee系统集成开发的一点心得
- 查看LINUX进程内存占用情况 top pmap ps
- 插上翅膀,让Excel飞起来——xlwings(一)
- SpringBoot+MyBatisPlus整合时提示:Invalid bound statement(not found):**.dao.UserDao.queryById
- oracle的em能干什么,转载 解决Oracle的EM登录
- 在输出终端中消除多余空格
- isNaN与parseInt/parseFloat
- 大学计算机思维导图_【21计算机考研】改考408+1!上海电力大学翻倍扩招,仍考数据结构!...
- sqlServer基础知识
- win10运行python没有硬编码器_windows下关于python的编解码问题
- html作品使用说明,使用说明html模板
- 二行代码解决全部网页木马
- Python 实现一个自动下载小说的简易爬虫
- 游戏服务端究竟解决了什么问题
- oracle招聘ocp认证,OracleOCP认证要通过哪些考试?
- SQL-查询最后一条数据
- CodeForces-1016C Vasya And The Mushrooms(模拟+思维+前缀和的前缀和) 解题报告 Apare_xzc
- HashMap结构图及特点
- cookie注入原理详解
- #18 可视化基础4-簇形柱状图、百分比堆积柱状图、并列子图
热门文章
- RocketMq 启动报错错误: 找不到或无法加载主类 Files\Java\jdk1.8.0_301\jre\lib\ext
- java中 字符串的补位
- 为什么越来越多的人放弃欧美市场,转做Starday日本市场?
- PAT 1034 有理数四则运算 python
- eclipse保存后不会自动编译
- 图像标注工具CVAT
- 开源图像数据集管理工具fiftyone使用
- oracle卸数的perl脚本,卸载cpan安装的所有perl模块
- 高德地图python爬虫 商家_Python3 | 通过百度地图API获取商家详细信息
- 前端自学驿站:【建议收藏】css晦涩难懂的点都在这啦