Android中的自助服务terminal模式

我正在评估是否以及如何将CF .NET企业应用程序移植到Android设备上运行。 Windows Mobile手机上的应用程序在Kiosk模式下运行,应用程序在启动后以全屏模式自动启动,用户无法意外或无意地访问手机的任何其他部分。

是否有可能在启动后只有一个应用程序自动启动,并防止用户意外(或自愿)访问Android设备的任何其他部分?

您可以通过侦听BroadcastReceiver中的android.intent.action.BOOT_COMPLETED意图,在启动时自动启动应用程序,并从那里启动您的Activity。 在活动中,您可以将自己注册为新的默认主屏幕[1]并处理按键。

我认为有些情况下,如果不修改框架,就无法处理(例如,在Home上显示longpress以显示当前活动的应用程序) – 但我也可能会误解。

但是对于一个足够的原型来说。

玩得开心!

[1]:

 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> 

您可以自定义(禁止访问菜单,限制应用程序添加等)来启用信息亭。 http://code.google.com/p/android-launcher-plus/

在新的Android L预览版中,Google已经宣布了“ 任务locking” ,而这正是如此。 它似乎需要root然而。

L Developer Preview引入了一个新的任务lockingAPI,可让您暂时限制用户离开您的应用程序或被通知中断。 例如,如果您正在开发教育应用程序以支持Android上的高风险评估要求,则可以使用此function。 一旦您的应用程序激活此模式,用户将无法看到通知,访问其他应用程序或返回到主屏幕,直到您的应用程序退出该模式。

为了防止未经授权的使用,只有授权的应用程序可以激活任务锁 此外,任务locking授权必须由专门configuration的设备所有者应用通过android.app.admin.DevicePolicyManager.setLockTaskComponents()方法授予。

要设置设备所有者,请按照下列步骤操作:

  • 将运行Android userdebug构build的设备附加到您的开发机器上。
  • 安装设备所有者应用
  • 创build一个device_owner.xml文件并将其保存到设备上的/data/system目录。
 $ adb root $ adb shell stop $ rm /tmp/device_owner.xml $ echo "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" >> /tmp/device_owner.xml $ echo "&device-owner package=\"<your_device_owner_package>\" name=\"*<your_organization_name>\" />" >> /tmp/device_owner.xml $ adb push /tmp/device_owner.xml /data/system/device_owner.xml $ adb reboot 

在应用程序中使用任务lockingAPI之前,请通过调用DevicePolicyManager.isLockTaskPermitted()来validation您的活动是否已获得授权。

要激活任务locking,请从授权活动调用android.app.Activity.startLockTask()

当任务locking处于活动状态时,以下行为将生效:

  • 状态栏为空,用户通知和状态信息被隐藏。
  • Home和Recent Appsbutton被隐藏。
  • 其他应用可能不会启动新的活动。
  • 目前的应用程序可能会开始新的活动,只要这样做不会创造新的任务。
  • 用户保持locking在您的应用程序,直到授权的活动调用Activity.stopLockTask()

找了一段时间后,我想出了一个很好的解决scheme。 这只适用于固定的设备,但我想如果只是为了这个应用程序,然后生根不应该是一个问题。

  • 通过添加您的应用程序启动器

     <category android:name="android.intent.category.HOME" /> 

    到你的意图filter

  • 确保你的应用程序崩溃的工具栏,所以你不能到达通知栏请参阅如何以编程方式禁用android上的状态栏/通知栏? 或http://blog.vogella.com/2011/02/28/android-hidding-the-status-and-title-bar/

  • 然后停止任何其他程序打开错误使用Accessibility服务来检查窗口状态改变,比较包白色或黑色列表,并使用ActivityManager.killBackgroundProcesses杀死,如果它不应该运行。

另外请查看http://thebitplague.wordpress.com/2013/04/05/kiosk-mode-on-the-nexus-7/

设置 Android开发者的单一用途设备页面描述了这个事情,你可以很容易地从那里知道更多的东西。

现在很容易将Android 6.0 Marshmallow和更高版本的设备configuration为公司拥有的一次性(COSU)设备。

