Brightness goes normal after changing activity - android

I was trying to switch between 'full brightness' and 'phones normal brightness' by using a switch button in my main activity.
I successfully handled the switching of brightness by using this code:
switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean bChecked) {
if (bChecked) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1.0f;
getWindow().setAttributes(params);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
getWindow().setAttributes(params);
}
}
});
if (switchButton.isChecked()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1.0f;
getWindow().setAttributes(params);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
getWindow().setAttributes(params);
}
The problem is,
after switching to 'full Brightness', when I change the activity, the brightness goes normal.
Now, How can I keep track of the 'brightness setting' from 'main activity' and apply it to the other activities of the app?
N.B. I don't want to change system brightness. Brightness will only change while using the app.
Thanks In Advance.

ok.
Finally solved my problem.
I have created a class having the logic of brightness controlling using SharedPreferences to Handle the state.
code:
if (br.getString("set", "").equals("1")) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1.0f;
getWindow().setAttributes(params);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
getWindow().setAttributes(params);
}
Then extend the class with the activities and initialize SharedPreferences in onCreate method.
br = getSharedPreferences("br", Activity.MODE_PRIVATE);
Thank you #0X0nosugar for the idea.

You need to hold a SCREEN_BRIGHT_WAKE_LOCK if you want it to have an effect beyond your activity. The method you are using above applies to the foreground window, and when you activity goes away that no longer applies.
Note Android generally frowns on use of wake locks because it's easy to screw up and not release them, wasting the devices battery. They recommend the window param version for the vary reason that it automatically releases when the user leaves the activity.

Related

Full screen TYPE_ACCESSIBILITY_OVERLAY

I'm new to the accessibility stuff on Android. While going through the classes and documentation I came across TYPE_ACCESSIBILITY_OVERLAY inside the WindowManager class.
The documentation says (only the relevant text)
For example, if there is a full screen accessibility overlay that is
touchable, the windows below it will be introspectable by an
accessibility service even though they are covered by a touchable
window.
So I set out to achieve just that, a full screen accessibility overlay and try to introspect the windows below it
Extended AccessibilityService and added my full screen overlay when onServiceConnected is called (the inspiration for adding overlay came from here)
#Override
protected void onServiceConnected() {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
FrameLayout mLayout = new FrameLayout(this);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
lp.format = PixelFormat.TRANSLUCENT;
lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.MATCH_PARENT;
lp.gravity = Gravity.TOP;
wm.addView(mLayout, lp);
mLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Here I'm getting the touch events on the overlay I added
return false;
}
});
}
Now, the question is, how do I introspect or find the windows below this overlay? Even in the onAccessibilityEvent callback I get just this overlay window. getWindows() always has a size of 1. Doesn't it refute the assertion made above for TYPE_ACCESSIBILITY_OVERLAY?
Relevant info: To receive the touch events on the overlay I have disabled touchExplorationMode in the service settings
android:canRequestTouchExplorationMode="false"
What you seem to be missing is flagRetrieveInteractiveWindows on your configuration. These properties and window layout paremeters configuration should work, without requiring for you to disable canRequestTouchExplorationMode in order to get the events and having getWindows return the AccessibilityWindowInfo instances underneath yours:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:packageNames="test.demo.com.tests"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagRetrieveInteractiveWindows|flagReportViewIds|flagIncludeNotImportantViews"
android:accessibilityFeedbackType="feedbackAllMask"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
And on service connected:
#Override
protected void onServiceConnected() {
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
FrameLayout layout = new FrameLayout(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS|
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;
windowManager.addView(layout, params);
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//You can either get the information here or on onAccessibilityEvent
return false;
}
});
}
EDIT:
Added FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS to accomplish full screen and removed canRequestTouchExplorationMode since the flag associated to this property should not be included and, therefore, of no use.

android Programmatically set screen brightness and keep it

