I have a rooted device that runs a custom launcher, I need to remove the actionbar/navigationbar/statusbar so that only the launcher can be used, and non of the native android stuff can be accessed.
I've tried almost all of the method's I could find on stackoverflow.
So I really help trying to figure out why this is not working.
I've also tried using immersive UI flags, but this still lets you access the navigation changes when you change focus.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}
private void hideSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
You can't disable the statusbar or navigationbar from AndroidManifest.xml. The only thing you could do is start immersive mode, but that would only hide them. So they would be still accessible.
You can take a look at GravityBox' sources, they disable/enable the navigationbar with root.
You can use themes that have no action bar and use fullscreen.
eg android:Theme.Holo.NoActionBar.Fullscreen
In your styles.xml
<resources>
<style name="AppBaseTheme"
parent="android:Theme.Holo.NoActionBar.Fullscreen"/>
<style name="AppTheme"
parent="AppBaseTheme">
// to do...
Have a look here:
Using Platform Styles and Themes
You can also set you app to be the home launcher for the device.
In terms of preventing people access to the settings, 4.2.2 is not helpful, and this is difficult outside of lollipop, where user accounts can be created with restricted access. As the user can always pull down to get the settings.
There are apps you can use that prevent users from uninstalling apps and making changes to settings. These are password protected, and can work well with other restrictive measures.
Related
Android introduced Dark Theme in API level 29 and higher (https://developer.android.com/guide/topics/ui/look-and-feel/darktheme). To support Dark Theme in your own app your app's theme needs to inherit from DayNight theme.
But what if you did your own theming, is there any intent from Android to get noticed about the system theme change?
If you add android:configChanges="uiMode" to your activities in the manifest, when the user changes the theme, the onConfigurationChanged method is called. If you override that you can do all the related work in there. In order to check what the current theme is you can do the following:
val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme
Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme
}
EDIT: Since the original question isn't specific to Kotlin, here is the Java version of the above for reference:
int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
case Configuration.UI_MODE_NIGHT_NO:
// Night mode is not active, we're using the light theme
break;
case Configuration.UI_MODE_NIGHT_YES:
// Night mode is active, we're using dark theme
break;
}
(source)
I need to hide the content of my application when it goes to the background so sensitive information are not showing up on the android multitasking view.
It's been suggested to use the following line to hide the screen
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
It works fine.
However, this prevents the user from taking screenshot as well which is not an expected behavior for me. I want to let the user take screenshot of the app if they need to. What I don't want is Android to display the latest screen on the multitasking view.
Would it be possible to set the FLAG_SECURE only when the app goes in the background?
We've ended up with this solution which worked the best for us:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
You can use Activity Lifecycle Callbacks. Just call setVisiblity(View.INVISIBLE) on the views that you want to hide in the onPause() Callback and setVisiblity(View.VISIBLE) in onResume() Callback.
So the general consensus is this; most people use their phones in portrait and most people use their tablet in landscape. Depending on which activity it is my app's layout goes crazy when you rotate on the phone to landscape and it just wouldn't be worth the time to fix considering users are unlikely to rotate here and have no reason to do so. I'm aware of the ole orientation="portrait" trick in the Manifest in the activity element, however this locks tablet users into portrait which wouldn't be appropriate. I would like to disable portrait on all my activities for tablet users yet simultaneously disable landscape on most all my activites for phone users. I tried to pull a fast one by making a layout-large-land folder and no layout-large folder, but that doesn't prevent the orientation from changing on tablets.
If you just use setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) from code you will catch interesting effect on Android 26+. If the system autorotation option is enabled and you hold phone in landscape orientation and start new Activity it will appears in landscape orientation and then rotate to portrait in a few seconds. You doesn't catch such effect if set android:screenOrientation="portrait" option in the AndroidManifest. But there are not way to have different rotation option into AndroidManifest for phone and tablet.
There's way to solve that if you wish lock portrait orientation on phone and unlock autorotation on tablet.
Set option android:screenOrientation="locked" in the AndroidManifest for each Activity in you project.
<activity android:name=".SomeActivity"
android:screenOrientation="locked" />
where "locked" – Locks the orientation to its current rotation, whatever that is. Added in API level 18 from Android docs
Then set in parent BaseActivity such code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
int orientation = getResources().getConfiguration().orientation;
if (isTablet()) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
} else if(orientation != Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
There are a few ways to detect that current device is Tablet. Choose implementation of isTablet() method yourself.
I guess you can use a code like this in onCreate() method:
int screenLayoutSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_SMALL || screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
And don't specify any orientation in xml, so by default it switches in both mode.
My suggestion would be to first find the way to know at run-time whether the activity is being executed in a Tablet by invoking a resource as explained in this answer. Then set the orientation as explained in this answer.
-Do One thing put this on the in the res/values file as bools.xml or whatever (file names don't matter here):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
and Put this one in res/values-sw600dp and res/values-xlarge:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
and then into java class file write this below code in onCreate method:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Devices that are more than 600 dp in the smallest width direction.
see the below link for the how to add directories and file into android studio project
in an android app,
if you create a new project,
then automatically the 3 dot settings menu is created on phones where it is needed
and it is handled the same way as it would have in older versions by:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
if you create a custom title, you have to add the 3 dot menu yourself
how do I know when it is needed? meaning phones that don't have the settings button
also how do i create a context menu that is customized and attached to the 3 dot button
Edit:
after a disscusion with Shobhit Puri, I understood that I was not considering the actionbar, since I am using a minimum API 8, I don't have it,
so there is the option that CommonsWare just supplied to check if the settings menu exists (I still need to check if it exists in API 8)
Shobhit Puri's suggestion was:
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(...) ;
ActionBar ab = getActionBar();
ab.setTitle("My Title");
ab.setSubtitle("sub-title") ;
but that of cores requires API 11 or the support library V7
either way I am excepting Shobhit Puri's answer, because of all his help, and I will post my final solution when I know it works
also thanks to CommonsWare for a nice answer
Edit2:
I decided to go with CommonsWare solution for now, I wrote it like this:
if (android.os.Build.VERSION.SDK_INT >= 14) {
ViewConfiguration vc = ViewConfiguration.get(this);
if (!vc.hasPermanentMenuKey()) {
setting_dots.setVisibility(View.VISIBLE);
setting_dots.setOnClickListener(this);
registerForContextMenu(setting_dots);
}
}
ideally I think you should use the actionbar, because it provides you with most of the work, but it has a lot of compatability issues with API 8 which for now I would rather avoid
As #dumazy pointed out that the Action bar's Menu Overflow icon is only shown on those devices which do not have a hardware menu-button.
How do I know when it is needed? meaning phones that don't have the settings button
This is handled by Android itself. You don't need to worry.
how do i create a context menu that is customized and attached to the 3 dot button
You can just have a an xml file inside Menu folder in res. Then you can specify the xml file inside the MenuInflater. Eg:
lets name it list_menu.xml
?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/menu_item_1"
android:title="#string/menu_string_1"
android:showAsAction="ifRoom|withText"/>
<item android:id="#+id/menu_item_1"
android:title="#string/menu_string_2"
android:showAsAction="ifRoom|withText"/>
</menu>
In the onCreateOptionsMenu you can set it as:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.list_menu, menu);
return true;
}
This menu would be attached to the overflow-icon and have the items that you want to show when it is clicked. There are some hacks like this which can show the overflow-icon on all devices but using them is highly discouraged. Let android handle this itself.
You seem to use Title bar. Instead, try to use Action Bar for the same.
Hope this answers your question.
how do I know when it is needed? meaning phones that don't have the settings button
Call hasPermanentMenuKey() on a ViewConfiguration.
also how do i create a context menu that is customized and attached to the 3 dot button
By programming. Since you are not using an action bar, it is impossible to give you specific advice that would be relevant.
Google says Actionbar overflow only appears on phones that have no menu hardware keys. Phones with menu keys display the action overflow when the user presses the key.
If you still want to implement this you may follow this solution.
Click here for your reference.
Just copy this method in your activity and call the method from onCreate method
private void getOverflowMenu() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
I am currently developing an app and I would like to have a little more control over it then usual without having to root the device.
I would like to remove the capability of the recent apps button in the navigation bar, or at least make it do something else from the default actions. Is there a way to do this? I'm sure there is since SureLock does the same thing.
Thanks
I have found a workaround for this on this website:http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/
you need to add this permission: android.permission.REORDER_TASKS
And add this code:
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if( !hasFocus)
{
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME );
sendBroadcast( new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) );
}
}
It is not possible to override the recent apps button.
There is no KeyEvent like there is for the Back Button, and as such this feature is not available.
See documentation here: http://developer.android.com/reference/android/view/KeyEvent.html
You may not be able to disable a button, but you can disable the app that is associated with it. I don't know how it is done, but I have seen kiosk app (for non-rooted devices) that disallow other apps from loading.