Android рдореЗрдВ SystemUI рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ



рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдореБрдЦреНрдп рдПрдВрдбреНрд░реЙрдЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди - SystemUI рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдФрд░ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛ред рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рд╖рдп рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рдереА, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЗрддрдиреА рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рд░ рджрд┐рди рдпрд╛ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдмрд╕ Google Play рдкрд░ рд╣рдЬрд╛рд░реЛрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореБрдЭреЗ рдПрдВрдбреНрд░реЙрдЗрдб рдХреА рд╕реВрдЪрдирд╛ рд╕реБрд░рдХреНрд╖рд╛ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрдирд╛рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдореБрджреНрджреЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИред

Android рдкрд░, SystemUI рдПрдХ рдРрд╕рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдкрде platform_frameworks_base / package / SystemUI / рдореЗрдВ рд╣реИ , рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рдпрд╣ рд╕рд┐рд╕реНрдЯрдо / рдирд┐рдЬреА-рдРрдк / -SystemUI рдореЗрдВ рд╣реИред

рдирд┐рдЬреА-рдРрдк рд╡рд╣ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВред рд╡реИрд╕реЗ, рд╕рд┐рд╕реНрдЯрдо / рдРрдк рдкрде рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИрдВ, рдФрд░ рд╕рд╛рдзрд╛рд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬреЛ рд╣рдо рдЕрдкрдиреЗ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рд╡реЗ рдбреЗрдЯрд╛ рдпрд╛ рдРрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддреЗ рд╣реИрдВред

рдпрд╣ рддреБрд░рдВрдд рдкреНрд░рд╢реНрди рдЙрдард╛рддрд╛ рд╣реИ: рд╕рднреА рдкреВрд░реНрд╡рд╕реНрдерд╛рдкрд┐рдд рдФрд░ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдзрдХреЗрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛, рдпрд╣ рдЕрд▓рдЧрд╛рд╡ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ?

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдХреБрдЫ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреВрд╕рд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдкреНрд░рдгрд╛рд▓реАрдЧрдд рд╣реИрдВ :) рдФрд░ рдпрд╣ рдЕрд▓рдЧрд╛рд╡ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╢реЛрд╖рдг рдХрд╡рд░реЗрдЬ рдХреЛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ рддрд╛рдХрд┐ рд╕реБрд░рдХреНрд╖рд┐рдд рд╕рдВрдЪрд╛рд▓рди рддрдХ рдкрд╣реБрдВрдЪ рдмрдирд╛рдИ рдЬрд╛ рд╕рдХреЗред рдЖрдк рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ ApplicationInfo.FLAG_SYSTEM рд╣реЛрдЧрд╛ рдФрд░ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЕрдзрд┐рдХ рдЕрдзрд┐рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдЕрдиреБрдорддрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдПрдкреАрдХреЗ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд╕реЗрдХреНрд╢рди рдореЗрдВ рд░рдЦреА рдЬрд╛рдПрдЧреАред

рддреЛ, SystemUI рдПрдХ рдПрдкреАрдХреЗ рдлрд╛рдЗрд▓ рд╣реИ, рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рдЖрдк рдЬрдЯрд┐рд▓ SystemUI рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ, рд╣реИ рдирд╛?

рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ:


  • рдиреЗрд╡рд┐рдЧреЗрд╢рди
  • рд╣рд╛рд▓ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧ
  • рддреНрд╡рд░рд┐рдд рд╕реЗрдЯрд┐рдВрдЧреНрд╕
  • рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдмрд╛рд░
  • рд▓реЙрдХ рд╕реНрдХреНрд░реАрди
  • рдорд╛рддреНрд░рд╛ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг
  • рд╣реЛрдо рд╕реНрдХреНрд░реАрди
  • ...

SystemUI рд▓реЙрдиреНрдЪ рдХрд░реЗрдВ


рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдКрдкрд░ рдХрд╣рд╛, рд╕рд┐рд╕реНрдЯрдордпреВрдЖрдИ рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рддрд░рд╣ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рд▓реЙрдиреНрдЪ рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рд▓реЙрдиреНрдЪ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИред SystemUI рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ рдЬреЛ рд╕рд┐рд╕реНрдЯрдо рдмреВрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

<application android:name=".SystemUIApplication" android:persistent="true" android:allowClearUserData="false" android:allowBackup="false" android:hardwareAccelerated="true" android:label="@string/app_label" android:icon="@drawable/icon" android:process="com.android.systemui" android:supportsRtl="true" android:theme="@style/Theme.SystemUI" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true" android:appComponentFactory="androidx.core.app.CoreComponentFactory"> 

