Kiosk mode in Android

2018-12-31 12:59发布

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 kiosk mode where the application autostart in fullscreen-mode after booting and with the users unable to accidentally or willingly access any other parts of the phone.

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条回答
初与友歌
2楼-- · 2018-12-31 13:10

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.

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

查看更多
怪性笑人.
3楼-- · 2018-12-31 13:13

Xposed framework can do this. It needs root and there is a possibility that it won't work on every and all platforms. Look for disable() method in class android.app.StatusBarManager.

Here in Android source code

Look here on how to write your own module: Xposed development tutorial

It's much easier than you think at first glance. Good Luck!

查看更多
浪荡孟婆
4楼-- · 2018-12-31 13:16

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.

查看更多
不流泪的眼
5楼-- · 2018-12-31 13:18

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.

查看更多
怪性笑人.
6楼-- · 2018-12-31 13:23

You could customise this (disable access to menu, limit application addition etc) to enable kiosk. http://code.google.com/p/android-launcher-plus/

查看更多
何处买醉
7楼-- · 2018-12-31 13:28

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();
}
查看更多
登录 后发表回答