I'm getting java.lang.IllegalStateException in my Android Music Player Application every time when I closes the Activity
mCurrentPosition = mediaPlayer.getCurrentPosition()/1000; // In milliseconds
I've tried nearly all the codes available and even all at java.lang.illegalStateException randomly occurs when getting mediaPlayer.getCurrentPosition also
Here's my Java code where I'm using it:
protected void initializeSeekBar(){
mSeekBar.setMax(mediaPlayer.getDuration()/1000);
mRunnable = new Runnable() {
#Override
public void run() {
int mCurrentPosition;
if(mediaPlayer!=null && mediaPlayer.isPlaying()){
mCurrentPosition = mediaPlayer.getCurrentPosition()/1000; // In milliseconds
}
else {
mCurrentPosition = 0;
}
if (mSeekBar != null) {
mSeekBar.setProgress(mCurrentPosition);
getAudioStats();
}
handler.postDelayed(mRunnable,1000);
}
};
handler.postDelayed(mRunnable,1000);
}
Please Help me out of this. Thanks in Advance
Edit 1
Also, my Seekbar goes to start when the music pauses and on play, it continues from where it was before pausing
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
getAudioStats();
initializeSeekBar();
if(mediaPlayer != null && fromUser) {
mediaPlayer.seekTo(progress * 1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
protected void getAudioStats(){
long duration = mediaPlayer.getDuration()/1000; // In milliseconds
long due = (mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition())/1000;
long pass = duration - due;
String test = DateUtils.formatElapsedTime(pass);
String test1 = DateUtils.formatElapsedTime(due);
current_time.setText("" + test);
//mDuration.setText("" + duration + " seconds");
total_time.setText("" + test1);
}
You need to remove your runnable from the handler queue when the activity closes (or, better yet, when it pauses). Try putting this in your activity's onPause() method:
handler.removeCallbacks(mRunnable);
For additional robustness, inside the runnable itself, you should only re-queue the runnable if the activity is still active. So instead of this:
handler.postDelayed(mRunnable,1000);
you should do this (assuming this code is in the activity class):
if (!isDestroyed()) {
handler.postDelayed(mRunnable,1000);
}
Also make sure you are stopping the media player before the activity is destroyed.
P.S. If you call initializeSeekBar() multiple times, you will be reassigning mRunnable and leaving the old one in the handler queue where it can cause trouble later. To fix this, you should add this at the start of initializeSeekBar():
protected void initializeSeekBar(){
if (mRunnable != null) {
handler.removeCallbacks(mRunnable);
}
// ... the rest of the method that you currently have
In my program you set the string value for the countdown timer in the secondActivity. That value is then sent to the MainActivities textView which is then supposed to start counting down as soon as the value is fetched. Right now I have made it so you can set the value, and the value is fetched correctly, but what I don't know how to do is start Counting Down this value when It is received. I have already made a CounterClass.
Here is my MainActivity Code...
Bundle extras = getIntent().getExtras();
String intentString;
if(extras != null) {
intentString = extras.getString("TimeValue");
timer = new CounterClass(60000, 1000);
timer.start();
timeSent();
} else {
intentString = "Default String";
}
textTime= (TextView) findViewById(R.id.timeText);
textTime.setText(intentString);
You need to start your timer. Always read the docs.
timer = new CounterClass(millisInFuture, countdownInterval);
timer.start();
EDIT
millisInFuture --- The number of millis in the future from the call to start() until the countdown is done and onFinish() is called.
countDownInterval ---
The interval along the way to receive onTick(long) callbacks.
EDIT 18-12-2015
Convert your intentString to millisInFuture and send it to the CounterClass. And then format it back to HH:MM in onTick() method.
String time = "16:54";
String split[] = time.split(":");
long futureInMillis = Integer.parseInt(split[0]) * 60 * 60 * 1000 + Integer.parseInt(split[1]) * 60 * 1000;
Lets say that you really want to implement your own class.
I think the best and clean way to do it is by interface.
First create a interface class.
AddTimes.java
public interface AddTimes {
void writeTime(String time);
}
Now, implement your interface in your class.
public class MainActivity extends AppCompatActivity implements AddTimes{
Use your class TextView variable "textTime"
timeText = (TextView)findViewById(R.id.timeText); //remove declaration TextView and use timeText instead of textTime .
start your class
new CounterClass(5000L,500L, this).start();
At the CounterClass, add constructor.
AddTimes addTimes;
public CounterClass(long millisInFuture, long countDownInterval, AddTimes addTimes) {
super(millisInFuture, countDownInterval);
this.addTimes = addTimes;
}
Replace textTime.setText(hms); to addTimes.writeTime(hms);
Finally. At your main activity. Implement AddTimes method.
public void writeTime(String time) {
timeText.setText("Time - " + time);
}
Instead of this
TextView timeText = (TextView)findViewById(R.id.timeText);
timeText.setText(intentString);
you need this
textTime= (TextView)findViewById(R.id.timeText);
textTime.setText(intentString);
timer = new CounterClass(10000, 1000);
timer.start();
As you might see timeText has changed to textTime which is a class member variable and your CounterClass uses it.
Copy the code as it is to you MainActivity.java file. Hope this might work.
public class MainActivity extends AppCompatActivity {
TextView textTime;
CountDownTimer timer;
int intValue = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
if(extras != null) {
String intentString = extras.getString("TimeValue"); //if this is a plain number like 20, 45, 209, 8
intValue = Integer.valueOf(intentString);
}
textTime= (TextView)findViewById(R.id.timeText);
timer = new CountDownTimer(intValue * 1000, 1000) {
public void onTick(long millisUntilFinished) {
intValue--;
textTime.setText("Count Down: " + intValue);
}
#Override
public void onFinish() {}
}
}
timer.start();
}
You can simply use the count down timer:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
textField.setText("seconds remaining: " + millisUntilFinished / 1000);
//here you can have your logic to set text to edittext
}
public void onFinish() {
textField.setText("done!");
}
}.start();
I am writing an HIIT (High Intensity Interval Training) activity for which I am implementing an interval timer. The CountDownTimer is supposed to finish 5 minutes of Warm-Up, then proceed to time the HIIT workout.
public class WarmUpActivity extends ActionBarActivity{
TextView Mode;
TextView Time;
int minutes;
long time_remaining;
boolean warmup_finished;
private CountDownTimer HIIT_Timer;
private void StartTimer() {
HIIT_Timer = new CountDownTimer(time_remaining, 1000) {
#Override
public void onTick(long millisUntilFinished) {
time_remaining = millisUntilFinished; //in case activity is paused or stopped
Time.setText(" " + (int)floor(millisUntilFinished / 60000) + ":" + ((millisUntilFinished / 1000) % 60));
if (warmup_finished == true) { //if we are in HIIT mode
if ((int)millisUntilFinished % 60000 == 0) { //every minute
if (Mode.getText() == "Low Intensity")
Mode.setText("High Intensity");
else
Mode.setText("Low Intensity");
}
}
}
#Override
public void onFinish() {
if (warmup_finished==false){
Mode.setText("Low Intensity");
warmup_finished = true;
HIIT_Method();
return;
}
else {
Completed_Method();
return;
}
}
}.start();
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.hiit_layout);
Mode=(TextView) findViewById(R.id.mode);
Time=(TextView) findViewById(R.id.time);
warmup_finished=false;
Mode.setText("Warm-Up");
time_remaining=5*60000; //5 minutes when created
}
#Override
public void onStart(){
super.onStart();
StartTimer();
return;
}
private void HIIT_Method(){
minutes=getIntent().getIntExtra(SelectHIITDuration.MINUTES, 0);
time_remaining=minutes*60000;
StartTimer();
return;
}
private void Completed_Method(){
Mode.setText("Workout Completed");
}
}
When warmup is finished and onFinish() is called for the first time, HIIT_Method is called, in which the HIIT timer is supposed to start with user specified duration. The problem is, after the new timer is declared using Start_Timer(), somehow Completed_Method is called. It can only be called from onFinish(). Why is onFinish() being called after I declare a new timer?
We need to move your call to startTimer from onStart to onCreate.
The issue here is understanding the Android lifecycle for an activity. A very good explanation by someone with better understanding than I is explained here.
Now from what I understand, we typically don't touch onStart until we start worrying about service binding and database queries, but other developers may think differently.
The official android documentation on an activity's lifecycle can be found here
Please I need help!!
I created an app that reads data from arduino through separate thread (ReadingProcessor) and fillings the values into readings[], then I created another separate thread that checks on the values. In this checking, if it's the first time that a warning occurs then the application sends message, else if there is previous warning readings, the application should wait till passing a warning interval
public class WarningProcessor extends Thread {
float readings[];
float[] min, max;
long elapsedTime;
long[] lastWarningTime;
boolean[] inWarning;
long checkInterval = Long.parseLong(Settings.Swarning) * 60000;
long currentTime;
SerialActivity sa = new SerialActivity();
WarningProcessor(float readings[]) {
this.readings = readings;
}
#Override
public void run() {
sleep_s(2);
synchronized (readings) {
lastWarningTime = new long[readings.length];
inWarning = new boolean[readings.length];
Arrays.fill(inWarning, false);
}
while (true) {
this.readings = ReadingProcessor.readings;
synchronized (readings) {
for (int i = 0; i < readings.length; i++) {
currentTime = Calendar.getInstance().getTimeInMillis();
if (readings[i] > 100) { //here to make boundaries
if (inWarning[i] == false) {
//send warning
for(String number : StartPage.phoneNumbers)
SmsManager.getDefault().sendTextMessage(number,
null,"Warning "+readings[i], null, null);
lastWarningTime[i] = currentTime;
inWarning[i] = true;
} else {
if (currentTime - lastWarningTime[i] > checkInterval) {
//send warning
for(String number : StartPage.phoneNumbers)
SmsManager.getDefault().sendTextMessage(number,
null,"Warning "+readings[i], null, null);
lastWarningTime[i] = currentTime;
}
}
} else {
inWarning[i] = false;
}
}
}
sleep_s(1);
}
}
In case of continuous warning data the program should sends message in interval, and this works well when I'm still on activity and also when I'm onpause() state, but the problem is that after the onpause() when I return to application UI , the program resends messages in case of continuous interval, discarding the waiting till passing the interval
public class SerialActivity extends Activity {
private static ArduinoSerialDriver sDriver;
private static TextView mDumpTextView;
private static ScrollView mScrollView;
String Data[]={"Temperature"};
float[] readings = new float[Data.length];
ReadingProcessor readingProcessor;
WarningProcessor warningProcessor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.serialactivity);
mDumpTextView = (TextView) findViewById(R.id.consoleText);
mScrollView = (ScrollView) findViewById(R.id.demoScroller);}
#Override
protected void onStart() {
super.onStart();
ReadingProcessor rp = new ReadingProcessor(readings,sDriver);
readingProcessor=rp;
WarningProcessor wp = new WarningProcessor(readings);
warningProcessor=wp;
rp.start();
wp.start();
}
#SuppressWarnings("deprecation")
#Override
protected void onDestroy() {
super.onDestroy();
readingProcessor.Stop();
warningProcessor.stop();
}
So please help me, I tried too many solutions like using handler and I got the same problem
onStart is called every time you return the application to the foreground. Your problem is that you have multiple instances of each thread running. If you only want one instance of each thread running, you need to create and start the threads in onCreate instead of onStart. In general, you should only start a thread in onStart if you are going to kill it in onPause.
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!