I'm developing an Android application that might be used at night. Therefor, I need to turn off the buttons' backlight. How can I do this? On my own phone the backlight turns off after a while, but on the Motorola Droid I don't think this happens.
I'm using a wakelock to keep the screen on. Should I use another flag or how can I do this?
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, WAKE_LOCK_TAG);
mWakeLock.acquire();
Thank you very much!
//Kaloer
There is a hack:
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);
}
I see that this is an old question that was mostly answered in a comment link, but to make it clear to anyone else who comes across this question, here's my own answer.
It's built-in since API 8. (doc)
float android.view.WindowManager.LayoutParams.buttonBrightness
This is a somewhat modified/simplified version of what I'm using in one of my apps (excluding irrelevant code). The inner class is required to prevent a crash at launch on older platforms that don't support it.
private void nightMode() {
Window win = getWindow();
LayoutParams lp = win.getAttributes();
if (prefs.getBoolean("Night", false))
changeBtnBacklight(lp, LayoutParams.BRIGHTNESS_OVERRIDE_OFF);
else changeBtnBacklight(lp, LayoutParams.BRIGHTNESS_OVERRIDE_NONE);
win.setAttributes(lp);
}
private void changeBtnBacklight(LayoutParams lp, float value) {
if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
try {
new BtnBrightness(lp, value);
} catch (Exception e) {
Log.w(TAG, "Error changing button brightness");
e.printStackTrace();
}
}
}
private static class BtnBrightness {
BtnBrightness(LayoutParams lp, float v) {
lp.buttonBrightness = v;
}
}
AFAIK, there is no API to control the backlight of the buttons -- sorry!
Related
I am trying to turn on hardware acceleration for my application
but I never seem to get a 'true' result from this function.
I tried all the methods in the Android Developers blog post about the
the tag android:hardwareAccelerated=true to the application
and even called
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
You should always call isHardwareAccelearted() after the view is attached to the window. I am not sure about your case as I can't see where actually you are calling it.
Also, the support level of various operations across API levels are mentioned here. I hope this helps.
You can also try this method to verify hardwareAcceleration.
public static boolean hasHardwareAcceleration(Activity activity) {
// Has HW acceleration been enabled manually in the current window?
Window window = activity.getWindow();
if (window != null) {
if ((window.getAttributes().flags
& WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
return true;
}
}
// Has HW acceleration been enabled in the manifest?
try {
ActivityInfo info = activity.getPackageManager().getActivityInfo(
activity.getComponentName(), 0);
if ((info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
return true;
}
} catch (PackageManager.NameNotFoundException e) {
Log.e("Chrome", "getActivityInfo(self) should not fail");
}
return false;
}
For checking for View try this.
chat_wv.post(new Runnable() {
#Override
public void run() {
Log.e("isHardwareAccelerated", ""+chat_wv.isHardwareAccelerated());
}
});
I am trying billow Code from this answer to check if the permission is enabled. but it is returning false even when the permission is enabled from the settings.
public static boolean canDrawOverlayViews(Context con){
if(Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP){return true;}
try {
return Settings.canDrawOverlays(con);
}
catch(NoSuchMethodError e){
return canDrawOverlaysUsingReflection(con);
}
}
public static boolean canDrawOverlaysUsingReflection(Context context) {
try {
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
Class clazz = AppOpsManager.class;
Method dispatchMethod = clazz.getMethod("checkOp", new Class[] { int.class, int.class, String.class });
//AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
int mode = (Integer) dispatchMethod.invoke(manager, new Object[] { 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName() });
return AppOpsManager.MODE_ALLOWED == mode;
} catch (Exception e) { return false; }
}
Recently I've also faced the same issue and got the following workaround .
Referenced from
https://code.google.com/p/android/issues/detail?id=198671#c7
public boolean getWindoOverLayAddedOrNot2() {
String sClassName = "android.provider.Settings";
try {
Class classToInvestigate = Class.forName(sClassName);
if (context == null)
context = activity;
Method method = classToInvestigate.getDeclaredMethod("isCallingPackageAllowedToDrawOverlays", Context.class, int.class, String.class, boolean.class);
Object value = method.invoke(null, context, Process.myUid(), context.getPackageName(), false);
Log.i("Tag", value.toString());
// Dynamically do stuff with this class
// List constructors, fields, methods, etc.
} catch (ClassNotFoundException e) {
// Class not found!
} catch (Exception e) {
// Unknown exception
e.printStackTrace();
}
return false;
}
does the check involves the device admin?
I have encountered this problem when disabling device admin, I have checked this permission in the DeviceAdminReceiver->onDisabled() and on some devices, and canDrawOverlays returned false, despite the fact i had the permission.
The above answer helped sometimes but not all the time. the thing that did work is Thread.sleep before the check.
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// some exception here
}
The minimal time that worked for me was 20 millis. than canDrawOverlays returned true
Note: this is not a good practice however this is the only thing that worked for me
Based on BennyP's answer, I've made a Runnable run the required code after 500ms and that worked very well. The feedback is a bit delayed, but the user won't even notice the delay.
This is the code I've added to my onResume()
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(!Settings.canDrawOverlays(ControllerActivity.this)){
//Handle overlay permission not given here
}
else{
//Handle overlay permission given here
}
}
}, 500);
Hope it helps!
I tried restarting the activity after the user accessed the setting . This is code :
public static void restartActivity(Activity act){
Intent intent = getIntent();
finish();
startActivity(intent);
}
First of all, I am really very surprised with this strange behaviour of
Settings.canDrawOverlays(this);
I also faced the same issue with its usage, it was returning false even if the permission is already assigned.
What I noticed that, I was using this check in my onStart() method, where it was creating this wired behavior. To resolve this, I searched over internet and no result was there that can satisfy me and the one I can use.
Solution
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.e("Overlay Permission", "" + Settings.canDrawOverlays(this));
if (!Settings.canDrawOverlays(this)) {
MyPreferences.saveBoolean(HomeScreen.this, "showOverlayPermissionDialog", true);
} else {
MyPreferences.saveBoolean(HomeScreen.this, "showOverlayPermissionDialog", false);
}
}
I did something lake this, in my onCreate(). Here I saved the values accordingly in my SharedPreferences, and according to these Shared Preference values, I created a check for showing an overlay dialog in my onStart(). This worked fine!
You can try this solution, and mark this answer useful if your problem is solved.
Thanks
today i create a app in map , but it crash when battery saver is on .
How to check event when battery saver in on, for every device, help me. Thanks
i try this, but not working in API <21:
PowerManager powerManager = (PowerManager)
this.getSystemService(Context.POWER_SERVICE);
if ( powerManager.isPowerSaveMode()) {
// Animations are disabled in power save mode, so just show a toast instead.
Toast.makeText(customer_textReport.this, "Vui lòng tắt chế độ tiết kiệm pin", Toast.LENGTH_SHORT).show();
}
else {
Intent intentvitri = new Intent(customer_textReport.this, CustomerGetLocation.class);
startActivityForResult(intentvitri, 111);
}
Check Google Developer: PowerManager
In the left top, you can change API level.
As you can see, isPowerSaveMode(), is added in API 21(Lollipop).
So it won't work on older devices.
On Mobiles with an Android version below 5.0 (Lollipop) the power_saving mode is different for each manufactor. However if your target version is 5.0 and higher you can use the PowerManager as descripted in Android Developer
Hmm.This is check high acurary mode in GPS. This is check:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
if (getLocationMode(getApplicationContext()) != 3) {
tvmessage.setText("Please turn on GPS high Acurary");
btcancel_Dialog.setText("OK");
btcancel_Dialog.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
dlg.dismiss();
}
});
dlg.show();
} else {
Intent intentvitri = new Intent(customer_textReport.this, CustomerGetLocation.class);
startActivityForResult(intentvitri, 111);
}
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
}
and method getLocationMode return mode of GPS:
private int getLocationMode(Context context) throws Settings.SettingNotFoundException {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
}
I ended up with this function.
Note: It's not equal to isPowerSaveMode(). It's more like isRunningOutOfPower() or couldBePowerSaveMode()
It checks if the SDK >= 21 then isPowerSaveMode function is available. if not, then check if the GPS mode is not HIGH_ACCURACY and battery level is less than 15% then it "could be" powerSaveMode.
public static boolean couldBePowerSaveMode(Context context) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (powerManager != null) {
return powerManager.isPowerSaveMode();
}
}
if (getLocationMode(context) != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
return getBatteryPercentage(context) <= 15;
}
return getBatteryPercentage(context) <= 15;
}
Try this (ready for copy/paste):
/**
* Checks if device is in power save mode. For older versions that do not support this API, returns false.
* #return true if it is, false otherwise.
*/
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static boolean isPowerSaveMode(Context context)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return powerManager.isPowerSaveMode();
}
// For older versions, we just say that device is not in power save mode
return false;
}
i would like to use following code to turn off Button back that i got from https://stackoverflow.com/a/4937448/1218762
final Window win = getWindow();
final WindowManager.LayoutParams winParams = win.getAttributes();
winParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//set screen brightness to the lowest possible
winParams.screenBrightness = 0.01f;
if (Build.VERSION.SDK_INT < 8) {
// hack for pre-froyo to set buttonBrightness off
try {
Field buttonBrightness = winParams.getClass().getField(
"buttonBrightness");
buttonBrightness.set(winParams, 0);
} catch (Exception e) {
e.printStackTrace();
}
} else {
winParams.buttonBrightness = 0;
}
win.setAttributes(winParams);
Reference : visit Night Mode where you you can turn off Button Lights in Service , i know Services don't have Window but how is it possible ?
Thank You.
One of the simple way I would suggest you is to broadcast some kind of turning-off message from your Service to your Activity and perform the required actions inside onReceive method of BroadcastReceiver.
I'm simply trying to toggle auto brightness on and off.
I started with this code (inside the onCreate method)
final ToggleButton autoBrightToggle = (ToggleButton) findViewById(R.id.brightToggle);
// display auto brightness state
final ToggleButton autoBrightToggle = (ToggleButton) findViewById(R.id.autoToggle);
autoOnOrOff.setText(String.valueOf(getAutoBrightnessMode()));
autoBrightToggle.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (autoBrightToggle.isChecked()) {
setAutoBright(true);
} else {
setAutoBright(false);
}
}
}); // end anonymous OnClickListener function
// toggle the brightness mode
private void setAutoBright(boolean mode) {
if (mode) {
Settings.System.putInt(cr, SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
autoOnOrOff.setText(String.valueOf(getAutoBrightnessMode()));
} else {
Settings.System.putInt(cr, SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_MANUAL);
autoOnOrOff.setText(String.valueOf(getAutoBrightnessMode()));
}
}
Which doesn't seem to work. The setAutoBrightnessMode() method is also called again in onResume() but with the same non-results.
Anyway, I'm sorry if someone feels this question is redundant but the other posts did not get me where I need to go!
(FWIW - I'm testing this on my old Droid X and my Galaxy Nexus, not the Emulator)
EDITED - UPDATE ON THIS:
I'm 99% sure now that I am not seeing any changes to the Auto-Brightness mode reflected in the Settings panel and desktop widgets - even though I may actually be changing it's value.
part of the problem is that I don't know how exactly to determine if Auto-Brightness is on or not!
For instance, does the screen quickly and visibly change? I've been expecting immediate visible changes in brightness according to environment - but perhaps the changes are subtle? and over a longer period? or perhaps it takes 30 seconds or more of environment change before brightness changes?
Can someone suggest how I can track this? I've tried querying the Settings.System.SCREEN_BRIGHTNESS_MODE constant - hooking this method up to a textfield:
private int getAutoBrightnessMode() {
try {
int brightnessMode = Settings.System.getInt(cr, SCREEN_BRIGHTNESS_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
int brightnessMode = -10000;
}
return brightnessMode;
}
But it always reads 0, even after an onResume(). :-((
I know this is a simple procedure, but I'm trying to learn this stuff on my own, and have had almost no formal CS training... So all I can say is I'm very frustrated by this and feel like I've worked myself into a corner and at this point I'm so annoyed I can't think straight anymore.
So help would be great.
I use following approach in my application. Tested on HTC Desire HD and pair of noname chinese tablets.
Add to manifest permission:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
And use below code to toggle auto brightness. There is one trick in the code: we need to "refresh" brightness of app manually, because it doesn't changes automatically. May be it is the problem in your case.
void setAutoBrightness(boolean value) {
if (value) {
Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
} else {
Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_MANUAL);
}
// After brightness change we need to "refresh" current app brightness
if (isChecked) {
refreshBrightness(-1);
} else {
refreshBrightness(getBrightnessLevel());
}
}
private void refreshBrightness(float brightness) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
if (brightness < 0) {
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
} else {
lp.screenBrightness = brightness;
}
getWindow().setAttributes(lp);
}
int getBrightnessLevel() {
try {
int value = Settings.System.getInt(getContentResolver(), SCREEN_BRIGHTNESS);
// convert brightness level to range 0..1
value = value / 255;
return value;
} catch (SettingNotFoundException e) {
return 0;
}
}