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?
You can autostart applications on boot by listening to the android.intent.action.BOOT_COMPLETED intent in a BroadcastReceiver and start your Activity from there. In the Activity you can register yourself as the new default homescreen[1] and handle the keys.
I think there are some instances that you can't handle without modifying the framework (like longpress on Home to show currently active Applications) - I could also be mistaken though.
But for a prototype that could be sufficient.
Have fun tinkering!
[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>
You could customise this (disable access to menu, limit application addition etc) to enable kiosk. http://code.google.com/p/android-launcher-plus/
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().
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
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();
}
Google recently released the Android Management API which allows to easily set up kiosk mode for any Android devices running Android 5.1 or above, and also to set various other policies.
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.
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.
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!
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.
Kiosk mode is nothing but locking a single or set of applications when you switch on an android device. This can be achieved by lock task mode. When the device runs in lock task mode, users typically can’t see notifications, access non-whitelisted apps, or return to the home screen.
The Device policy controller (DPC) can whitelist the app that can run when the system is in lock task mode. Since its a dedicated device for a specific purpose the person using the device can't leave lock task mode. The device which are Android 5.0 and higher can run in lock task mode.
• Whitelisting the applications
First step is to whitelist the application by DPC.
DPC can whitelist the apps which can be used in lock task mode by calling
DevicePolicyManager.setLockTaskPackages()
▪ Start lock task mode
Once the whitelisting is done, DPC can call the below function to start the lock task.
ActivityOptions.setLockTaskEnabled()
You can find more details regarding the lock task mode here. https://developer.android.com/work/dpc/dedicated-devices/lock-task-mode
Related
I developed a Device Owner App (Full Kiosk) and in Lock Task Mode, that once installed on a provisioned device, it's instructed to set itself on the top of the screen.
Everything was fine until some day ago, when on some devices, after a firmware upgrade, an issue has come out.
Device: BlackView BV6000
Android: 8 Oreo (API l. 26)
At the device boot (or re-boot), the app get opened itself on the PIN screen, above it, and so It stops the device boot as I cannot insert my PIN any more and it occupy the screen as main (and only) activity.
Normally, the boot sequence would be:
LOCK_BOOT_COMPLETED
BOOT_COMPLETED
App start
but in this case the app would open itself in any case once the device has direct booted on the PIN lock screen.
The only receiver I have left in manifest.xml (I have removed all other receivers, but App still opens itself):
<receiver
android:name=".receivers.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="AlarmReceiver" />
</intent-filter>
</receiver>
In my opinion, it would be caused by the fact that as an Alarm it's in the common case always awaiting to be delivered, once the device boots, my app receives the alarm intent, so it awakes the alarm receiver, and in doing so, it for sure awake the whole App, that it would be set-up as Device Owner and in lock taskmode so what I obtain is that my app gets in foreground over the PIN lock screen before I could actually do anything and force me to use it.
Additionaly, the app is set up to be the launcher by following lines:
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
intentFilter.addCategory(Intent.CATEGORY_HOME);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
devicePolicyManager.addPersistentPreferredActivity(
adminComponentName, intentFilter, new ComponentName(
context.getPackageName(), MyActivity.class.getName()));
Addirtionally, I make the keyguard disabled by:
devicePolicyManager.setKeyguardDisabled(adminComponentName, true);
My question is: how can I prevent the app to get in foreground over the PIN lock screen? I would like to make my app opening after the lock screen (on real BOOT_COMPLETE) but I don't have any clue about how to prevent the app to boot up once it gets the Alarm intent.
After a bit of investigations I found the origin of the issue.
The solutions is to do not open the app as the HOME app, so that it would override the PIN lock screen on some devices, instead it's important to bind it to be open on the desidered events (i.e. boot, reboot, default action, ...)
Solution's implementation follows:
I removed from my AdminController:
intentFilter.addCategory(Intent.CATEGORY_HOME);
related to devicePolicyManager.addPersistentPreferredActivity(•)
(and also add to be sure of proper reset)
devicePolicyManager.clearPackagePersistentPreferredActivities(
adminComponentName, context.getPackageName());
and also removed from my manifest:
<category android:name="android.intent.category.HOME" />
P.S. I found that the action BOOT_COMPLETED it's not always delivered correctly (even using it together with QUICKBOOT_POWERON), and so that's the reason I was using the CATEGORY_HOME intent.
I changed my previous solution.
As the fact of the BOOT_COMPLETED doesn't triggers so affordably in Android system, also due to Android security policies, even if the app is in Device Owner COSU mode (lock task), I had to revert back to the CATEGORY_HOME intent.
So to solve my previous problem, I found that was caused by calling startLockTask when the app was in background under the PIN lock screen, and usually it would stayed on an activity under the screen. I just needed to add a check as follow to ensure that the app would be locked only if the screen is unlocked.
KeyguardManager myKM = (KeyguardManager) this.getSystemService(Context.KEYGUARD_SERVICE);
if( !myKM.inKeyguardRestrictedInputMode() && MyApp.getInstance().isAppInForeground() ) {
adminController.lockApp(this);
}
I want my Android app work like this:
When a new USB device is connected, and my app is already active, my app asks for permission to use the USB device.
When the same (type of) USB device is connected again, and my app is active, then my app can use it without having to ask for permission again.
If my app is active, the current activity continues running (rather than
a new Activity being started) when a known USB device is connected.
I can't get #3 to work: Android 9 insists on starting a new Activity, because my app is registered as a default handler for this USB device. I don't care about default handlers: I don't need an app to be started when the device is connected. (However, I do need #2.)
I tried this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0) {
finish();
return;
}
...
}
Unfortunately this didn't work: it removed both copies of my activity from the stack, navigating back to the Android home screen. I only want to remove or prevent the Activity automatically created by Android when a known USB device is connected.
What I want is possible, the app Serial USB Terminal seems to work like this.
How can I accomplish it?
the 'Serial USB Terminal' app uses
android:launchMode="singleTask"`
As you can see in https://github.com/kai-morich/SimpleUsbTerminal, launchMode=singleTask and singleTop have same effect for most apps. Only if you would start another activity in the app, e.g. Android Settings then you should use singleTask, else a new MainActivity would be started when the settings activity is currently shown.
This (singleTop) seems to have fixed it in the manifest:
<activity android:name=".MainActivity" android:launchMode="singleTop">
I'm not sure if this is the right way to solve it though.
The device we’re speaking about is an Android 8 head unit with an external USB keyboard attached.
Well, I need to assign some tasks to this keyboard’s function keys, e.g. launching certain applications. Say, F4 can launch the media player, F5 the navigation app and so on. Either the Automate or the AutoInput Tasker plugin would be nice for this purpose, but all of this kind of applications use accessibility service for interacting with physical HID devices.
The big problem here is that this particular Android device regularly kills the accessibility services on (warm) reboot. Tried absolutely everything, from disabling power save mode to mark the Automate etc. as device admin app, nothing helped. So I have resigned and now I’m thinking for an alternative way to re-enable the appropriate accessibility service after the system disabled it after reboot for an unknown reason.
If the device was rooted I suppose there would be an easy way to restart an accessibility service by a shell command or whatever (just guessing, I’m pretty beginner in Android). But obviously I want to avoid rooting if possible. The ideal scenario would be to (auto)start a shell command / application / foreground service / whatever on each reboot – which would have enough administrative privileges to re-enable the accessibility service the system just have disabled during the reboot. Of course, all this stuffs without rooting the device. But I’m not really sure this can be done on Android (on Windows it would be enough a service running in System account, but Android is a different story).
A fair solution might be to
root the device,
install the shell command (application, foreground service, whatever) meant to restart the accessibility service after each reboot and
unroot the device (using SuperSU by example) in order to protect the user and not to void the warranty.
Would anybody tell me whether the above solution can give the desired result, and – if so – may I have some guidelines how to do this?
to achieve your purpose you should work with BroadcastReceiver and jobIntentService
first create a boot receiver
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
MyService.enqueueWork(context, new Intent());
}
}
}
add it to the manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".MyService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
Now you have to define your jobIntent
public class MyService extends JobIntentService {
public static final int JOB_ID = 0x01;
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, MyService.class, JOB_ID, work);
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
// your code
}
}
And that’s it. This will directly start the service (when running on pre-O platforms) or enqueue work for it as a job (when running on O and later). No matter what the platform is, everything you pass in enqueueWork will ultimately appears in onHandleWork.
here is some useful links : link - link
I am working on an application where I am using Google Push Notification. Application receives notification when it is running in Xiaomi phone otherwise when it's killed it does not receive notification.
If we want to receive notification if application is killed then we need to allow auto restart app manually from security app of xiaomi. I want any trick to do this programmatically without asking user. Is there any way to do this ?
http://en.miui.com/thread-33826-1-1.html
There are five settings that needs to be done manually in case of xiaomi to properly run any application. I have done a lot of research on this and there's no way to fix these settings programmatically. These are the settings:
Auto Start -> ON (Toggle and restart your app)
MIUI Optimization under Developer Options -> OFF
Memory Optimization under Developer Options -> LOW/OFF
No restrictions on background activities under Battery & Performance Settings
Battery Saver -> OFF
There are many other devices in which the manual settings needs to be done in order for the app to work as expected e.g. Lenovo, some Micromax devices. Companies impose these kind on restrictions on background activities to improve the overall battery life. Some apps like facebook and whatsapp work correctly as these might have been included as system apps.
After MIUI 6 & 7:
MIUI power saving mode is default set to "Standard" (Background access to the location services and the network will be restricted)
Where to set:
Settings -> Additional settings -> Battery & performance -> Manage apps battery usage -> Power Saving Modes -> Set to Off (MIUI won't restrict background activities)
As for my understanding once you clear apps or clear memory in Recent Apps menu, xiaomi (or MIUI rom) will force close all the services and memory related to that app similar to user going to settings and force stopping app ,
This Link talks about the same issue, hence all the Broadcast receivers and Services will be ended unless started by the user again, so the notification wont be received,
However you can try just enabling auto-start for your app permissions in settings and If it still doesn't work try creating service that restarts by itself and enable auto-start in the settings,
AutoStart is very important in MIUI, untill its enabled all the notification or app activity will be force closed and will never start
I faced a similar issue and fixed it by adding a BOOT_COMPLETED receiver to my app.
Add following to manifest :
<receiver
android:name=".receivers.BootReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Then create your BootReceiver class
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Intent startServiceIntent = new Intent(context, FBTokenService.class);
context.startService(startServiceIntent);
Intent notificationServiceIntent = new Intent(context, FBNotificationService.class);
context.startService(notificationServiceIntent);
}
}
}
It should work with this.
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?
You can autostart applications on boot by listening to the android.intent.action.BOOT_COMPLETED intent in a BroadcastReceiver and start your Activity from there. In the Activity you can register yourself as the new default homescreen[1] and handle the keys.
I think there are some instances that you can't handle without modifying the framework (like longpress on Home to show currently active Applications) - I could also be mistaken though.
But for a prototype that could be sufficient.
Have fun tinkering!
[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>
You could customise this (disable access to menu, limit application addition etc) to enable kiosk. http://code.google.com/p/android-launcher-plus/
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().
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
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();
}
Google recently released the Android Management API which allows to easily set up kiosk mode for any Android devices running Android 5.1 or above, and also to set various other policies.
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.
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.
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!
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.
Kiosk mode is nothing but locking a single or set of applications when you switch on an android device. This can be achieved by lock task mode. When the device runs in lock task mode, users typically can’t see notifications, access non-whitelisted apps, or return to the home screen.
The Device policy controller (DPC) can whitelist the app that can run when the system is in lock task mode. Since its a dedicated device for a specific purpose the person using the device can't leave lock task mode. The device which are Android 5.0 and higher can run in lock task mode.
• Whitelisting the applications
First step is to whitelist the application by DPC.
DPC can whitelist the apps which can be used in lock task mode by calling
DevicePolicyManager.setLockTaskPackages()
▪ Start lock task mode
Once the whitelisting is done, DPC can call the below function to start the lock task.
ActivityOptions.setLockTaskEnabled()
You can find more details regarding the lock task mode here. https://developer.android.com/work/dpc/dedicated-devices/lock-task-mode