How to always show Android settings button on ActionBar? - android

How can I always show Android settings button on ActionBar? (4.0+)
I would like to show it even if the device has an hardware button for settings, so it would be same with devices with and without hardware buttons.
This is what I'm talking about: http://oi48.tinypic.com/2j104l0.jpg

There is one awful hack which generally have been answered on many questions. Call this from your onCreate():
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();
}
}
It is highly suggested not to use this hack as sHasPermanentMenuKey field can change anytime. However this has been working for me and others uptil now. See
Android action bar not showing overflow
On a second note, the hardware button is present on the phone for a reason. Just showing the addition overflow menu might confuse your users. Ideally a user would be very much accustomed to using his/her personal phone. So, if the user's phone has a hardware button for overflow menu option, then it need not have the icon on the top of action bar. Having an addition button might confuse users due to difference in behavior in different apps.
Hope that helps.
Edit:
In short, its not recommended as sHasPermanentMenuKey field in the Android code can be changed anytime, which will break your app if not found.

Related

menu button doesn't show on nexus 7

so I am facing this problem for long time. I've got Nexus 4 and Nexus 7 both running Android 4.3, and i've got application with targetSdkVersion="11"("I use 11 because any target sdk below 11 doesn't support multitouch for me). And the problem is that 3-dot menu shows on Nexus 4 but doesnt show on Nexus 7. 3 dot menu button on nexus 7 works only if I put targetSdkVersion="8" but then multitouch doesnt work
Nexus 4:
Nexus 7 :
code :
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="11" />
screenshots :
nexus 7
nexus 4:
In case you are specifically wondering why the button is not being shown the following rules apply when Android determines if a legacy menu button is needed:
If target API version is less than 11 it is shown on all devices
If target version is 11, 12, or 13 (i.e. tablet-only Honeycomb) Android assumes that your app has been designed for tablets and won't show a legacy button on tablets, but will on phones
If target is 14 or above (ICS and above), Android assumes your app is designed for tablets and phones and so the legacy button isn't shown.
But like the other answers say, you shouldn't be using this menu button. If you don't want an entire ActionBar, another option would to have a three-dot button in your activity which shows a menu using PopupMenu.
You should not be using that menu anymore. From the Menus documentation:
On Android 3.0 and higher, items from the options menu are presented by the action bar as a combination of on-screen action items and overflow options. Beginning with Android 3.0, the Menu button is deprecated (some devices don't have one), so you should migrate toward using the action bar to provide access to actions and other options.
Use an ActionBar.
The correct solution is to use an ActionBar but there may be some hacks to get the overflow menu to appear.
Specifically, there's a hidden window flag FLAG_NEEDS_MENU_KEY you can access via reflection. Here's a code snippet (from this blog):
public static void addLegacyOverflowButton(Window window) {
if (window.peekDecorView() == null) {
throw new RuntimeException("Must call addLegacyOverflowButton() after setContentView()");
}
try {
window.addFlags(WindowManager.LayoutParams.class.getField("FLAG_NEEDS_MENU_KEY").getInt(null));
}
catch (NoSuchFieldException e) {
// Ignore since this field won't exist in most versions of Android
}
catch (IllegalAccessException e) {
Log.w(TAG, "Could not access FLAG_NEEDS_MENU_KEY in addLegacyOverflowButton()", e);
}
}
I tested this on a couple of Nexus devices and it works. Comments on the blog state that there are devices where it doesn't work. Use with caution. And use an ActionBar, really.
There's a simple way to force a menu option to stay in the menu overflow. If you're creating a menu with XML, you can force this using the "showAsAction" attribute.
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_option"
android:showAsAction="never"
android:title="#string/option_name" />
</menu>
If you set "showAsAction" to "never", it will be forced to don't show on the ActionBar, so the option will remain on the menu overflow.
There's more info (like how to vinculate the XML menu file to an Activity) on the official Android documentation webpage: http://developer.android.com/guide/topics/resources/menu-resource.html
I wish this can be helpful!
I wouldnt always recommend using this, since its a hack which breaks the consistency of the phone, but if you want the "3 dots" menu, which is called the overflow menu you need to add this method
//Hack to display overflowMenu on devices with a menu button
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();
}
}
And in your onCreate() call this method.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.Activity);
getOverflowMenu();
}

setting button in android application

I develop an android application and put it in a android market. users put comments for me and tell me that setting button doesn't work for my application. I don't know what setting button is and how I can enable it for my application.
can any one help me?
I guess what you mean is the menu button. The problem often is that some devices don't have a physical menu button, thus they cannot access the menu of your app.
Try to use a Holo theme for your app's activities and show an ActionBar. By default, the three dots button for your menu will then be shown in the ActionBar on devices that don't have a physical menu button.
For a consistend UI on all devices, you could show the menu button in your ActionBar permanently, whether the device has a physical menu button or not, using this code:
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
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(); }
}
Do you use Eclipse?
Check if you have a method onCreateOptionsMenu in your activity class.
Eclipse creates automatically this method and adds a menu in your activity (depending on how you create the activity class file)

Transparent notification bar with live wallpaper on Galaxy S4

