Need help to understand accelerometer code - java

I have read through a lot of code but I do not understand how you can make an image move using the accelerometer sensor, I understand how to register it but I do not understand how to actually make an image or a shape draw move in sync with the accelerometer axis, I am using android java to do this. Please can someone help me as I am really struggling. Thank you for your time and help.

So, here's the code to register a listener (I know you said you've done this already, but it can never hurt):
private void enableAccelerometerListening() {
sensorManager = (SensorManager) getSystemService(COntext.SENSOR_SERVICE);
sensorManager.registerListener(sensorEventListener), sensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
private void disableAccelerometerListening() {
if (sensorManager != null) {
sesnsorManager.unregisterListener(sensorEVentListener, sensorManager.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER));
sensorManager = null;
}}
You will need a couple fields just below your class declaration:
private SesnsorManager sensorManager;
private float acceleration;
private float currentAcceleration;
private float lastAcceleration;
private static final int ACCELERATION_THRESHOLD = 15000;
Here is the event handler, which gets very close to what you need help with:
private SensorEventListener sensorEventListener = new SensorEventListener() {
public void onSesnsorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
lastAcceleration = currentAcceleration; //save previous accel value
currentAcceleration = x*x + y*y + z*z;
acceleration = currentAcceleration * (currentAcceleration - lastAcceleration); // calc the change in acceleration
//if the accel is above a certain threshold:
if (acceleration > ACCELERATION_THRESHOLD) {
//MAKE YOUR CODE HERE THAT RESPONDS TO ACCELERATION EVENTS
//Note, your accel threshold should be determined by trial and error on a number of devices
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy {}
};

Also, I'll try to address some of your animation needs, though I am much more spotty in this area. I imagine that what you need to do is make your image move as the accelerometer detects moves. The image will have to be moved via an animation, rather than the accelerometer directly. So say 'spot' is your image, okay? (the code below both adds a spot and sets up its animations(which are not directly tied to the accelerometer, but I hope this will be helpful nonetheless):
public void addSpot() {
int x = random.nextInt(viewWidth - SPOT_DIAMETER);
int y = random.nextInt(viewHeight = SPOT_DIAMETER);
int x2 = random.nextInt(viewWidth - SPOT_DIAMETER);
int y2 = random.nextInt(viewWidth - SPOT_DIAMETER);
final ImageView spot = (ImageView) layoutFinlater.inflate(R.layout.untouched, null);
spot.setLayoutParams(new RelativeLayout.LayoutParams(SPOT_DIAMETER, SPOT_DIAMETER));
spot.setX(x);
spot.setY(y);
Well right here is where I think you could start doing something with the accelerometer events...
As you saw in my other response above,
if (acceleration > ACCELERATION_THRESHOLD) {
spot.animate().x(x2).y(y2).setDuration(animationTime);
animationTime will just be something in milliseconds that you feel is appropriate, and don't forget to take care of importing the necessary packages.

Related

SensorManager only working on some devices

I have the following code to get the x and y angle of my device and it is working fine on my phone, but not my tablet (Samsung galaxy tab e). I was wondering if anyone had any idea as to what could be causing it to work on one device but not another.
I did also ensure that screen rotation was enabled on both. My assumption is that the tablet is lacking a sensor, and what I'm looking for most is a workaround. Any help would be much appreciated. Thanks in advance!
Source code:
double yAngle;
double xAngle;
#Override
protected void onResume() {
super.onResume();
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),RATE);
}
#Override
public void onSensorChanged(SensorEvent event) {
float[] rotationMatrix;
rotationMatrix = new float[16];
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
determineOrientation(rotationMatrix);
lblY.setText(String.format("%.1f", yAngle));
lblX.setText(String.format("%.1f", xAngle));
}
private void determineOrientation(float[] rotationMatrix){
//CREATING FLOAT ARRAY OF ORIENTATION VALUES
float [] orientationValues = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationValues);
yAngle = Math.toDegrees(orientationValues[2]);
xAngle = Math.toDegrees(orientationValues[1]);
}
You can use adb shell pm list features to check all sensors and other features supported.

Call sensor activity object from another class

