16

Background

Somehow the app "Navbar Apps" allows to customize the background of the nav bar, even if it's not in the foreground, and even not just a simple color.

enter image description here

The problem

I thought it's only possible to change the color of it, and only when the app is in the foreground...

I've seen it on some custom roms, even having special effects when music plays, but I didn't know it's possible to customize it even without a custom rom (or root).

The questions

  1. Is it a hack? How do they change, not just the color of the navigation bar, but even set a background image for it (including dynamic one, for battery status) ?

  2. Is it also possible to change other system bars, like the notification bar?

  3. How does it check which app is in the foreground (needed for deciding when to change the color, based on current app, probably)? Is it a new API ? I thought that the API for getting the foreground activity got deprecated and now doesn't help in any way...

android developer
  • 114,585
  • 152
  • 739
  • 1,270

1 Answers1

8

The basic setup is quite easy. Making it into an app will take some work.

You'll need to use the Accessibility APIs, along with WindowManager#addView(...).

Is it a hack?

I can't say I like the idea, but its not exactly a hack.

How do they change, not just the color of the navigation bar, but even set a background image for it (including dynamic one, for battery status) ?

Since we're adding a View (or ViewGroup), we have a lot more control.

Is it also possible to change other system bars, like the notification bar?

I'll look into this.

How does it check which app is in the foreground (needed for deciding when to change the color, based on current app, probably)?

You can use Accessibility APIs to listen for Window level changes (AccessibilityEvent) - this will give you the packageName. Use it as you like.

I'll provide you with some pointers:

Manifest:

  • permission: SYSTEM_ALERT_WINDOW
  • accessibility service declaration: <service />

Accessibilityservice

  • Inflate, initialize & add your layout in: onServiceConnected()
  • I used TYPE_SYSTEM_OVERLAY with WindowManager#addView(...)
  • Listen for AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
  • Override onAccessibilityEvent(AccessibilityEvent); packageName will be available here

Outcome

enter image description here

An example project is hosted here: Link.

Vikram
  • 51,313
  • 11
  • 93
  • 122
  • Where did you add the view? Is it like the on-top samples that use SYSTEM_ALERT_WINDOW? Like the chatheads tutorials (here for example: http://www.piwai.info/chatheads-basics/ ) . As I remember, views cannot enter the nav-bar. How did you put it there? Also, isn't it important to keep the service alive (make it foreground), so that the view won't disappear (as the service might get killed) ? – android developer Oct 07 '16 at 22:33
  • Please show the code to put the view. I also don't get how you know where and when to put it, as the nav bar can be hidden on some cases, and orientation mode can also affect it (different on tablets for example) – android developer Oct 08 '16 at 13:50
  • 2
    @androiddeveloper Yes, the solution uses `SYSTEM_ALERT_WINDOW`. Using `FLAG_LAYOUT_NO_LIMITS` along with `Gravity.BOTTOM`, you can position the view anywhere on the screen. An `AccessibilityService` is managed by the system, and __enabled/disabled__ by the user. In other words, you (as a developer) won't start/stop the service. – Vikram Oct 08 '16 at 18:04
  • 2
    @androiddeveloper This is only a proof of concept. There are some flaky APIs that tell you if the nav-bar is present on the device -.see [this](http://stackoverflow.com/questions/16092431/check-for-navigation-bar). Orientation of the nav-bar - see [this](http://stackoverflow.com/questions/21057035/detect-android-navigation-bar-orientation). This is only my opinion - but with these kind of apps, you design for the common case, and improve your code as an when bugs are reported. This is evident from `NavBar Apps'` reviews & Google+ page. – Vikram Oct 08 '16 at 18:13
  • 1
    I see. So you say it probably has a lot of workarounds so that it can know when to put the special on-top view and how. Can you please show the code to put the on-top view with the new flags? – android developer Oct 09 '16 at 07:52
  • Thank you ! A small github project of what you wrote is also nice :) – android developer Oct 12 '16 at 20:59
  • 1
    You can look at the project here: [Link](https://github.com/vikramkakkar/SublimeNavBar). – Vikram Oct 14 '16 at 04:30
  • How cool! Can you please show the relevant code here? Also, what do you think are the workarounds the mentioned app uses for putting the fake nav-bar on the right time, in the right place ? – android developer Oct 14 '16 at 05:46