I'm trying to set the screen brightness from my app, but as soon the screen rotates (Auto-Rotate) my brightness is reset to the systems default brightness.
The code I'm using is following:
final WindowManager.LayoutParams lp = ((Activity) context).getWindow().getAttributes();
lp.screenBrightness = 0.5f;
((Activity) context).getWindow().setAttributes(lp);
((Activity) context).startActivity(new Intent(context, DummyActivity.class));
This is happening because your activity is restarting.
You can try adding your window settings code in onCreate of your activity.
Make sure that this code is added before setting the view of the activity.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 0.5f;
getWindow().setAttributes(lp);
setContentView(R.layout.your_layout_id);
}

android lock SYSTEM orientation to landscape (not just my application)

i want to give the user the option to set the phone's orientation to auto, portrait or landscape.which means for the ENTIRE PHONE's orientation not just my application. every other app must have the landscape orientation too. it was pretty simple to do the first two like this
portrait:
Settings.System.putInt( this.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0);
auto:
Settings.System.putInt( this.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 1);
but i can't find a way to set it to landscape. i want to set all apps to landscape not just mine. i see here that it can be done but it doesn't give much information. How to make Android system force LANDSCAPE for all apk?. anyone willing to explain or provide code snippet?
Code below can force your screen to landscape mode. It is similar to set it to other mode.
public class MyService extends Service {
private boolean mViewAdded = false;
private WindowManager.LayoutParams mLayoutParams;
private View mOverlayView;
private WindowManager mWindowManager;
// Call this some where in your code
private void setLandscapeOrientation() {
mWindowManager = ((WindowManager)getSystemService("window"));
mOverlayView = new View(this);
mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
mLayoutParams.width = 0;
mLayoutParams.height = 0;
mLayoutParams.flags = mLayoutParams.flags |
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
mLayoutParams.flags = mLayoutParams.flags &
~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON &
~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
mLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
if (mViewAdded) {
mWindowManager.updateViewLayout(mOverlayView, mLayoutParams);
} else {
mWindowManager.addView(mOverlayView, mLayoutParams);
mViewAdded = true;
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mViewAdded) {
mWindowManager.removeView(mOverlayView);
mViewAdded = false;
}
}
}
In your AndroidManifest.xml, for each activity put
android:screenOrientation="landscape"
It forces the activity to landscape

Can't apply system screen brightness programmatically in Android

I'm using the following to set the system auto brightness mode and level:
android.provider.Settings.System.putInt(y.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS_MODE, 0);
android.provider.Settings.System.putInt(y.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, y.brightness1);
I can change auto-brighess on and off, and set different levels. The settings seem to be applied properly -- I can go to into Settings --> Display --> Brightness, and whanever setting I set is actually shown correctly. However, the actual screen isn't changing its brightness. If i just tap on the slider in Display Settings, then everything gets applied.
I shoudl mention that I'm running an app withat a main activity, and these settings are getting applied in the BroadcastReceiver. I did try to create a dummy activity and tested the stuff there, but got the same results.
OK, found the answer here:
Refreshing the display from a widget?
Basically, have to make a transparent activity that processes the brightness change. What's not mentioned in the post is that you have to do:
Settings.System.putInt(y.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS_MODE, 0);
Settings.System.putInt(y.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, brightnessLevel);
then do
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = brightness;
getWindow().setAttributes(lp);
And if you call finish() right after applying the changes, brightness will never actually change because the layout has to be created before the brightness settings is applied. So I ended up creating a thread that had a 300ms delay, then called finish().
I'm doing something similar with screen brightness in one of my apps, and I'm doing it through the WindowManager and it works. I'm using the following code to get the current screen brightness (and save it for later) and set it to full:
WindowManager.LayoutParams lp = getWindow().getAttributes();
previousScreenBrightness = lp.screenBrightness;
float brightness = 1;
lp.screenBrightness = brightness;
getWindow().setAttributes(lp);
Use the answer given by "user496854" above
If you are taking max screenBrightness =255 then while doing
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = brightness; getWindow().setAttributes(lp);
divide screenBrightness by 255 like
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = brightness/(float)255;
getWindow().setAttributes(lp);
I created a static method in my Application class which I invoke from all my Activity.onResume() methods.
MyApplication extends Application {
...
public static void setBrightness(final Activity context) {
// get the content resolver
final ContentResolver cResolver = context.getContentResolver();
// get the current window
final Window window = context.getWindow();
try {
// get the current system brightness
int brightnessLevel = System.getInt(cResolver,System.SCREEN_BRIGHTNESS);
// get the current window attributes
LayoutParams layoutpars = window.getAttributes();
// set the brightness of this window
layoutpars.screenBrightness = brightnessLevel / (float) 255;
// apply attribute changes to this window
window.setAttributes(layoutpars);
} catch (SettingNotFoundException e) {
// throw an error cuz System.SCREEN_BRIGHTNESS couldn't be retrieved
Log.e("Error", "Cannot access system brightness");
e.printStackTrace();
}
}
}
MyActivity extends Activity {
...
public void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
MyApplication.setBrightness(this);
}
}