I am working on a project in which the content on the screen changes with the direction of mobile's axis. For this, I created a class which calculates azimuthal angle by accessing sensor data. This class also has a method setLine which gives back a,b,c in line equation a.x + b.y + c = 0 when supplied gps co-ordinates. This line is the z-axis of mobile.
So I created an object of this class from another class. But whenever I am accessing setLine, By seeing the log I got to know that azimuthal = NULL and oldAzimuthal = Math.PI/180 which is what I set.
I don't understand this. When I created the ViewAngleActivity object, this should have already initialized sensors and I shouldn't be getting NULL for azimuthal .
Earlier when I used ThisViewAngleActivity as the main class I didn't face such issue. I was properly getting azimthal.
Am I missing some concepts? Please help.
I am uploading the code for ViewAngleActivity
public class ViewAngleActivity extends Activity implements SensorEventListener {
Float azimuth;
Float pitch;
Float roll;
float oldAzimuth;
private SensorManager mSensorManager;
Sensor accelerometer;
Sensor magnetometer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Log.d("gettingViewAngle:","in onCreateSensor got Created");
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
float[] mGravity;
float[] mGeomagnetic;
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
if (SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic)) {
// orientation contains azimut, pitch and roll
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
oldAzimuth = azimuth;
azimuth = orientation[0];
pitch = orientation[1];
roll = orientation[2];
// at this point, orientation contains the azimuth(direction), pitch and roll values.
Log.d("onSensorChanged:", "azimuth = "+ azimuth);
Log.d("onSensorChanged:", "oldAzimuth = "+ oldAzimuth);
}
}
}
/**
* This method calculates line equation of mobile axis
* #param currentLatitude
* #param currentLongitude
* #return co-efficients of the line a.x + b.y + c = 0
*/
public double[] setLine(Double currentLatitude, Double currentLongitude){
double angle = 1;
double a,b,c;
double[] coEfficients = {1, 1, 0};
Log.d("setLine:", "azimuth = "+ azimuth);
Log.d("setLine:", "oldAzimuth = "+ oldAzimuth);
if(azimuth!= null) {
angle = (float) azimuth;
if (angle == 0){
angle = Math.PI/180;
}
if ( angle%((Math.PI)/2) ==0){
a = 0;
b = 1;
c = ( - currentLongitude);
}
else {
a = -(Math.tan((double) angle));
b = 1;
c = (Math.tan((double) angle) * currentLatitude) - currentLongitude;
}
Log.d("setLine:Using azimuth", "azimuth = "+ angle);
coEfficients[0] = a ;
coEfficients[1] = b ;
coEfficients[2] = c ;
}
else{
angle = (float) oldAzimuth;
if (angle == 0){
angle = Math.PI/180;
}
if ( angle%((Math.PI)/2) ==0){
a = 0;
b = 1;
c = ( - currentLongitude);
}
else {
a = -(Math.tan((double) angle));
b = 1;
c = (Math.tan((double) angle) * currentLatitude) - currentLongitude;
}
Log.d("setLine:UsingOldAzimuth", "oldAzimuth = "+ angle);
coEfficients[0] = a ;
coEfficients[1] = b ;
coEfficients[2] = c ;
}
return coEfficients;
}
}
The object I created from other class is as follows
private ViewAngleActivity viewAngleActivity;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewAngleActivity = new ViewAngleActivity();
//other parts of the code//
}
#Override
public void method1{
method2;
}
public void method1{
double[] coEfficients = viewAngleActivity.setLine(currentLatitude,currentLongitude);
}
You're only creating an instance of ViewAngleActivity, it's never really added to the window.
Your onCreate() and onResume() methods never get called, they are only called when your Activity is added to the window and goes through the Activity Lifecycle
Since you're instantiating your mSensorManager instance inside onCreate(), it never gets created and is still null.
Since onResume() isn't called (see second point up there), then your viewAngleActivity instance (which is also your SensorEventListener interface) never gets registered to mSensorManager, and as such the method onSensorChanged(SensorEvent evt) inside your ViewAngleActivity instance never gets called. Since that's where you're setting azimuth it's still going to be NULL cause that method is never called.
You might want to try a different approach, probably move all the code in your ViewAngleActivity's onCreateView() methods to a constructor like so:
//note the context parameter, pass this one when you create your ViewAngleActivity instance
public ViewAngleActivity(Context context){
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Log.d("gettingViewAngle:","in onCreateSensor got Created");
//then you use your context to reg.
mSensorManager.registerListener(context, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(context, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
Please read more about Android's Activity Lifecycle and how they are added on screen. Note that with the above approach, you'd have to handle unregistering your SensorEventListener, cause obviously onPause() would never be called in ViewAngleActivity.
//this is how you'd probably go about it:
viewAngleActivty.mSensorManager.unregisterListener(viewAngleActivity);
Or instead, implement what you're trying to do in the new Activity you're using as your MainActivity, that would be even easier.

Accessing multiple sensors in non-activity classes

I am trying to use multiple sensors like Accelerator,Magnetic Field, Light and so on and for each sensor I wrote an individual class which not an activity , each of them has its SensorEventListener as well. What I want to do is when user chooses one of them I start to show the data on a fragment(on MainActivity) , when user changes the previous sensor should stop and new one should start. However, when I try to stop previous one by unregistering its listener , it doesn't unregister but it registers and works. I want to stop previous listener. What is wrong? Any ideas?
Here is the sensor class;
public class Accelerometer
{
private SensorManager sensorManager;
private Sensor sensor;
public List<ObjAccelerometer> lstData;
ObjAccelerometer currentData;
float lastX,lastY,lastZ;
String currentTime;
int numberOfSamples;
Context context;
public Accelerometer(Context _context,int _numberSample)
{
context=_context;
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
numberOfSamples=_numberSample;
lstData=new ArrayList<>();
}
public void registerUnregister(boolean register)
{
if(register)
sensorManager.registerListener(mSensorListener, sensor, SensorManager.SENSOR_DELAY_FASTEST);
else
sensorManager.unregisterListener(mSensorListener);
}
Calendar time;
private final SensorEventListener mSensorListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
if(numberOfSamples>lstData.size()) {
if (currentData != null) {
lastX = currentData.get_x();
lastY = currentData.get_y();
lastZ = currentData.get_z();
}
currentData = new ObjAccelerometer();
time = Calendar.getInstance();
currentTime = time.get(Calendar.HOUR) + ":" + time.get(Calendar.MINUTE) + ":" + time.get(Calendar.SECOND) + ":" + time.get(Calendar.MILLISECOND);
currentData.set_time(currentTime);
currentData.set_x(event.values[0]);
currentData.set_y(event.values[1]);
currentData.set_z(event.values[2]);
Float speed = Math.abs(event.values[0] + event.values[1] + event.values[2] - lastX - lastY - lastZ);
currentData.set_speed(speed);
lstData.add(currentData);
Util.createToaster(context, "X Y Z Time:" + currentData.toString());
}
else
registerUnregister(false);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
}
Here the code for calling them ;
unRegisterAllSensors();
switch (selectedSensor) {
case Accelerometer:
accelerometer= new Accelerometer(context, DEFAULT_SAMPLE_NUMBER);
accelerometer.registerUnregister(true);
lstAccelerometer = accelerometer.lstData;
break;
case Linear_Accelerometer:
linearAccelerometer= new LinearAccelerometer(context, DEFAULT_SAMPLE_NUMBER);
linearAccelerometer.registerUnregister(true);
break;
....
Here is the unRegisterAllSensors() function code:
if(accelerometer!=null) {
accelerometer.registerUnregister(false);
accelerometer=null;
}
if(linearAccelerometer!=null) {
linearAccelerometer.registerUnregister(false);
linearAccelerometer=null;
}
Sorry about bothering people,it actually works!
I made a few changes including setting SensorManager final parameter and also removing Toast message and add A toaster only for register and unregister of each listener. It worked! I believe the problem was caused by two things;
1-Toasting the message is slower process than sensing because of that even though I unregistered messages were still on the screen for a while.
2- when I didn't define SensorManager final , every time I was getting a new instance of it so size of the listener list was 0.
Still, this can be a good sample for people who want to call sensors from non-activity classes.
Thanks!

How to rotate image in imageview on button click each time?

This is java code.I am getting image from image gallery.I have one Button and one ImageView. It is rotating only one time.When I again click button it is not rotating image.
public class EditActivity extends ActionBarActivity
{
private Button rotate;
private ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
rotate=(Button)findViewById(R.id.btn_rotate1);
imageView = (ImageView) findViewById(R.id.selectedImage);
String path = getIntent().getExtras().getString("path");
final Bitmap bitmap = BitmapFactory.decodeFile(path);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 510, 500,
false));
rotate.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
imageView.setRotation(90);
}
});
}
Change your onClick() method to
#Override
public void onClick(View v)
{
imageView.setRotation(imageView.getRotation() + 90);
}
Notice, what the docs say
Sets the degrees that the view is rotated around the pivot point. Increasing values result in clockwise rotation.
I'd like to update my answer to show how to use RotateAnimation to achieve the same effect in case you're also targeting Android devices running Gingerbread (v10) or below.
private int mCurrRotation = 0; // takes the place of getRotation()
Introduce an instance field to track the rotation degrees as above and use it as:
mCurrRotation %= 360;
float fromRotation = mCurrRotation;
float toRotation = mCurrRotation += 90;
final RotateAnimation rotateAnim = new RotateAnimation(
fromRotation, toRotation, imageview.getWidth()/2, imageView.getHeight()/2);
rotateAnim.setDuration(1000); // Use 0 ms to rotate instantly
rotateAnim.setFillAfter(true); // Must be true or the animation will reset
imageView.startAnimation(rotateAnim);
Usually one can setup such View animations through XML as well. But, since you have to specify absolute degree values in there, successive rotations will repeat themselves instead of building upon the previous one to complete a full circle. Hence, I chose to show how to do it in code above.