Full Edit since it apparently wasn't clear that this is indeed a programming question
On the Galaxy S4, the notification bar is transparent by default. When using the built-in "Bubbles" wallpaper this looks as follows for example:
Now I have developed my own live wallpaper. For sake of simplicity, I just fill the available canvas with 0xFFFF0000 for the screenshots, but normally it shows a different scene. On the Galaxy S4, my wallpaper does not show a transparent notification bar, but the default black one:
I noticed that sometimes my wallpaper shows a transparent bar also, here on the lockscreen. However, I was unable to reliably reproduce the behaviour.
My question is simply: is there any way to reliably enable the transparent notification bar from my wallpaper code or manifest? Actually, the unpredictable switching between transparent and black bar makes the user experience much worse than just with an always-black bar.
This is indeed possible on an unrooted S4:
public static boolean setTransparentNotificationBarTouchWiz(View view) {
try {
Field field = View.class.getDeclaredField("SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND");
Class<?> t = field.getType();
if (t == int.class) {
int value = field.getInt(null);
view.setSystemUiVisibility(value);
return true;
}
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
}
return false;
}
My thanks to Kevin # TeslaCoil for sharing this flag with me.
Sorry, unless you are making a custom ROM this isn't possible, unless you only want the status bar changed for your app.
This would require a heck of a lot of work.
First you will need to add Theme.NoTitleBar.Fullscreen to your manifest
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
>
Then once you have done that you need to create a standard layout which represents the status bar, this would mean that you have to add the time, and also receive all the notifications from other apps, I do not personally know how to do that but I'm sure there is a way.
If you really want to do this goodluck, you have a hard time ahead of you.

Is there a way to programmatically control the back-light for the android back button?

I'm currently making an android app and testing it on a Samsung GT-S5830.
The problem I'm having is that the back button back-light is always off when the app is running (so it's not visible), which seems to confuse the users who I have asked to test the app.
The question is whether there is a way to programmatically ensure that the back-light for the back button is always on?
I'm dubious about it, as the problem seems to be phone model dependent.
Thanks.
there is already a stackoverflow answer but I will post again:
private void setDimButtons(boolean dimButtons) {
Window window = getWindow();
LayoutParams layoutParams = window.getAttributes();
float val = dimButtons ? 0 : -1;
try {
Field buttonBrightness = layoutParams.getClass().getField(
"buttonBrightness");
buttonBrightness.set(layoutParams, val);
} catch (Exception e) {
e.printStackTrace();
}
window.setAttributes(layoutParams);
}
Or try to find something in here (the new design is horrible ...) http://developer.android.com/reference/android/os/PowerManager.html

How to check if the native/hardware keyboard is used?

I want to check if the native/hardware keyboard is used, and also if possible I want to disable the third party keyboards.
My goal is simple I use just the native android soft keyboard for entering values in my edit boxes and no other keyboard should be able to this
Thanks
EDIT
I know it is not good idea to do what I am trying to do, I know that the basic idea of android is to have intents and activities and services who know to handle some types of intent according intent-filter. But this in every rule there is an exception, especially when we talk about security.
I want to disable all third party keyboards, and if this is not possible to do it with some API or something... is there any workaround to this problem ?
EDIT
String s=Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
This returns the currently enabled input method (keyboard),but I need something like the 'system keyboard' and I do not see any flag like that :-(.
List<InputMethodInfo> list = m.getInputMethodList();
One possible solution is to take the list[0] as the keyboard I am searching, but I do not want to relay on the order (except if the order is garanteed that always the keyboard with index 0 is the one that comes install with the phone)
this is the value of list
[InputMethodInfo{com.htc.android.htcime/.HTCIMEService, settings: com.htc.android.htcime.HTCIMESettings}, InputMethodInfo{com.volosyukivan/.WiFiInputMethod, settings: null}]
I want to check if the native/hardware keyboard is used
You can use the Configuration object to see if the device's hardware keyboard is hidden. Usually, that would imply they are using that keyboard, since most devices do not show an IME when the hardware keyboard is available. However, some devices might support both simultaneously, and I don't know how external keyboards (USB, Bluetooth) interact with this value.
also if possible I want to disable the third party keyboards.
Fortunately, this is not possible.
is there any workaround to this problem ?
There is no problem cited to this point in the question.
yes the will not be happy, but they will be much more unhappy if you let their secure data to be corrupt
If users choose to use an alternative keyboard, that is their choice as users. The user is perfectly capable of switching keyboards if they wish. The user is perfectly capable of making these decisions. It is entirely possible that an alternative keyboard is more secure than a built-in one, due to devices loaded with spyware from the factor, such as CarrierIQ. Hence, your assumption that you are improving security by attacking the user's choice of keyboard is fundamentally flawed.
Of course, you do not have to support using any keyboard at all, forcing users to use some sort of on-screen input option that you devise yourself. This is not completely secure either (e.g., tapjacking attacks), and it may cause usability problems for people who chose certain third-party keyboards for specific reasons (e.g., blind users, users with motor control issues).
I am not aware that there is a way to definitively determine what the firmware's own IME is, particularly since this varies by device and firmware.
Something like this should let you check if the user is using a non-standard keyboard. However, instead of preventing them using this keyboard, how about a helpful warning message about the possible security risks?
public boolean isUsingCustomInputMethod() {
InputMethodManager imm = (InputMethodManager) mCtx.getSystemService(
Context.INPUT_METHOD_SERVICE);
List<InputMethodInfo> mInputMethodProperties = imm.getEnabledInputMethodList();
final int N = mInputMethodProperties.size();
for (int i = 0; i < N; i++) {
InputMethodInfo imi = mInputMethodProperties.get(i);
if (imi.getId().equals(
Settings.Secure.getString(mCtx.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD))) {
if ((imi.getServiceInfo().applicationInfo.flags &
ApplicationInfo.FLAG_SYSTEM) == 0) {
return true;
}
}
}
return false;
}
I find precise solution
InputMethodManager m = (InputMethodManager) ctx.getSystemService("input_method");
List<InputMethodInfo> a = m.getInputMethodList();
for (InputMethodInfo inputMethodInfo : a) {
if (inputMethodInfo.getIsDefaultResourceId() == 0) {
//it is not default
return false;
}
}
//it is default
return true;

Categories

Resources