Brightness Screen Filter

Does anyone have an idea how to implement an Brightness Screen Filter like the one here:
http://www.appbrain.com/app/screen-filter/com.haxor
I need a starting point and I can't figure out how to do it.
Just make a transparent full screen activity that lets touches pass through. To make touches pass through use the following Window flags before setting the contentView:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Window window = getWindow();
// Let touches go through to apps/activities underneath.
window.addFlags(FLAG_NOT_TOUCHABLE);
// Now set up content view
setContentView(R.layout.main);
}
For your main.xml layout file just use a full screen LinearLayout with a transparent background:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/background"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#33000000">
</LinearLayout>
Then to adjust the "brightness" just change the value of the background colour from your code somewhere:
findViewById(R.id.background).setBackgroundColor(0x66000000);
Get an instance of WindowManager.
WindowManager windowManager = (WindowManager) Class.forName("android.view.WindowManagerImpl").getMethod("getDefault", new Class[0]).invoke(null, new Object[0]);
Create a full screen layout xml(layout parameters set to fill_parent)
Set your view as not clickable, not focusable, not long clickable, etc so that touch is passed through to your app and the app can detect it.
view.setFocusable(false);
view.setClickable(false);
view.setKeepScreenOn(false);
view.setLongClickable(false);
view.setFocusableInTouchMode(false);
Create a layout parameter of type android.view.WindowManager.LayoutParams.
LayoutParams layoutParams = new LayoutParams();
Set layout parameter like height, width etc
layoutParams.height = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutParams.FILL_PARENT;
layoutParams.flags = 280; // You can try LayoutParams.FLAG_FULLSCREEN too
layoutParams.format = PixelFormat.TRANSLUCENT; // You can try different formats
layoutParams.windowAnimations = android.R.style.Animation_Toast; // You can use only animations that the system to can access
layoutParams.type = LayoutParams.TYPE_SYSTEM_OVERLAY;
layoutParams.gravity = Gravity.BOTTOM;
layoutParams.x = 0;
layoutParams.y = 0;
layoutParams.verticalWeight = 1.0F;
layoutParams.horizontalWeight = 1.0F;
layoutParams.verticalMargin = 0.0F;
layoutParams.horizontalMargin = 0.0F;
Key step: You can set what percentage of brightness you need.
layoutParams.setBackgroundDrawable(getBackgroundDrawable(i));
private Drawable getBackgroundDrawable(int i) {
int j = 255 - (int) Math.round(255D * Math.exp(4D * ((double) i / 100D) - 4D));
return new ColorDrawable(Color.argb(j, 0, 0, 0));}
Finally add view to windowManager that you created earlier.
windowManager.addView(view, layoutParams);
Note: You need SYSTEM_ALERT_WINDOW permission to lay an overlay on the screen.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Have tested this and it works. Let me know if you get stuck.
Of course you can't use this is production code, but if you are playing around .. try this Undocumented hack
It uses :
private void setBrightness(int brightness) {
try {
IHardwareService hardware = IHardwareService.Stub.asInterface(
ServiceManager.getService("hardware"));
if (hardware != null) {
hardware.setScreenBacklight(brightness);
}
} catch (RemoteException doe) {
}
}
Remember that it uses this permission :
<uses-permission android:name="android.permission.HARDWARE_TEST"/>
You ca try this also:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.max_bright);
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 100 / 100.0f;
getWindow().setAttributes(lp);
}

Categories

Resources