рдпрджрд┐ рд╣рдо SystemServer рдореЗрдВ рдЖрддреЗ рд╣реИрдВ, рдЬреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдХреА рджреБрдирд┐рдпрд╛ рдХреЗ рджреЛ рд╕реНрддрдВрднреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ (рджреВрд╕рд░рд╛ Zygote рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдФрд░ рд╕рдордп рдкрд░ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛), рддреЛ рд╣рдо рдЙрд╕ рдЬрдЧрд╣ рдХреЛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ SystemUI рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рд╕рд┐рд╕реНрдЯрдо рдмреВрдЯ рд╣реЛрддрд╛ рд╣реИред

  static final void startSystemUi(Context context, WindowManagerService windowManager) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); //Slog.d(TAG, "Starting service: " + intent); context.startServiceAsUser(intent, UserHandle.SYSTEM); windowManager.onSystemUiStarted(); } 

рдпрд╣рд╛рдВ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ SystemUI рд╕реЗрд╡рд╛ рдЧреИрд░-рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ API startServiceAsUser рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреА рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реЗрдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реЛрдиреЗ рдкрд░ рдХреБрдЫ рдмрд╛рд░ рд╕реЛрдЪреЗрдВред рд╕реМ рдмрд╛рд░ рд╕реЛрдЪреЛ :)

рдЗрд╕рд▓рд┐рдП, рдпрд╣рд╛рдВ рд╣рдо рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рд┐рд╕реНрдЯрдордпреВрдЖрдИ рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдПрдХ рдЕрд▓рдЧ рд╕реЗрд╡рд╛ рдпрд╛ рдПрдХ рд╕реНрд╡рддрдВрддреНрд░ рдореЙрдбреНрдпреВрд▓ рд╣реИред

 public abstract class SystemUI implements SysUiServiceProvider { public Context mContext; public Map<Class<?>, Object> mComponents; public abstract void start(); protected void onConfigurationChanged(Configuration newConfig) { } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { } protected void onBootCompleted() { } @SuppressWarnings("unchecked") public <T> T getComponent(Class<T> interfaceType) { return (T) (mComponents != null ? mComponents.get(interfaceType) : null); } public <T, C extends T> void putComponent(Class<T> interfaceType, C component) { if (mComponents != null) { mComponents.put(interfaceType, component); } } public static void overrideNotificationAppName(Context context, Notification.Builder n, boolean system) { final Bundle extras = new Bundle(); String appName = system ? context.getString(com.android.internal.R.string.notification_app_name_system) : context.getString(com.android.internal.R.string.notification_app_name_settings); extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName); n.addExtras(extras); } } 

рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯрд╛рд░реНрдЯ () рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдиреАрдЪреЗ рд╕реВрдЪреАрдмрджреНрдз рд╣реИрдВред

 <string-array name="config_systemUIServiceComponents" translatable="false"> <item>com.android.systemui.Dependency</item> <item>com.android.systemui.util.NotificationChannels</item> <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item> <item>com.android.systemui.keyguard.KeyguardViewMediator</item> <item>com.android.systemui.recents.Recents</item> <item>com.android.systemui.volume.VolumeUI</item> <item>com.android.systemui.stackdivider.Divider</item> <item>com.android.systemui.SystemBars</item> <item>com.android.systemui.usb.StorageNotification</item> <item>com.android.systemui.power.PowerUI</item> <item>com.android.systemui.media.RingtonePlayer</item> <item>com.android.systemui.keyboard.KeyboardUI</item> <item>com.android.systemui.pip.PipUI</item> <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item> <item>@string/config_systemUIVendorServiceComponent</item> <item>com.android.systemui.util.leak.GarbageMonitor$Service</item> <item>com.android.systemui.LatencyTester</item> <item>com.android.systemui.globalactions.GlobalActionsComponent</item> <item>com.android.systemui.ScreenDecorations</item> <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item> <item>com.android.systemui.SliceBroadcastRelayHandler</item> </string-array> 

рдорд╛рддреНрд░рд╛ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг


