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
Related
UPDATE
I'm noticing that I actually am receiving the NETWORK_LOGS_AVAILABLE intent! The problem is, it's taking a very long time (over an hour?) to receive it.
Is there any known way to increase the frequency of receiving these events?
Original Question
I am trying to process DNS events that can now be read after receiving the onNetworkLogsAvailable intent in a DeviceAdminReceiver application. This functionality was made available as of Android 8.0.
For some reason, I am never receiving this intent, even though I am successfully calling the setNetworkLoggingEnabled method. Upon admin being enabled, I am receiving the ACTION_DEVICE_ADMIN_ENABLED event, but nothing else after that.
Here's where I enable network logging:
public class NetworkAdminReceiver extends DeviceAdminReceiver {
#Override
public void onEnabled(Context context, Intent intent) {
DevicePolicyManager manager =
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
if ( manager == null )
{
throw new IllegalStateException("Unable to get DevicePolicyManager");
}
if (manager.isDeviceOwnerApp(context.getPackageName())) {
manager.setNetworkLoggingEnabled(getWho(context), true);
}
else
{
Toast.makeText(context, "This application is not device owner. DNS logging only works" +
" when this application is setup as the Device Owner", Toast.LENGTH_LONG).show();
}
}
// *snip* rest of class
}
Although I am not sure whether it's required (cannot find in documentation), I've also added the NETWORK_LOGS_AVAILABLE intent action to the receiver's filter:
<receiver android:name=".admin.NetworkAdminReceiver"
android:label="#string/device_admin"
android:description="#string/device_admin_description"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="#xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
<action android:name="android.app.action.NETWORK_LOGS_AVAILABLE"/>
</intent-filter>
</receiver>
The application is marked as the device owner, network logging is enabled, and yet I never receive the intent. The only explanation I could think of is that network logs do not become available very frequently, but I could find no documentation supporting this theory.
I am also currently only testing this in the emulator. I am unsure if that would have an effect on this, though I cannot see how it would.
Is there anything that I am missing in order to properly receive the network logs via the DeviceAdminReceiver?
I'm afraid there's no elegant solution.
This limitation looks like it was made intentionally. As you can see in the sources, the event is triggered when hard-coded thresholds are reached. It's either 1200 events or 1.5H timeout, whichever comes first. I did not manage to find any usable hooks in the NetworkLogger. They definitely did not want users to meddle with it.
The only option I see is to use reflection to get access to the hidden API.
The most straightforward, IMHO, is to get a handle to the IIpConnectivityMetrics service and use it to subscribe to the network events. I did not test this solution myself, though.
It seems like you can now force retrieve log for debugging purposes as described here: https://developer.android.com/work/dpc/logging#development_and_testing
Quote from the documentation:
While you’re developing and testing, you might want to receive onNetworkLogsAvailable() callbacks without having to browse hundreds of web pages. In Android 9.0 (API level 28) or higher, you can make a few sample network requests and force the system to send a logs-available callback. Run the following Android Debug Bridge (adb) command in your terminal:
adb shell dpm force-network-logs
The system limits how frequently you can use the tool and reports any intentional slowing in the terminal output. If there aren’t any logs to retrieve, your DPC doesn’t receive a callback.
I am building an app that is designed to run continuously. Furthermore, the user is locked into the app (via the pinning feature) when it is being used. When the app has not detected user interaction for a while, it unpins itself, calls the Android dream service, and displays a screensaver of sorts. When the user taps the device, it 'wakes up', goes to the main screen, and repins itself.
I need my app to auto-update. However, given the circumstances, I have had difficulty in doing so. It simply does not seem to update, or according to one of my colleagues, updated but closed the app.
Is there a way for the app to detect, download, and install an update while running, and then, if necessary, relaunch itself? What would be the best approach?
Thanks much.
Is there a way for the app to detect, download, and install an update while running
This is handled for you by google play store. An app is killed when it is going to be upgraded to a new version so the installation of the new version is smooth and data is not corrupted.
if necessary, relaunch itself?
If you want to keep running (or rather, restart the app) after an upgrade, yes you have to do some additional stuff.
A way that I use is this:
Put in manifest:
<receiver android:name=".receivers.AppUpgraded">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
public class AppUpgraded extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
// your app was just upgraded, restart stuff etc.
}
}
Note there is also a action.PACKAGE_REPLACED which will trigger for ANY app that is upgraded. You're likely only interested in the upgrade of your own app, so use action.MY_PACKAGE_REPLACED.
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
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