3

如果这有点含糊,我深表歉意,所以如果您建议我改写或关闭问题,请告诉我。

我正在运行一个未实现 SDK 功能之一的 Android 设备。我正在尝试通过记录的 SDK 调用使屏幕变暗。此调用在其他设备上按预期工作,但在此设备上没有任何作用,这向我表明该功能未在此手机上正确实现。更令人困惑的是,我可以通过直接操作从 ADB 写入 /sys/class/backlight/... 文件来调暗亮度(据我所知,这是尽可能接近该系统的驱动程序)。

被调用的 java 代码如下(亮度是某个整数),这是针对 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);

基本上,某处存在断开连接,我不确定最有可能在哪里。

由于这是一个 Dalvik 应用程序并且正在执行 Dalvik 字节码,我的第一个想法是,“好吧,也许 Dalvik 没有使用对显示驱动程序的正确引用进行编译”。这表明每部 Android 手机都有自己独特编译的 Dalvik 版本,这似乎很愚蠢。我目前最好的猜测是,Dalvik 通过硬件抽象层,HAL 不知道亮度驱动程序句柄,而 ADB 文件直接控制亮度。这听起来像是造成此类问题的合理原因吗?有没有人有任何其他可能导致此类错误的原因?谢谢你的帮助。

4

1 回答 1

1

一些手机,尤其是较旧或速度较慢的手机,已经剥离了一些 Settings ContentObserver 功能以节省资源(如电池)。如果我没记错的话,这是旧 API 中的默认行为。一种解决方法是通过像这样的非 ui 活动手动触发亮度新设置:

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----- 
}

并通过在意图中传递所需的亮度级别来更改亮度设置后调用它,如下所示:

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);

为此,您必须像这样在清单中声明活动:

<activity android:name=".act_brightnesshelper"
        android:theme="@style/Theme.Transparent"
        android:configChanges="orientation"
        android:noHistory="true"
    android:excludeFromRecents="true">
</activity>

如果您要更改活动内部的亮度,则可以直接在其中执行此操作。我提供的代码用于更改活动上下文之外的亮度,即应用程序小部件。

编辑基于 OP 评论

让我们看一下来自 android 源代码的 BrightnessController.java,正如您在第 164 行中看到的那样,当用户在系统设置 ui 中更改亮度滑块时调用的函数。在第 174 行,亮度设置通过 Settings.system 类更新,就像你我在我们的代码中所做的那样。但在此之前,在第 170 行调用了函数 setBrightness(在第 193 行声明)。

setBrightness 通过调用 setTemporaryScreenBrightnessSettingOverride 设置亮度级别,这是对 IPowerManager.Stub.asInterface(ServiceManager.getService("power")) 的调用。实际上android本身正在做我建议的事情。它通过系统调用设置亮度级别,它似乎等效于:

lp.screenBrightness = brightnessLevel / 255f;
getWindow().setAttributes(lp);

在活动中调用,然后在数据库中设置实际设置。所以实际上我建议的不是解决方法,而是系统如何做到这一点。我认为您提到的设备中没有实现错误,而是与硬件本身有关,并且由于 android 不直接与硬件通信(请参见此处),因此可能与硬件有关或者驱动程序是在这款手机中设计的。

希望这可以帮助...

于 2013-08-08T22:16:21.640 回答