Change the System Brightness Programmatically

I want to change the system brightness programmatically. For that purpose I am using this code:
WindowManager.LayoutParams lp = window.getAttributes();
lp.screenBrightness = (255);
window.setAttributes(lp);
because I heard that max value is 255.
but it does nothing. Please suggest any thing that can change the brightness.
Thanks
You can use following:
// Variable to store brightness value
private int brightness;
// Content resolver used as a handle to the system's settings
private ContentResolver cResolver;
// Window object, that will store a reference to the current window
private Window window;
In your onCreate write:
// Get the content resolver
cResolver = getContentResolver();
// Get the current window
window = getWindow();
try {
// To handle the auto
Settings.System.putInt(
cResolver,
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
);
// Get the current system brightness
brightness = Settings.System.getInt(
cResolver, Settings.System.SCREEN_BRIGHTNESS
);
} catch (SettingNotFoundException e) {
// Throw an error case it couldn't be retrieved
Log.e("Error", "Cannot access system brightness");
e.printStackTrace();
}
Write the code to monitor the change in brightness.
then you can set the updated brightness as follows:
// Set the system brightness using the brightness variable value
Settings.System.putInt(
cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness
);
// Get the current window attributes
LayoutParams layoutpars = window.getAttributes();
// Set the brightness of this window
layoutpars.screenBrightness = brightness / 255f;
// Apply attribute changes to this window
window.setAttributes(layoutpars);
Permission in manifest:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
For API >= 23, you need to request the permission through Settings Activity, described here:
Can't get WRITE_SETTINGS permission
You can set the screenBrightness attribute of the window, like so:
WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);
This code/technique is adapted from a blog entry by Almond Joseph Mendoza on January 5, 2009, entitled "Changing the Screen Brightness Programatically" (archived on the Wayback Machine).
The screenBrightness attribute is a floating-point value ranging from 0 to 1, where 0.0 is 0% brightness, 0.5 is 50% brightness, and 1.0 is 100% brightness.
Note that this doesn't affect the brightness for the entire system, only for that particular window. However, in most cases, for most applications, this is probably all you need. In particular, it has the advantage of not requiring elevated permissions, which would be required to change a global system setting.
I had the same problem.
Two solutions:
here, brightness =(int) 0 to 100 range as i am using progressbar
1 SOLUTION
float brightness = brightness / (float)255;
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = brightness;
getWindow().setAttributes(lp);
2 SOLUTION
I just used dummy activity to call when my progress bar stop seeking.
Intent intent = new Intent(getBaseContext(), DummyBrightnessActivity.class);
Log.d("brightend", String.valueOf(brightness / (float)255));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this is important
//in the next line 'brightness' should be a float number between 0.0 and 1.0
intent.putExtra("brightness value", brightness / (float)255);
getApplication().startActivity(intent);
Now coming to the DummyBrightnessActivity.class
public class DummyBrightnessActivity extends Activity{
private static final int DELAYED_MESSAGE = 1;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == DELAYED_MESSAGE) {
DummyBrightnessActivity.this.finish();
}
super.handleMessage(msg);
}
};
Intent brightnessIntent = this.getIntent();
float brightness = brightnessIntent.getFloatExtra("brightness value", 0);
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = brightness;
getWindow().setAttributes(lp);
Message message = handler.obtainMessage(DELAYED_MESSAGE);
//this next line is very important, you need to finish your activity with slight delay
handler.sendMessageDelayed(message,200);
}
}
don't forget to register DummyBrightnessActivity to manifest.
hope it helps!!
In my case, I only want to light up the screen when I display a Fragment and not change the system wide settings. There is a way to only change the brightness for your Application/Activity/Fragment. I use a LifecycleObserver to adjust the screen brightness for one Fragment:
class ScreenBrightnessLifecycleObserver(private val activity: WeakReference<Activity?>) :
LifecycleObserver {
private var defaultScreenBrightness = 0.5f
init {
activity.get()?.let {
defaultScreenBrightness = it.window.attributes.screenBrightness
}
}
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun lightUp() {
adjustScreenBrightness(1f)
}
#OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun lightDown() {
adjustScreenBrightness(defaultScreenBrightness)
}
private fun adjustScreenBrightness(brightness: Float) {
activity.get()?.let {
val attr = it.window.attributes
attr.screenBrightness = brightness
it.window.attributes = attr
}
}
}
And add the LifecycleObserver such as this in your Fragment:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// ...
lifecycle.addObserver(ScreenBrightnessLifecycleObserver(WeakReference(activity)))
// ...
return binding.root
}
I tried several solutions that others posted and none of them worked exactly right. The answer from geet is basically correct but has some syntactic errors. I created and used the following function in my application and it worked great. Note this specifically changes the system brightness as asked in the original question.
public void setBrightness(int brightness){
//constrain the value of brightness
if(brightness < 0)
brightness = 0;
else if(brightness > 255)
brightness = 255;
ContentResolver cResolver = this.getApplicationContext().getContentResolver();
Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
}
Complete Answer
I did not wanted to use Window Manager to set brightness. I wanted the brighness to reflect on System level as well as on UI. None of the above answer worked for me. Finally this approach worked for me.
Add Write setting permission in Android Manifest
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions"/>
Write Settings is a Protected settings so request user to allow Writing System settings:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.System.canWrite(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
}
Now you can set Brightness easily
ContentResolver cResolver = getContentResolver();
Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
brighness value should be in range of 0-255 so if you have aslider with range (0-max) than you can normalize the value in range of (0-255)
private float normalize(float x, float inMin, float inMax, float outMin, float outMax) {
float outRange = outMax - outMin;
float inRange = inMax - inMin;
return (x - inMin) *outRange / inRange + outMin;
}
Finally you can now change Brightness in of 0-100% from 0-255 range like this:
float brightness = normalize(progress, 0, 100, 0.0f, 255.0f);
Hope it will save your time.
this worked for me till kitkat 4.4 but not in android L
private void stopBrightness() {
Settings.System.putInt(this.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, 0);
}
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 10; // range from 0 - 255 as per docs
getWindow().setAttributes(params);
getWindow().addFlags(WindowManager.LayoutParams.FLAGS_CHANGED);
This worked for me. No need of a dummy activity. This works only for your current activity.
This is the complete code on how to change system brightness
private SeekBar brightbar;
//Variable to store brightness value
private int brightness;
//Content resolver used as a handle to the system's settings
private ContentResolver Conresolver;
//Window object, that will store a reference to the current window
private Window window;
/** Called when the activity is first created. */
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Instantiate seekbar object
brightbar = (SeekBar) findViewById(R.id.ChangeBright);
//Get the content resolver
Conresolver = getContentResolver();
//Get the current window
window = getWindow();
brightbar.setMax(255);
brightbar.setKeyProgressIncrement(1);
try {
brightness = System.getInt(Conresolver, System.SCREEN_BRIGHTNESS);
} catch (SettingNotFoundException e) {
Log.e("Error", "Cannot access system brightness");
e.printStackTrace();
}
brightbar.setProgress(brightness);
brightbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
System.putInt(Conresolver, System.SCREEN_BRIGHTNESS, brightness);
LayoutParams layoutpars = window.getAttributes();
layoutpars.screenBrightness = brightness / (float) 255;
window.setAttributes(layoutpars);
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (progress <= 20) {
brightness = 20;
} else {
brightness = progress;
}
}
});
}
Or you may check this tutorial for complete code
happy coding:)
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS,
progress);
private SeekBar Brighness = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lcd_screen_setting);
initUI();
setBrightness();
}
private void setBrightness() {
Brighness.setMax(255);
float curBrightnessValue = 0;
try {
curBrightnessValue = android.provider.Settings.System.getInt(
getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
int screen_brightness = (int) curBrightnessValue;
Brighness.setProgress(screen_brightness);
Brighness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int progress = 0;
#Override
public void onProgressChanged(SeekBar seekBar, int progresValue,
boolean fromUser) {
progress = progresValue;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do something here,
// if you want to do anything at the start of
// touching the seekbar
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS,
progress);
}
});
}
initUI(){
Brighness = (SeekBar) findViewById(R.id.brightnessbar);
}
Add this in manifest
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions"/>
Please Try this , it's May help you. Worked fine for me
According to my experience
1st method.
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 75 / 100.0f;
getWindow().setAttributes(lp);
where the brightness value very according to 1.0f.100f is maximum brightness.
The above mentioned code will increase the brightness of the current window. If we want to increase the brightness of the entire android device this code is not enough, for that we need to use
2nd method.
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS, 192);
Where 192 is the brightness value which very from 1 to 255. The main problem of using 2nd method is it will show the brightness in increased form in android device but actually it will fail to increase android device brightness.This is because it need some refreshing.
That is why I find out the solution by using both codes together.
if(arg2==1)
{
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 75 / 100.0f;
getWindow().setAttributes(lp);
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS, 192);
}
It worked properly for me
You need to create the variable:
private WindowManager.LayoutParams mParams;
then override this method (to save your previous params):
#Override
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
mParams = params;
super.onWindowAttributesChanged(params);
}
than where you wish to change the screen brightness (on the app) just use:
mParams.screenBrightness = 0.01f; //use a value between 0.01f for low brightness and 1f for high brightness
getWindow().setAttributes(mParams);
tested on api version 28.
Was just looking into this for Android 10 and this still works for me on there. But requires getting the calling Activity instance inside the fragment which is less than optimal since we only get the context from onAttach now. Setting it to -1.0f sets it to the system value (the one from brightness settings slider), 0.0f to 1.0f sets brightness values from min to max at your leisure.
WindowManager.LayoutParams lp = myactivity.getWindow().getAttributes();
lp.screenBrightness = brightness;
myactivity.getWindow().setAttributes(lp);
myactivity.getWindow().addFlags(WindowManager.LayoutParams.FLAGS_CHANGED);
I'm using this utils class works for Android 9
public class BrightnessUtil {
public static final int BRIGHTNESS_DEFAULT = 190;
public static final int BRIGHTNESS_MAX = 225;
public static final int BRIGHTNESS_MIN = 0;
public static boolean checkForSettingsPermission(Activity activity) {
if (isNotAllowedWriteSettings(activity)) {
startActivityToAllowWriteSettings(activity);
return false;
}
return true;
}
public static void stopAutoBrightness(Activity activity) {
if (!isNotAllowedWriteSettings(activity)) {
Settings.System.putInt(activity.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
}
public static void setBrightness(Activity activity, int brightness) {
if (!isNotAllowedWriteSettings(activity)) {
//constrain the value of brightness
if (brightness < BRIGHTNESS_MIN)
brightness = BRIGHTNESS_MIN;
else if (brightness > BRIGHTNESS_MAX)
brightness = BRIGHTNESS_MAX;
ContentResolver cResolver = activity.getContentResolver();
Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
}
}
private static void startActivityToAllowWriteSettings(Activity activity) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + activity.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
}
#SuppressLint("ObsoleteSdkInt")
private static boolean isNotAllowedWriteSettings(Activity activity) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(activity);
}
}
There you go, short and sweet; Kotlin version.
/**
* This can be used to override the user's preferred brightness of the screen.
* A value of less than 0, the default, means to use the preferred screen brightness.
* 0 to 1 adjusts the brightness from dark to full bright!
*/
fun Fragment.screenBrightness(x: Float) = activity?.screenBrightness(x)
fun Activity.screenBrightness(x: Float) = window?.apply {
attributes = attributes?.apply { screenBrightness = x.coerceIn(-1f..1f) } }
Kdoc'd also!

Categories