Reputation: 1202
I apologize if this gets a bit vague, so please let me know if you'd recommend I rephrase or close the question.
I'm running an Android device where one of the SDK functions isn't implemented. I'm attempting to dim the screen via a documented SDK call. This call works as expected on other devices, but does nothing on this one, which suggests to me that the function is not properly implemented on this phone. More confusingly, I can dim the brightness by directly manipulating writing to the /sys/class/backlight/... file from ADB (which is, as far as I can tell, as close as I can get to the driver for this system).
The java code being called is below (brightness is some integer), and this is being targeted for Android 4.2.2.
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, brightness);
Basically, there's a disconnect somewhere, and I'm not sure where that would most likely be.
Since this is a Dalvik app and is execiting Dalvik byte code, my first thought was, "well, maybe Dalvik wasn't compiled with the proper reference to the display driver". That would suggest that each android phone has its own uniquely-compiled version of Dalvik, which seems silly. My best current guess is that Dalvik goes through the hardware abstraction layer, and the HAL isn't aware of the brightness driver handle, while ADB file directly controls the brightness. Does this sound like a reasonable cause of such an issue? Does anyone have any other likely causes of such a class of bug? Thanks for your help.
Upvotes: 3
Views: 1077
Reputation: 3137
Some phones, especially older or slow ones, have stripped out some of the Settings ContentObserver functionality in order to preserve resources (like battery). And if I remember correct this was the default behavior in older APIs. A work around is to manually trigger the brightness new setting via a non ui activity like this one:
public class act_brightnesshelper extends Activity {
//----- Private Static Members -----
private static final String TAG = "act_brightnesshelper";
//----- Private Static Members END -----
//----- Private Members -----
private int brightnessLevel;
//----- Private Members END -----
//----- Activity Overrides -----
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
brightnessLevel = this.getIntent().getExtras().getInt("brightnessLevel");
}
@Override
public void onAttachedToWindow() {
Log.d(TAG, "onAttachedToWindow brightnessLevel = " + brightnessLevel);
super.onAttachedToWindow();
WindowManager.LayoutParams lp = getWindow().getAttributes();
try {
lp.screenBrightness = brightnessLevel / 255f;
getWindow().setAttributes(lp);
} catch(Exception ex) {
//Do Nothing...
}
//Finish the Activity after 500ms...
Thread WaitThread = new Thread(){
@Override
public void run() {
try {Thread.sleep(500);} catch (InterruptedException e) {}
finish();
}
};
WaitThread.start();
}
//----- Activity Overrides END-----
}
and call it after you change the brightness setting by passing the required brightness level in the intent extra like this:
Settings.System.putInt(<cnt resolver>, Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
Settings.System.putInt(<cnt resolver>, Settings.System.SCREEN_BRIGHTNESS, <your level>);
Intent iBriHelper = new Intent(cx, act_brightnesshelper.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
iBriHelper.putExtra("brightnessLevel", <your level>);
context.startActivity(iBriHelper);
for this to be right you have to declare the activity in the manifest like this:
<activity android:name=".act_brightnesshelper"
android:theme="@style/Theme.Transparent"
android:configChanges="orientation"
android:noHistory="true"
android:excludeFromRecents="true">
</activity>
If you are changing the brightness inside an activity then you can do this directly in it. The code I provide is for changing the brightness outside the context of an activity i.e. an app-widget.
EDIT Based on OP comments
Let's take a look at BrightnessController.java from android source code here as you can see in line 164 is the function which called whenever the user changes the brightness slider in the system settings ui. In line 174 the brightness setting is updated via the Settings.system class as you and I do in our code. BUT before that in line 170 there is a call to function setBrightness (declared in line 193).
setBrightness set the brightness level via a call to setTemporaryScreenBrightnessSettingOverride which is a call to IPowerManager.Stub.asInterface(ServiceManager.getService("power")). Actually android itself is doing what I proposed. It sets the brightness level via a system call which it seems that it is equivalent to:
lp.screenBrightness = brightnessLevel / 255f;
getWindow().setAttributes(lp);
called in an activity and then it sets the actually setting in the database. So actually what I propose isn't a work around but it is how the system do it. I don't think that there is an implementation error in the device you are mentioning but rather that it has to do with the hardware itself and since android doesn't communicate with the hardware directly (see here) it may be on how the hardware or the driver is designed in this phone.
Hope this helps...
Upvotes: 1