启动您的应用程序

最好的方法是将你的应用程序设置为启动器

 <activity ... android:launchMode="singleInstance" android:windowActionBar="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> 

locking您的应用程序

最可靠的方法是使用棒棒糖或更大的设备,并利用

 startLockTask 

首先,您必须将您的应用设置为设备所有者。 注意您的设备必须是未提供的:如果您注册了它,您应该进行工厂重置并跳过帐户注册。

要能够注册您的应用程序,您必须先设置一个DeviceAdminReceiver组件:

 package com.example.myapp; public class MyDeviceAdminReceiver extends android.app.admin.DeviceAdminReceiver { @Override public void onEnabled(Context context, Intent intent) { Toast.makeText(context, "Device admin permission received", Toast.LENGTH_SHORT).show(); } @Override public CharSequence onDisableRequested(Context context, Intent intent) { return "are you sure?"; } @Override public void onDisabled(Context context, Intent intent) { Toast.makeText(context, "Device admin permission revoked", Toast.LENGTH_SHORT).show(); } @Override public void onLockTaskModeExiting(Context context, Intent intent) { // here you must re-lock your app. make your activity know of this event and make it call startLockTask again! } } 

一旦你有一个未configuration的设备,你可以从adb启动以下命令( 不需要root

 adb shell dpm set-device-owner com.example.myapp/.MyDeviceAdminReceiver 

为了避免android要求用户权限来固定你的应用程序,你必须调用setLockTaskPackages

最后!

 @Override public void onResume(){ super.onResume(); DevicePolicyManager mDevicePolicyManager = (DevicePolicyManager) getSystemService( Context.DEVICE_POLICY_SERVICE); ComponentName mAdminComponentName = new ComponentName(getApplicationContext(), MyDeviceAdminReceiver.class); mDevicePolicyManager.setLockTaskPackages(mAdminComponentName, new String[]{getPackageName()}); startLockTask(); } @Override public void finish(){ stopLockTask(); super.finish(); } 

谷歌最近发布了Androidpipe理API ,可以为任何运行Android 5.1或更高版本的Android设备轻松设置Kiosk模式,并设置各种其他策略。

在这个论坛发帖find另一种可能的技术。 引用该post:

http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/10839-android-kiosk-mode-tutorial.html

使用以下方法可以构build一个应用程序,防止“普通”用户使用除应用程序之外的任何其他应用程序。

该应用程序由两个模块组成。 主要活动和一项服务。 该服务被configuration为在启动时启动。 当服务启动时,它检查活动是否正在运行。 如果未运行,则使用定时器启动主要活动。

当活动暂停时,它会安排服务在一秒钟内启动:代码:

 Sub Activity_Pause (UserClosed As Boolean) If kiosk Then StartServiceAt(KioskService, DateTime.Now + 1 * DateTime.TicksPerSecond, false) End Sub 

如果用户在主屏幕上按下,则主屏幕将出现几秒钟。 但是,您的应用程序将在几秒钟后返回到前端,用户将无法与任何其他应用程序交互或更改设置。

该服务被设置为前台服务。 这可以防止Android终止我们的服务。 按停止button可以停用信息亭模式。

似乎还有一个示例kiosk模式代码ZIP文件可供下载 。

Xposed框架可以做到这一点。 它需要根,而且有可能不会在所有的平台上工作。 在类android.app.StatusBarManager中查找disable()方法。

在这里Android的源代码

在这里看看如何编写自己的模块: Xposed开发教程

乍一看比你想象的要容易得多。 祝你好运!

除了使用BOOT接收器设置您的应用程序以及防止状态栏扩展的这个答案之外 ,该解决scheme还可以作为完整的自助服务terminal应用程序在4.4及更高版本上运行:

放在你的onCreate()中:

  final View view = (View) findViewById(android.R.id.content); if (view != null) { //"hides" back, home and return button on screen. view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN); view.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { // Note that system bars will only be "visible" if none of the // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set. if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN); } } }); } 

这将完全隐藏后退button,应用程序和主页button。