рд╣рдо рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рд╡реЙрд▓реНрдпреВрдо рдмрдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪрддреЗ рд╣реИрдВ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдХреНрдпрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рд╣рдо рдзреНрд╡рдирд┐ рдХреЛ рдмрдврд╝рд╛ рдпрд╛ рдХрдо рдХрд░ рд╕рдХреЗрдВред рдСрдкрд░реЗрд╢рди рд╢рдмреНрджреЛрдВ рдореЗрдВ рдХрд╛рдлреА рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рд╡реЙрд▓реНрдпреВрдо рдпреВрдЖрдИ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЬреЛ рд╕рд┐рд╕реНрдЯреЗрдирдпреВрдЖрдИ / рд╡реЙрд▓реНрдпреВрдо рдХреЗ рд╕рдмрдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рддреЛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреА рдЕрд▓рдЧ-рдЕрд▓рдЧ рдореЛрдб рдореЗрдВ рдЕрдкрдиреА рднрд┐рдиреНрдирддрд╛ рд╣реИред


рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдХрд╣рд╛ рд╣реИ рдХрд┐ SystemUI рд╕реЗрд╡рд╛рдПрдВ рд╕реНрдЯрд╛рд░реНрдЯ () рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд╢реБрд░реВ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдпрджрд┐ рд╣рдо рд╡реЙрд▓реНрдпреВрдордпреВрдЖрдИ рд╡рд░реНрдЧ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ , рддреЛ рдпрд╣ рд╕рд┐рд╕реНрдЯрдордпреВрдЖрдИ рд╕реЗ рднреА рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред

 public class VolumeUI extends SystemUI { private static final String TAG = "VolumeUI"; private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG); private final Handler mHandler = new Handler(); private boolean mEnabled; private VolumeDialogComponent mVolumeComponent; @Override public void start() { boolean enableVolumeUi = mContext.getResources().getBoolean(R.bool.enable_volume_ui); boolean enableSafetyWarning = mContext.getResources().getBoolean(R.bool.enable_safety_warning); mEnabled = enableVolumeUi || enableSafetyWarning; if (!mEnabled) return; mVolumeComponent = new VolumeDialogComponent(this, mContext, null); mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning); putComponent(VolumeComponent.class, getVolumeComponent()); setDefaultVolumeController(); } тАж 

