Amazon Gift Cards

Monday, January 5, 2009

Changing the Screen Brightness Programatically

Update: If your target is cupcake(android 1.5), you might want to see this tutorial


There are some discussion on Google group on this matter so i try to see if how this problem can be fixed. This problem could be fixed by using something that is not documented and is not advised to use (Its sort of a hack, i'm not responsible if something went wrong on your android). What this app will do it count to 240, 20 per second starting from 0. Then on each count it will set the brightness of your phone.

Anyway here is the how i did it. Please read the Note at the bottom.

First add <uses-permission android:name="android.permission.HARDWARE_TEST"></uses-permission> to your Manifest file.
package com.monmonja.firstDemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.IHardwareService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.widget.TextView;

public class Main extends Activity  { 
  private TextView txtStatus;
  private RefreshHandler mRedrawHandler = new RefreshHandler();

  class RefreshHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
      Main.this.updateUI();
    }

    public void sleep(long delayMillis) {
      this.removeMessages(0);
      sendMessageDelayed(obtainMessage(0), delayMillis);
    }
  };

  private void updateUI(){
    int currentInt = Integer.parseInt((String) txtStatus.getText()) + 20;
    if(currentInt <= 250){
      mRedrawHandler.sleep(1000);
      setBrightness(currentInt);
      txtStatus.setText(String.valueOf(currentInt));
    }
  }

  @Override 
  public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.main);
    this.txtStatus = (TextView) this.findViewById(R.id.txtStatus);
    updateUI();
  } 

  private void setBrightness(int brightness) {
    try {
      IHardwareService hardware = IHardwareService.Stub.asInterface(
ServiceManager.getService("hardware"));
      if (hardware != null) {
        hardware.setScreenBacklight(brightness);
      }
    } catch (RemoteException doe) {          
    }        
  }
}


Note
By default there is no IHardwareService and other classes related to it. In order to have this you can download hardware09.jar and place it on your application folder (In my app, i created a new folder named lib). In order to use this on eclipse, you need to right click on your application, Properties, Java Build Paths, and click Add JAR.

Set to include hardware.jar

Quick Explanation
We get our hardware services via IHardwareService hardware = IHardwareService.Stub.asInterface(ServiceManager.getService("hardware")); then we set the brightness hardware.setScreenBacklight(brightness);

Source Code
Main.xml of Changing Brightness
Main.java of Changing Brightness

References
Using Handler in Android
FlashLight Source File

Hope you will get the hardware09.jar to work/referenced in your eclipse.

Hope it helps :)

Update History
   Jan 17, 2012 - Visual Update

18 comments:

Ajeya said...

Great article!!

One question though. Is there anyway to get the screen brightness so that I can restore it to what it was before I changed it?

phoeniix said...

To get the current brightness level just request it from the systems settings: Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);

Day 02: Flashlight - The journey with little green men said...

[...] Almond Mendoza - Changing the Screen Brightness Programatically [...]

Mark said...

hardware09.jar looks fine but when I reference it in my projects it compiles fine but during load and start i get the following errors and exceptions:

DexOpt: 'Landroid/os/IInterface;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/IHardwareService;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/IHardwareService$Stub$Proxy;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/IHardwareService$Stub;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/RemoteException;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/ServiceManager;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/ServiceManagerNative;' has an earlier definition; blocking out
DexOpt: 'Landroid/os/ServiceManagerProxy;' has an earlier definition; blocking out
DexOpt: not verifying 'Landroid/os/IInterface;': multiple definitions
DexOpt: not verifying 'Landroid/os/IHardwareService;': multiple definitions
DexOpt: not verifying 'Landroid/os/IHardwareService$Stub$Proxy;': multiple definitions
DexOpt: not verifying 'Landroid/os/IHardwareService$Stub;': multiple definitions
DexOpt: not verifying 'Landroid/os/RemoteException;': multiple definitions
DexOpt: not verifying 'Landroid/os/ServiceManager;': multiple definitions
DexOpt: not verifying 'Landroid/os/ServiceManagerNative;': multiple definitions
DexOpt: not verifying 'Landroid/os/ServiceManagerProxy;': multiple definitions
DexOpt: not resolving ambiguous class 'Landroid/os/ServiceManager;'

Uncaught handler: thread main exiting due to uncaught exception
java.lang.VerifyError: net.abc.xzy
at net.abc.xzy.do(do.java:116)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
at android.app.ActivityThread.access$1800(ActivityThread.java:112)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3948)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
at dalvik.system.NativeStart.main(Native Method)

krt said...

I am using Android sdk1.5 r1 patch.. tried the below on emulator.

I did as you have suggested. included hardware09.jar as you have mentioned,
compilation has no problem but executing it has.

