首页 文章

Android中的Kiosk模式

提问于
浏览
103

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

Is it possible on Android to have only one application autostart after booting and prevent users from accidentally (or willingly) access any other parts of the Android device?

10 回答

  • 9

    您可以通过侦听BroadcastReceiver中的 android.intent.action.BOOT_COMPLETED intent并从那里启动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>
    
  • 0

    您可以自定义此选项(禁用对菜单的访问,限制应用程序添加等)以启用自助服务终端 . http://code.google.com/p/android-launcher-plus/

  • 17

    在新的Android L预览版中,谷歌宣布Task Locking,就是这样 . 但它似乎确实需要root .

    L Developer Preview引入了一个新的任务锁定API,可让您临时限制用户离开您的应用或被通知中断 . 例如,如果您正在开发教育应用程序以支持Android上的高风险评估要求,则可以使用此功能 . 一旦您的应用激活此模式,用户将无法看到通知,访问其他应用或返回主屏幕,直到您的应用退出该模式 . 为防止未经授权的使用,只有授权的应用才能激活任务锁定此外,任务锁定授权必须由特殊配置的设备所有者应用程序通过android.app.admin.DevicePolicyManager.setLockTaskComponents()方法授予 . 要设置设备所有者,请执行以下步骤:将运行Android userdebug版本的设备附加到开发计算机 . 安装您的设备所有者应用 . 创建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
    

    在应用程序中使用任务锁定API之前,请通过调用DevicePolicyManager.isLockTaskPermitted()来验证您的活动是否已获得授权 . 要激活任务锁定,请从您的授权活动中调用android.app.Activity.startLockTask() . 当任务锁定处于活动状态时,以下行为将生效:状态栏为空,并隐藏用户通知和状态信息 . 主页和最近的应用程序按钮被隐藏 . 其他应用可能无法启动新活动 . 当前应用程序可能会启动新活动,只要这样做不会创建新任务 . 在授权活动调用Activity.stopLockTask()之前,用户将保持锁定在您的应用上 .

  • 1

    经过一段时间的搜索,我找到了一个很好的解决方案 . 这只适用于root设备,但我想如果只是这个应用程序,那么生根应该不是问题 .

    • 通过添加使您的应用程序成为启动器
    <category android:name="android.intent.category.HOME" />
    

    你的意图过滤器

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

  • 26

    Set up Single-Purpose Devices Page的android开发者已经描述了这些东西,你可以从那里轻松了解更多的东西 .

    现在很容易将 Android 6.0 Marshmallow and later 设备配置为公司拥有的一次性(COSU)设备 .

  • 2

    forum post中找到了另一种可能的技术 . 引用该帖子:

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

    使用以下方法,您可以构建一个应用程序,以防止“常规”用户使用除您的应用程序之外的任何其他内容 . 该应用程序由两个模块组成 . 主要活动和服务 . 该服务配置为在引导时启动 . 启动服务时,它会检查活动是否正在运行 . 如果它没有运行,它使用计时器来启动主要活动 . 当活动暂停时,它会安排服务在一秒钟内启动:代码:

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

    如果用户按下主屏幕,主屏幕将显示几秒钟 . 但是,您的应用程序将在几秒钟后返回到前面,用户将无法与任何其他应用程序交互或更改设置 . 该服务被设置为前台服务 . 这可以防止Android终止我们的服务 . 按“停止”按钮可停用信息亭模式 .

    似乎也有example kiosk-mode code ZIP file available for download .

  • 3

    启动时启动应用程序

    实现此目的的最佳方法是将您的应用程序设置为启动器

    <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>
    

    锁定您的应用

    最可靠的方法是使用Lollipop或更高版本的设备并使用

    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!
        }
    }
    

    一旦你有一个未设置的设备,你可以从adb( no root required )启动以下命令

    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();
    }
    
  • 2

    谷歌最近发布了Android Management API,它允许为运行Android 5.1或更高版本的任何Android设备轻松设置信息亭模式,还可以设置各种其他策略 .

  • 2

    Xposed framework 可以做到这一点 . 它需要root,并且它可能无法在所有平台上运行 . 在类 android.app.StatusBarManager 中查找 disable() 方法 .

    Here in Android source code

    看看如何编写自己的模块:Xposed development tutorial

    这比你初看起来容易得多 . 祝好运!

  • 16

    除了使用BOOT接收器设置应用程序,以及this answer以防止状态栏扩展,此解决方案适用于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);
                            }
                        }
                    });
        }
    

    这将完全隐藏后退按钮,应用程序和主页按钮 .

相关问题