Kiosk mode in Android

后端 未结 11 1832
感情败类
感情败类 2020-11-22 11:26

I\'m in the process of evaluating if and how a CF .NET enterprise application can be ported to run on Android devices. The application on Windows Mobile phones are run in ki

相关标签:
11条回答
  • 2020-11-22 11:34

    In the new Android L Preview, Google has announced Task Locking, which does exactly that. It does seem to need root however.

    The L Developer Preview introduces a new task locking API that lets you temporarily restrict users from leaving your app or being interrupted by notifications. This could be used, for example, if you are developing an education app to support high stakes assessment requirements on Android. Once your app activates this mode, users will not be able to see notifications, access other apps, or return to the Home screen, until your app exits the mode.

    To prevent unauthorized usage, only authorized apps can activate task locking. Furthermore, task locking authorization must be granted by a specially-configured device owner app, through the android.app.admin.DevicePolicyManager.setLockTaskComponents() method.

    To set up a device owner, follow these steps:

    • Attach a device running an Android userdebug build to your development machine.
    • Install your device owner app.
    • Create a device_owner.xml file and save it to the /data/system directory on the device.
    $ 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
    

    Before using the task locking API in your app, verify that your activity is authorized by calling DevicePolicyManager.isLockTaskPermitted().

    To activate task locking, call android.app.Activity.startLockTask() from your authorized activity.

    When task locking is active, the following behavior takes effect:

    • The status bar is blank, and user notifications and status information is hidden.
    • The Home and Recent Apps buttons are hidden.
    • Other apps may not launch new activities.
    • The current app may start new activities, as long as doing so does not create new tasks.
    • The user remains locked on your app until an authorized activity calls Activity.stopLockTask().
    0 讨论(0)
  • 2020-11-22 11:39

    After searching for this for a while I've come up with a good solution. This only works on rooted devices though, but I guess if it's just for this one app then rooting it shouldn't be a problem.

    • Make your application the launcher by adding

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

      to your intent-filter

    • Make sure your app collapses the toolbar so you cannot reach the notification bar see How to disable status bar / notification bar on android programmatically? or http://blog.vogella.com/2011/02/28/android-hidding-the-status-and-title-bar/

    • Then to stop any other programs from opening by mistake use an Accessibility Service to check for Window State Changed, compare the package to a white or black list and use ActivityManager.killBackgroundProcesses to kill if it shouldn't run.

    Also check out http://thebitplague.wordpress.com/2013/04/05/kiosk-mode-on-the-nexus-7/ for another way

    0 讨论(0)
  • 2020-11-22 11:39

    Starting your app on boot

    the BEST way to accomplish this is setting your app as the launcher

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

    the most reliable way is to use a device with Lollipop or greater and make use of

    startLockTask
    

    first you must set your app as the device owner. NB your device must be unprovisioned: if you registered it you should do a factory reset and skip the account registration.

    to be able to register your app you must first setup a DeviceAdminReceiver component:

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

    once you have an unprovisioned device you can launch the following command from adb (no root required)

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

    to avoid android asking the user permissions to pin your app you must call setLockTaskPackages

    finally!

    @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();
    }
    
    0 讨论(0)
  • 2020-11-22 11:39

    Set up Single-Purpose Devices Page of android developer have described this things you can easily get to know more things from there.

    Now it is easy to configure Android 6.0 Marshmallow and later devices as corporate-owned, single-use (COSU) devices.

    0 讨论(0)
  • 2020-11-22 11:39

    Along with setting up your application with a BOOT receiver, and this answer for preventing status bar expansion, this solution works on 4.4 and above as a complete kiosk app :

    Place in your 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);
                            }
                        }
                    });
        }
    

    This will completely hide the back button, apps and home button.

    0 讨论(0)
  • Found another possible technique in this forum post. Quoting that post:

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

    Using the following methods you can build an application that will prevent "regular" users from playing with anything other than your application.

    The application is made of two modules. The main activity and a service. The service is configured to start at boot. When the service is started it checks if the activity is running or not. If it is not running it uses a timer to start the main activity.

    When the activity is paused it schedules the service to start in one second: Code:

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

    If the user presses on the home screen, the home screen will appear for several seconds. However your application will return to the front after a few seconds and the user will not be able to interact with any other applications or change the settings.

    The service is set to be a foreground service. This prevents Android from killing our service. Press on the Stop button to deactivate kiosk mode.

    There appears to be an example kiosk-mode code ZIP file available for download, too.

    0 讨论(0)
提交回复
热议问题