D/installd( 539): DexInv: --- BEGIN '/data/app/vmdl13614.tmp' ---
D/dalvikvm( 707): DexOpt: 'Landroid/os/IInterface;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/IHardwareService;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/IHardwareService$Stub$Proxy;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/IHardwareService$Stub;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/RemoteException;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/ServiceManager;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/ServiceManagerNative;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: 'Landroid/os/ServiceManagerProxy;' has an earlier definition; blocking out
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/IInterface;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/IHardwareService;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/IHardwareService$Stub$Proxy;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/IHardwareService$Stub;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/RemoteException;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/ServiceManager;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/ServiceManagerNative;': multiple definitions
D/dalvikvm( 707): DexOpt: not verifying 'Landroid/os/ServiceManagerProxy;': multiple definitions
I/dalvikvm( 707): DexOpt: not resolving ambiguous class 'Landroid/os/ServiceManager;'
D/dalvikvm( 707): DexOpt: load 59ms, verify 43ms, opt 1ms
D/installd( 539): DexInv: --- END '/data/app/vmdl13614.tmp' (success) ---
.
.
W/PackageManager( 565): Not granting permission android.permission.HARDWARE_TEST to package com.MyService (protectionLevel=2 flags=0x44)
.
.
E/dalvikvm( 720): Could not find method android.os.IHardwareService.setScreenBacklight, referenced from method com.MyService.app.MyServiceTest.testIsMyTest
W/dalvikvm( 720): VFY: unable to resolve interface method 41: Landroid/os/IHardwareService;.setScreenBacklight (I)V
W/dalvikvm( 720): VFY: rejecting opcode 0x72 at 0x0039

Any input would be of great help.
Thanks,
krt

admin said...

Are you developing using cupcake or 1.5?

krt said...

I am using 1.5 sdk.

admin said...

please see this post http://almondmendoza.com/2009/05/23/changing-the-screen-brightness-programatically-in-cupcake/ tnx

krt said...

thanks for the quick reply.
But I do not have a window.I just wanted to right simple program which modifies the window brightness.

DAK said...

I am try to change system brightness setting. NOT LayoutParams for just one window in SDK 1.5 r3.

I changed library files (hardware09.jar) to recent cupcake classes and tried this sample. Then It does not work and throw an exception

10-15 10:52:41.087: ERROR/AndroidRuntime(4420): Caused by: java.lang.SecurityException: Requires HARDWARE_TEST permission

However, I have asked for the permission in AndroidManifest.xml definetly.

I could find interesting warning which state permission is not granted.
10-15 10:52:37.397: WARN/PackageManager(56): Not granting permission android.permission.HARDWARE_TEST to package com.monmonja.firstDemo (protectionLevel=2 flags=0x44)

Some says HARDWARE_TEST permission is not allowed to third party app but I know there are bunch of application that support brightness change in cupcake.

I spent too much time for googling and I am getting tired :(

please please show me the way!

admin said...

try this one:

WindowManager.LayoutParams lp=yourActivity.getWindow().getAttributes();
// SDK 1.5 call:
//lp.screenBrightness=val;
try {
fieldScreenBrightness.setFloat(lp, val);
} catch (IllegalAccessException e) {
Log.d("BrightnessNew for SDK 1.5", "Setting brightness failed");
}
yourActivity.getWindow().setAttributes(lp);

Source: http://code.google.com/p/openintents/source/browse/trunk/Flashlight/src/org/openintents/flashlight/BrightnessNew.java

DAK said...

Thanks for replay..
I saw that method in your "Changing the Screen Brightness Programatically in Cupcake" article.
It works very well but only for one window.

Not only just one activity, I want to change system brightness permanently.

Like your bightness change toggle widget.
Thanks in advance :)

Marc said...

The implementation of the IHardwareService that is provided here has worked wonders on all kinds of fronts.

Can you tell me where you acquired the hardware09.jar file? Are there other files like it that allow access/interface with other hidden classes? Did you compile that jar file yourself? If so, how did you do it?

I'm looking to unlock more android functions that have been hidden away.

Thanks,

Marc

admin said...

Marc, i just got it from http://code.google.com/p/apps-for-android/ if you looking to unlock more android functions this might help you too Calling private methods in Android

update: should be http://code.google.com/p/openintents/

Fred said...

How do you make this in widgets?

Anonymous said...

the link to cupcake at the top should be:
http://www.tutorialforandroid.com/2009/05/changing-screen-brightness.html

Anonymous said...

hi admin...!
how to creat a jar file that u did, even i would like to use unimported packages in my application.

GVK51 said...

hey i need to build a jar file from the internal classes present in android.os, how i can do that please help me