3

これが少し曖昧になってしまったら申し訳ありませんが、質問を言い換えるか、閉じることをお勧めするかどうか教えてください.

SDK 関数の 1 つが実装されていない 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

一部の電話、特に古いものや遅いものでは、リソース (バッテリーなど) を節約するために、設定 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コメントに基づく編集

164行目でわかるように、AndroidソースコードからBrightnessController.javaを見てみましょう。これは、ユーザーがシステム設定UIで明るさスライダーを変更するたびに呼び出される関数です。174 行目では、Settings.system クラスを介して明るさの設定を更新しています。しかし、その前に 170 行目に setBrightness 関数の呼び出しがあります (193 行目で宣言されています)。

setBrightness は、IPowerManager.Stub.asInterface(ServiceManager.getService("power")) への呼び出しである setTemporaryScreenBrightnessSettingOverride への呼び出しを介して輝度レベルを設定します。実際、Android自体は私が提案したことを行っています。これは、次のように見えるシステム コールを介して輝度レベルを設定します。

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

アクティビティで呼び出され、データベースに実際の設定を設定します。したがって、実際に私が提案するのは回避策ではなく、システムがそれを行う方法です。あなたが言及しているデバイスに実装エラーがあるとは思いませんが、それはハードウェア自体に関係していると思います.Androidはハードウェアと直接通信しないため(here を参照)、ハードウェアの方法にある可能性がありますまたはドライバーはこの電話で設計されています。

お役に立てれば...

于 2013-08-08T22:16:21.640 に答える