Android 9.0 (P版本) 亮度控制接口变更

1. Android 9.0 之前的亮度控制接口

import android.os.IPowerManager;
import android.provider.Settings;
import android.content.Context;


    /**
     * Used by the settings application and brightness control widgets to
     * temporarily override the current screen brightness setting so that the
     * user can observe the effect of an intended settings change without
     * applying it immediately.
     * <p>
     * The override will be canceled when the setting value is next updated.
     *
     * brightness The overridden brightness.
     * @see android.provider.Settings.System#SCREEN_BRIGHTNESS
     */
    public static void setBrightnessValue(Context mContext, int value) {
        try {
            IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
            if (power != null) {
                power.setTemporaryScreenBrightnessSettingOverride(value);
            }
        } catch (RemoteException doe) {
            Log.w(TAG, doe);
        }
        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, value);
    }

    public static void setBrightnessValueBg(Context mContext, int value) {
        try {
            IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
            if (power != null) {
                power.setTemporaryScreenBrightnessSettingOverride(value);
            }
        } catch (RemoteException doe) {
            Log.w(TAG, doe);
        }
    }
1.1 参见Android 8.0的SystemUI代码

frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java:419: mPower.setTemporaryScreenBrightnessSettingOverride(brightness);

package com.android.systemui.settings;

public class BrightnessController implements ToggleSlider.Listener {

    private void setBrightness(int brightness) {
        try {
            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
        } catch (RemoteException ex) {
        }
    }

2. Android 9.0 的亮度控制接口

2.1 参考Android 9.0的SystemUI代码
package com.android.systemui.settings;

import android.hardware.display.DisplayManager;


public class BrightnessController implements ToggleSlider.Listener {

    private final DisplayManager mDisplayManager;


    private void setBrightness(int brightness) {
        mDisplayManager.setTemporaryBrightness(brightness);
    }
2.2 查看 DisplayManager.setTemporaryBrightness源码
  • 源码路径

frameworks/base/core/java/android/hardware/display/DisplayManager.java

root@69959bbb90c6:/home/suhuazhi/9.1# find frameworks/ -name  "DisplayManager.java"
frameworks/base/core/java/android/hardware/display/DisplayManager.java

  • 查看实现方式 -DisplayManager.setTemporaryBrightness
package android.hardware.display;

@SystemService(Context.DISPLAY_SERVICE)
public final class DisplayManager {

    private final DisplayManagerGlobal mGlobal;


    /**
     * Temporarily sets the brightness of the display.
     * <p>
     * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
     * </p>
     *
     * @param brightness The brightness value from 0 to 255.
     *
     * @hide Requires signature permission.
     */
    public void setTemporaryBrightness(int brightness) {
        mGlobal.setTemporaryBrightness(brightness);
    }
  • 源码路径
    frameworks/base/core/java/android/hardware/display/DisplayManagerGlobal.java
root@69959bbb90c6:/home/suhuazhi/9.1# find frameworks/ -name  "DisplayManagerGlobal.java"
frameworks/base/core/java/android/hardware/display/DisplayManagerGlobal.java
  • 查看实现方式 -DisplayManagerGlobal.setTemporaryBrightness
package android.hardware.display;


public final class DisplayManagerGlobal {

    private final IDisplayManager mDm;


    /**
     * Temporarily sets the brightness of the display.
     * <p>
     * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
     * </p>
     *
     * @param brightness The brightness value from 0 to 255.
     *
     * @hide Requires signature permission.
     */
    public void setTemporaryBrightness(int brightness) {
        try {
            mDm.setTemporaryBrightness(brightness);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
  • 查看实现方式 -DisplayManagerService.setTemporaryBrightness
  • ./frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java

上述 IDisplayManager 是一个aidl接口,对应找DisplayManagerService即可

package com.android.server.display;

public final class DisplayManagerService extends SystemService {


        @Override // Binder call
        public void setTemporaryBrightness(int brightness) {
            mContext.enforceCallingOrSelfPermission(
                    Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
                    "Permission required to set the display's brightness");
            final long token = Binder.clearCallingIdentity();
            try {
                synchronized (mSyncRoot) {
                    mDisplayPowerController.setTemporaryBrightness(brightness);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

上述需要权限

    <!-- DisplayManager.setTemporaryBrightness -->
    <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS" />

3. 综合上述Android 9.0 的亮度控制接口

  • 权限
    <!-- DisplayManager.setTemporaryBrightness -->
    <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS" />
  • 软件接口
import android.hardware.display.DisplayManager;
import android.content.Context;
import android.os.ServiceManager;
import android.os.IPowerManager;

    /**
     * Used by the settings application and brightness control widgets to
     * temporarily override the current screen brightness setting so that the
     * user can observe the effect of an intended settings change without
     * applying it immediately.
     * <p>
     * The override will be canceled when the setting value is next updated.
     *
     * brightness The overridden brightness.
     * @see android.provider.Settings.System#SCREEN_BRIGHTNESS
     */
    public static void setBrightnessValue(Context mContext, int value) {
        setBrightnessValueBg(mContext, value);
        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, value);
    }

    public static void setBrightnessValueBg(Context mContext, int value) {
        if (android.os.Build.VERSION.SDK_INT >= 27) {
            // <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS" />
            DisplayManager mDisplayManager = mContext.getSystemService(DisplayManager.class);
            mDisplayManager.setTemporaryBrightness(value);
        } else {
            /*try {
                IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
                if (power != null) {
                    power.setTemporaryScreenBrightnessSettingOverride(value);
                }
            } catch (RemoteException doe) {
                Log.w(TAG, doe);
            }*/
        }
    }
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android 9.0 及以上版本,为了进一步增强应用程序的安全性,Android 引入了更严格的后台限制,禁止所有未在前台运行的应用程序启动服务。如果您想在后台启动服务,需要使用 `startForegroundService()` 方法,并且需要在 5 秒钟内调用 `startForeground()` 方法将服务设置为前台服务。 以下是一个使用 `startForegroundService()` 和 `startForeground()` 的示例代码: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 创建一个 NotificationChannel NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT); // 向系统注册 NotificationChannel NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); } // 创建一个 Intent,启动你的服务 Intent serviceIntent = new Intent(this, YourService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 在 Android 9.0 及以上版本上,需要调用 startForegroundService() 方法启动服务。 startForegroundService(serviceIntent); // 在启动服务后,5 秒钟内调用 startForeground() 方法将服务设置为前台服务。 // 如果在 5 秒钟内没有调用 startForeground() 方法,系统会认为服务无法正常启动,会抛出异常。 new Handler().postDelayed(new Runnable() { @Override public void run() { startForeground(1, new Notification()); } }, 5000); } else { // 在 Android 9.0 以下版本上,可以直接调用 startService() 方法启动服务。 startService(serviceIntent); } ``` 注意:在 Android 9.0 及以上版本上,如果你使用的是 `startForeground()` 方法,会在 5 秒钟后抛出 `ANR` 异常,因为 Android 9.0 及以上版本要求服务必须在 5 秒钟内设置为前台服务。如果你想在后台运行服务,必须使用 `startForegroundService()` 和 `startForeground()` 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值