Search code examples
androiddelphiscreenfiremonkey

Dim Screen Android Firemonkey


Does anyone know how to dim the screen on Delphi Firemonkey for Android? I've been googling around and searching but could only find how to remove the auto dim for android by acquiring a Wakelock (Delphi XE5 Android. How to use PowerManager.WakeLock?).

At best I'd like to achieve two states: Evening = 20% brightness Daytime = 100% brightness

I am using Delphi 10.1 Berlin. Thank you for your help.


Solution

  • Taking this Stack Overflow question, which has the Java solution, as a guide I rustled up this helper unit that should work in Delphi versions from around XE8 to 10.1 Berlin, which seems to do the trick:

    unit ScreenBrightnessU;
    
    interface
    
    function GetScreenBrightness: Byte;
    procedure SetScreenBrightness(Brightness: Byte);
    
    implementation
    
    uses
      MiscU,
      FMX.Helpers.Android,
    {$IF RTLVersion >= 31}
      FMX.DialogService,
    {$ELSE}
      FMX.Dialogs,
    {$ENDIF}
      System.UITypes,
      System.SysUtils,
      Androidapi.Helpers,
      Androidapi.JNI.App,
      Androidapi.JNI.Provider,
      Androidapi.JNI.GraphicsContentViewText;
    
    function GetScreenBrightness: Byte;
    var
      Resolver: JContentResolver;
    begin
      Resolver :=
    {$IF RTLVersion >= 30}
        TAndroidHelper.ContentResolver;
    {$ELSE}
        SharedActivityContext.getContentResolver;
    {$ENDIF}
      Result := TJSettings_System.JavaClass.getInt(
        Resolver,
        TJSettings_System.JavaClass.SCREEN_BRIGHTNESS);
    end;
    
    procedure SetScreenBrightness(Brightness: Byte);
    var
      Resolver: JContentResolver;
      AttainedBrightness: Single;
      LayoutParams: JWindowManager_LayoutParams;
      Window: JWindow;
    begin
      if not HasPermission('android.permission.WRITE_SETTINGS') then
    {$IF RTLVersion >= 31}
        TDialogService.MessageDialog('App does not have the WRITE_SETTINGS permission', TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], TMsgDlgBtn.mbCancel, 0, nil)
    {$ELSE}
        MessageDlg('App does not have the WRITE_SETTINGS permission', TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], 0)
    {$ENDIF}
      else
      begin
    {$IF RTLVersion >= 30}
        Resolver := TAndroidHelper.ContentResolver;
    {$ELSE}
        Resolver := SharedActivityContext.getContentResolver;
    {$ENDIF}
        // This will set the manual mode (set the automatic mode off)
        TJSettings_System.JavaClass.putInt(
          Resolver,
          TJSettings_System.JavaClass.SCREEN_BRIGHTNESS_MODE,
          TJSettings_System.JavaClass.SCREEN_BRIGHTNESS_MODE_MANUAL);
        // This will set the required brightness
        TJSettings_System.JavaClass.putInt(
          Resolver,
          TJSettings_System.JavaClass.SCREEN_BRIGHTNESS,
          Brightness);
        try
          AttainedBrightness := GetScreenBrightness;
          CallInUIThread(
            procedure
            begin
      {$IF RTLVersion >= 30}
              Window := TAndroidHelper.Activity.getWindow;
      {$ELSE}
              Window := SharedActivity.getWindow;
      {$ENDIF}
              LayoutParams := Window.getAttributes;
              LayoutParams.screenBrightness := AttainedBrightness / 255;
              Window.setAttributes(LayoutParams);
            end);
        except
          // ONOES!!!!
          // <sweeps issue under the carpet>
        end;
      end;
    end;
    
    end.
    

    You'll note that the code does permission checking via the helper unit below. This is not vital so long as you ensure you have the WRITE_SETTINGS permission set in your project for all the Android build configurations.

    unit MiscU;
    
    interface
    
    function HasPermission(const Permission: string): Boolean;
    
    implementation
    
    uses
      FMX.Helpers.Android,
      Androidapi.Helpers,
      Androidapi.JNI.JavaTypes,
      Androidapi.JNI.GraphicsContentViewText;
    
    function HasPermission(const Permission: string): Boolean;
    begin
      //Permissions listed at http://d.android.com/reference/android/Manifest.permission.html
    {$IF RTLVersion >= 30}
      Result := TAndroidHelper.Context.checkCallingOrSelfPermission(
    {$ELSE}
      Result := SharedActivityContext.checkCallingOrSelfPermission(
    {$ENDIF}
        StringToJString(Permission)) =
        TJPackageManager.JavaClass.PERMISSION_GRANTED
    end;
    
    end.