рдпрд╣рд╛рдВ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ mEnabled рдХреЗ рд╕рд╛рде рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдзреНрд╡рдирд┐ рд╕реЗрдЯрд┐рдВрдЧ рд╡рд╛рд▓рд╛ рдкреИрдирд▓ рджрд┐рдЦрд╛рдирд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдФрд░ VolumeDialogComponent рджреНрд╡рд╛рд░рд╛ рджреЗрдЦрддреЗ рд╣реБрдП, VolumeUI рд╕рд╛рдЙрдВрдбрдмрд╛рд░ рдХреЛ рдПрдХ рд╕рдВрд╡рд╛рдж рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╡реЙрд▓реНрдпреВрдо рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рджрдмрд╛рдиреЗ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рд╕рднреА рдХреНрд░рд┐рдпрд╛рдПрдВ рдлреЛрдирд╡рд┐рдВрдбреЛ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ ред

  protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) { ... switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_MUTE: { // If we have a session send it the volume command, otherwise // use the suggested stream. if (mMediaController != null) { mMediaController.dispatchVolumeButtonEventAsSystemService(event); } else { getMediaSessionManager().dispatchVolumeKeyEventAsSystemService(event, mVolumeControlStreamType); } return true; } ... protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event) { final KeyEvent.DispatcherState dispatcher = mDecor != null ? mDecor.getKeyDispatcherState() : null; if (dispatcher != null) { dispatcher.handleUpEvent(event); } //Log.i(TAG, "Key up: repeat=" + event.getRepeatCount() // + " flags=0x" + Integer.toHexString(event.getFlags())); switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: { // If we have a session send it the volume command, otherwise // use the suggested stream. if (mMediaController != null) { mMediaController.dispatchVolumeButtonEventAsSystemService(event); } else { getMediaSessionManager().dispatchVolumeKeyEventAsSystemService( event, mVolumeControlStreamType); } return true; } тАж 

рдЬрд╣рд╛рдБ рддрдХ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, KEYCODE_VOLUME_UP (+) рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реИ рдФрд░ KEYCODE_VOLUME_DOWN (-) рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЬрд╛рдПрдЧрд╛ред рджреЛрдиреЛрдВ рдШрдЯрдирд╛рдУрдВ рдореЗрдВ, onKeyDown рдФрд░ onKeyUp рджреЛрдиреЛрдВ рдкрд░, рдбрд┐рд╕реНрдкреИрдЪрд╡реЙрд▓реНрдордмреВрдЯрдирдПрд╡реЗрдВрдЯрдПрд╡реЗрдВрдЯрд╕рд┐рд╕реНрдЯрдореНрд╕ рд╕рд░реНрд╡рд┐рд╕ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

  public void dispatchVolumeButtonEventAsSystemService(@NonNull KeyEvent keyEvent) { switch (keyEvent.getAction()) { case KeyEvent.ACTION_DOWN: { int direction = 0; switch (keyEvent.getKeyCode()) { case KeyEvent.KEYCODE_VOLUME_UP: direction = AudioManager.ADJUST_RAISE; break; ... mSessionBinder.adjustVolume(mContext.getPackageName(), mCbStub, true, direction, ... } 

рдЗрд╕рд▓рд┐рдП, рдпрд╣рд╛рдВ рд╣рдо рдПрдбрдЬрд╕реНрдЯрд╡реЛрд▓реНрдпреВрдо рд╡рд┐рдзрд┐ рдХрд╣рддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рд╣рдо рдЕрдкрдиреА рджрд┐рд╢рд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХреЗрдВ рдХрд┐ рдХреМрди рд╕рд╛ рдЗрд╡реЗрдВрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реМрдВрдкрд╛ рдЬрд╛рдПрдЧрд╛ред

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЬрдм рд╣рдо AudioService рдореЗрдВ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ , рдЬрд╣рд╛рдВ sendVolumeUpdate рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд╣рд╛рдВ рдкреЛрд╕реНрдЯрд╡реЙрд▓реНрдпреВрдордЪреЗрдВрдЬ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдЪрдбреАрдПрдордЖрдИ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

  // UI update and Broadcast Intent protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) { ... mVolumeController.postVolumeChanged(streamType, flags); } private int updateFlagsForSystemAudio(int flags) { ... if (mHdmiSystemAudioSupported && ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) { flags &= ~AudioManager.FLAG_SHOW_UI; } ... } return flags; } public void postVolumeChanged(int streamType, int flags) { ... mController.volumeChanged(streamType, flags); ... } 

RingtonePlayer


Android рдореЗрдВ RingtonePlayer рдПрдХ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рдпрд╣ SystemUI рд╕реЗ рднреА рдЖрд░рдВрдн рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреНрд░рд╛рд░рдВрдн () рд╡рд┐рдзрд┐ рдореЗрдВ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ:

  @Override public void start() { ... mAudioService.setRingtonePlayer(mCallback); ... } 

рдпрд╣рд╛рдВ рд╣рдо mCallback рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ IRingtonePlayer рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред

 private IRingtonePlayer mCallback = new IRingtonePlayer.Stub() { @Override public void play(IBinder token, Uri uri, AudioAttributes aa, float volume, boolean looping) throws RemoteException { ... } @Override public void stop(IBinder token) { ... } @Override public boolean isPlaying(IBinder token) { ... } @Override public void setPlaybackProperties(IBinder token, float volume, boolean looping) { ... } @Override public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) { ... } @Override public void stopAsync() { ... } @Override public String getTitle(Uri uri) { ... } @Override public ParcelFileDescriptor openRingtone(Uri uri) { ... } }; 

рдЕрдВрдд рдореЗрдВ, рдЖрдк рдзреНрд╡рдирд┐ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП Binder рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ RingtonePlayerService рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

PowerUI


рдкрд╛рд╡рд░ рдкреНрд░рдмрдВрдзрди рдФрд░ рд╕реВрдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкрд╛рд╡рд░рдпреВрдЖрдИ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрд╣ рдЗрд╕реА рддрд░рд╣ SystemUI рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рд╕реНрдЯрд╛рд░реНрдЯ () рд╡рд┐рдзрд┐ рд╣реИред

 public void start() { mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mHardwarePropertiesManager = (HardwarePropertiesManager) mContext.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE); mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime(); mWarnings = Dependency.get(WarningsUI.class); mEnhancedEstimates = Dependency.get(EnhancedEstimates.class); mLastConfiguration.setTo(mContext.getResources().getConfiguration()); ContentObserver obs = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { updateBatteryWarningLevels(); } }; final ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, obs, UserHandle.USER_ALL); updateBatteryWarningLevels(); mReceiver.init(); showThermalShutdownDialog(); initTemperatureWarning(); } 

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL рдкрд░рд┐рд╡рд░реНрддрди рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдм рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдФрд░ рдлрд┐рд░ mReceiver.init () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

  public void init() { // Register for Intent broadcasts for... IntentFilter filter = new IntentFilter(); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(this, filter, null, mHandler); } 

рдпрд╣рд╛рдВ рдкреНрд░рд╕рд╛рд░рдг рд░рд┐рд╕реАрд╡рд░ рдкрдВрдЬреАрдХреГрдд рд╣реИ, рдЬрд┐рд╕рдХреА рдорджрдж рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрди рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреА рдЬрд╛рддреА рд╣реИред

рдХрд╛рд░реНрдп


Recents Android рдореЛрдмрд╛рдЗрд▓ рдЙрдкрдХрд░рдгреЛрдВ рдореЗрдВ рдПрдХ рдкреНрд░рд╛рдердорд┐рдХ рдФрд░ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕реБрд╡рд┐рдзрд╛ рд╣реИред

рдореБрдЦреНрдп рдХрд╛рд░реНрдп:


  • рд╕рднреА рдХрд╛рд░реНрдп рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ
  • рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВ
  • рдХрд╛рд░реНрдп рд╣рдЯрд╛рдирд╛


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, Recents рднреА SystemUI рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИред RecentsActivity рдирд╡реАрдирддрдо рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреА рд╕реНрдХреНрд░реАрди рдкрд░ рджреЗрдЦ рд╕рдХреЗрдВред


рдФрд░ рд╣рд╛рд▓ рд╣реА рдХреЗ рдЗрдирдЯреИрд╕реНрдХрдлреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдо рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 public static class RecentTaskInfo implements Parcelable { public int id; public int persistentId; public Intent baseIntent; public ComponentName origActivity; public ComponentName realActivity; public CharSequence description; public int stackId; ... 

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд░рдирд┐рдВрдЧ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╡рд┐рд╖рдп рдореЗрдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рд╕рднреА рдкрдХреНрд╖реЛрдВ рд╕реЗ рдЗрд╕рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкреГрд╖реНрдарднреВрдорд┐ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдХреНрд░реАрди рдХреЛ рдзреБрдВрдзрд▓рд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рддрд╛рдХрд┐ рд╕реНрдиреИрдкрд╢реЙрдЯ рдХрд╛ рдПрдХ рдЕрдкрдардиреАрдп рд╕рдВрд╕реНрдХрд░рдг RecentsTask рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрд╡реЗрджрди рд╕реНрдиреИрдкрд╢реЙрдЯ onPause () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рд╕реЗ рдкрд╣рд▓реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХрдИ рддрд░реАрдХреЛрдВ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╛ рдЭрдВрдбрд╛ рд╕реЗрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреЗрд╡рд▓ рд╕реНрдХреНрд░реАрди рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЫрд┐рдкрд╛рдП

 getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); 

рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рд╕рд┐рд░реНрдл рд╕реНрдиреИрдкрд╢реЙрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА рдереАред

рдЖрдк рдЖрдо рддреМрд░ рдкрд░ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрд╡реЗрджрди рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЧрддрд┐рд╡рд┐рдзрд┐ рдкреНрд░рдХрдЯ рдореЗрдВ рдиреАрдЪреЗ рд░рдЦрдХрд░ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ

 android:excludeFromRecents = "true" 

рдпрд╛ рдЖрдк рдХреЗ рд╕рд╛рде рдЪрд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

 Intent.FLAG_ACTIVITY_MULTIPLE_TASK 

рдЖрдк рдзреНрд╡рдЬ рдХреЗ рдКрдкрд░ рдореБрдЦреНрдп рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдмрд╛рд╣рд░ рдХрд░реЗрдВ = рд╕рдЪ , рддрд╛рдХрд┐ рдЗрд╕рдХреА рд╕реНрдХреНрд░реАрди рдЪрд▓ рд░рд╣реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рди рд╣реЛ, рд▓реЗрдХрд┐рди рдЬрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрд▓рдЧ рдХрд╛рд░реНрдп рдЪрд▓рд╛рдПрдВ рдЬреЛ рдореБрдЦреНрдп рдЧрддрд┐рд╡рд┐рдзрд┐ рд╕реЗ рдпрд╛ рддреЛ рдзреБрдВрдзрд▓реА рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ, рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдЫрд╡рд┐ рдХреЛ рджрд┐рдЦрд╛рдПрдЧрд╛ред рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ, рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╣ Google рдбрд┐рд╕реНрдХ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИред

рд▓реЙрдХ рд╕реНрдХреНрд░реАрди


рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдореЙрдбреНрдпреВрд▓ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреАрдЧрд╛рд░реНрдб рдкрд╣рд▓реЗ рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдпрд╣ рдПрдХ рдРрд╕реА рд╕реЗрд╡рд╛ рд╣реИ рдЬреЛ SystemUI рдореЗрдВ рдЪрд▓рддреА рд╣реИ, рдФрд░ KeyguardViewMediator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред

 private void setupLocked() { ... // Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard // is disabled. if (mContext.getResources().getBoolean( com.android.keyguard.R.bool.config_enableKeyguardService)) { setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser()), mAodShowing, mSecondaryDisplayShowing, true /* forceCallbacks */); } else { // The system's keyguard is disabled or missing. setShowingLocked(false, mAodShowing, mSecondaryDisplayShowing, true); } ... mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0); String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND); if (soundPath != null) { mLockSoundId = mLockSounds.load(soundPath, 1); } ... int lockSoundDefaultAttenuation = mContext.getResources().getInteger( com.android.internal.R.integer.config_lockSoundVolumeDb); mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20); ... } 

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, KeyguardService рд▓реЙрдХ рд╕реНрдХреНрд░реАрди рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд╕рд╛рде рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рд╕реНрдЯреЗрдЯрд╕рдмрд╛рд░ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЬрд╛рдирдХрд╛рд░реА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд╕реНрдХреНрд░реАрди рдХреЗ рджреГрд╢реНрдп рд╕реНрд╡рд░реВрдк рдФрд░ рд╕реВрдЪрдирд╛ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЬрд╛рддреА рд╣реИред

рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдмрд╛рд░


SystemBars рдореЗрдВ рдПрдХ рдЬрдЯрд┐рд▓ рдЙрдкрдХрд░рдг рдФрд░ рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИред рдЙрдирдХрд╛ рдХрд╛рдо рджреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИ:
  1. рд╕рд┐рд╕реНрдЯрдордмрд╛рд░реНрд╕ рдХреА рд╢реБрд░реБрдЖрдд
  2. рд╕реВрдЪрдирд╛рдПрдБ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ

рдЕрдЧрд░ рдЖрдк SystemBars рдХреЗ рд▓реЙрдиреНрдЪ рдХреЛ рджреЗрдЦреЗрдВ

 private void createStatusBarFromConfig() { ... final String clsName = mContext.getString(R.string.config_statusBarComponent); ... cls = mContext.getClassLoader().loadClass(clsName); ... mStatusBar = (SystemUI) cls.newInstance(); ... } 

рдлрд┐рд░ рд╣рдо рдЙрд╕ рд╕рдВрд╕рд╛рдзрди рдХрд╛ рд▓рд┐рдВрдХ рджреЗрдЦрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдХрдХреНрд╖рд╛ рдХрд╛ рдирд╛рдо рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

 <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string> 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ StatusBar рдпрд╣рд╛рдБ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╕реВрдЪрдирд╛ рдФрд░ UI рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рд╕рдВрджреЗрд╣ рдирд╣реАрдВ рдерд╛ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЯреНрд░рд┐рдХреНрд╕ рд╣реИрдВ рдЬреЛ рдХреЛрдб рдХреА рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВред SystemUI рдЗрд╕ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдФрд░ рдореБрдЭреЗ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдиреЗ рдореЗрдВ рдмрд╣реБрдд рдордЬрд╝рд╛ рдЖрдпрд╛ред рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдмрд╣реБрдд рдХрдо рд╕рд╛рдордЧреНрд░реА рд╣реИ, рдпрджрд┐ рдЖрдкрдХреЛ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рд╕реБрдзрд╛рд░реЗрдВред

PS рдореИрдВ рд╣рдореЗрд╢рд╛ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдореЗрдВ @paradisecurity рдкрд░ рд╕рд╛рдордЧреНрд░реА рдФрд░ рдЫреЛрдЯреЗ рд▓реЗрдЦреЛрдВ рдХреЗ рдЪрдпрди рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддрд╛ рд╣реВрдВред

Source: https://habr.com/ru/post/hi433620/


All Articles