[Guide] How to add a Settings Observer to your Rom

Search This thread

tdunham

Recognized Contributor
Jun 21, 2008
13,686
36,462
TampaBay
[Guide] How to add a SettingsObserver to your Rom


This will allow you to add a settings observer to existing smali.
Adding a settings observer allows you to create a real-time update to an existing mod such as colors and toggles so the modification takes effect instantly without any other user intervention such as reboots, etc.

Huge credits @remuntada for all the information included in this guide.

Probably the most utilized settings observer is present for the PhoneStatusBar.smali in SystemUI.apk so we will provide this as an example:

Also see here for example of how to add a RegObserver to QSPanel
RegObserver Guide


SettingsObserver Guide
SystemUI.apk smali edits:
\smali\com\android\systemui\statusbar\phone\PhoneStatusBar.smali
New code is in BLUE
Code:
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$PmsBrightnessEnableObserver;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EasyModeEnableObserver;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BrightnessEnableObserver;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BatteryTextObserver;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$DozeServiceHost;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$ShadeUpdates;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$FastColorDrawable;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyTicker;,
        [COLOR="Blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;,[/COLOR]
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EmergencyModeObserver;,
            }
.end annotation
Same smali, add new code in BLUE
The edit is about halfway into the smali. Make sure the values of the new code match the surrounding values. Note that after that :cond_0 there may be additional code in your smali. Just insert the new code where indicated.
Code:
.method public start()V
.
.
.
    :cond_0[COLOR="Blue"]
    new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;

    iget-object v1, p0, Lcom/android/systemui/statusbar/BaseStatusBar;->mHandler:Lcom/android/systemui/statusbar/BaseStatusBar$H;

    invoke-direct {v0, p0, v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;-><init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V

    invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->observe()V[/COLOR]

    new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;

    iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    iget-object v2, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mCastController:Lcom/android/systemui/statusbar/policy/CastControllerImpl;

    invoke-direct {v0, v1, v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;-><init>(Landroid/content/Context;Lcom/android/systemui/statusbar/policy/CastController;)V

    iput-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mIconPolicy:Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;
Same smali, add YOUR new method.
This is just an example method of a mod I added to change the dateview color that gets invoked from the SettingsObserver:
Code:
.method setDateTextViewColor()V
    .locals 8

    iget-object v1, p0, Lcom/android/systemui/SystemUI;->mContext:Landroid/content/Context;

    invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v2

    const-string v3, "pulldown_date_color"

    const v1, -0x111112

    invoke-static {v2, v3, v1}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v7

    iget-object v5, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarWindow:Lcom/android/systemui/statusbar/phone/StatusBarWindowView;

    const v6, 0x7f0d02b8  ## [COLOR="Green"]<public type="id" name="date_expanded"
[/COLOR]
    invoke-virtual {v5, v6}, Lcom/android/systemui/statusbar/phone/StatusBarWindowView;->findViewById(I)Landroid/view/View;

    move-result-object v4

    check-cast v4, Landroid/widget/TextView;

    invoke-virtual {v4, v7}, Landroid/widget/TextView;->setTextColor(I)V

    return-void
.end method

Add the PhoneStatusBar$SettingsObserver.smali file already attached at the bottom of this post to the same folder as PhoneStatusBar.smali.
Now lets look in the PhoneStatusBar$SettingsObserver.smali to see how we made the changes to it.
Note the text in BLUE, this where we check for changes to the key string and in the second method is where the new method gets launched to update the view if changes have been detected to that key.
Note the text in GREEN, this is how you would add two more mods to the settings observer with two additional methods to invoke in PhoneStatusBar. They are only present as an example.
Code:
.class Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
.super Landroid/database/ContentObserver;
.source "PhoneStatusBar.java"


# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = "SettingsObserver"
.end annotation


# instance fields
.field final synthetic this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;


# direct methods
.method constructor <init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
    .locals 0

    iput-object p1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;

    invoke-direct {p0, p2}, Landroid/database/ContentObserver;-><init>(Landroid/os/Handler;)V

    return-void
.end method


# virtual methods
.method observe()V
    .locals 3

    const/4 v2, 0x0

    iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;

    iget-object v1, v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v0

    [COLOR="Blue"]const-string v1, "pulldown_date_color"

    invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v1

    invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver[/COLOR](Landroid/net/Uri;ZLandroid/database/ContentObserver;)V

    [COLOR="Green"]const-string v1, "second_settings_key_goes_here"

    invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v1

    invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
	
    const-string v1, "third_settings_key_goes_here"

    invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v1

    invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V[/COLOR]

    return-void
.end method

.method public onChange(Z)V
    .locals 1

   [COLOR="Blue"] iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;

    invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setDateTextViewColor()V
[/COLOR]
    [COLOR="Green"]iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;

    invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setSecondMethod()V

    iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;

    invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setThirdMethod()V

[/COLOR]    return-void
.end method


Modifying and adding a Settings Observer to most other smalis:


For smali where #annotations does not exist, add a new one right below the .source line like in this example. If #annotations already exist, add the line to #annotations as in the PhoneStatusBar.smali example above.
Note the highlighted text in RED, this path must match the smali you are working in (the green highlighted path).
Code:
.class public [COLOR="Green"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];
.super Landroid/widget/LinearLayout;
.source "DialpadView.java"

[COLOR="Blue"]# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        [COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
    }
.end annotation[/COLOR]
Search for either one of these methods:
Code:
.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
And add the new code in BLUE (and Red) before the return-void at the end of the method.
Note that the paths in RED have to match the smali you're working in.
Note that I had to increase the .locals value to accommodate the new entry which I did in this example.
Code:
.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
    [COLOR="Blue"].locals 3[/COLOR]

    const/4 v0, 0x0

    invoke-direct {p0, p1, p2, v0}, Lcom/android/incallui/dialpad/DialpadView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V

    [COLOR="blue"]new-instance v1, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;

    new-instance v2, Landroid/os/Handler;

    invoke-direct {v2}, Landroid/os/Handler;-><init>()V

    invoke-direct {v1, p0, v2}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;-><init>([COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];Landroid/os/Handler;)V

    invoke-virtual {v1}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;->observe()V
[/COLOR]
    return-void
.end method
Important note:
Wouldn't you know it, the smali I chose to use as an example does not support mcontext so I used getContext here and in the attached DateView$SettingsObserver.smali
After the last .method public constructor method (or with the rest of the access$xxx methods, if they exist) insert this method.
Note the path highlighted in RED must match the smali you are working with.
Code:
.method static synthetic access$001([COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];)Landroid/content/Context;
    .locals 1

    invoke-virtual {p0}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];->getContext()Landroid/content/Context;

    move-result-object v0

    return-object v0
.end method
Important note:
Use this one instead if your smali DOES support mcontext:
Code:
.method static synthetic access$001([COLOR="red"]Lcom/android/keyguard/sec/SecKeyguardClockSingleView[/COLOR];)Landroid/content/Context;
    .locals 1

    iget-object v0, p0, [COLOR="red"]Lcom/android/keyguard/sec/SecKeyguardClockSingleView[/COLOR];->mContext:Landroid/content/Context;

    return-object v0
.end method

How to create a new YourFile$SettingsObserver

I don't recommend using
PhoneStatusBar$SettingsObserver.smali or DateView$SettingsObserver.smali
as your templates. The first is specifically for PhoneStatusBar.smali and use DateView$SettingsObserver.smali if your smali does not support mcontext.

Using one of the attached $SettingsObserver files as a template, do the following edits throughout the ENTIRE $SettingsObserver.smali (only highlighting first few lines for brevity).
Find and replace all 14 of the paths to correspond with the smali you are working in.
The .source line is the smali name only. Change this to match the smali you are working in also.
The completed SettingsObserver.smali gets placed in the same folder as the parent smali we are working with.
Code:
.class public [COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
.super Landroid/database/ContentObserver;
.source "[COLOR="red"]DialpadView[/COLOR].java"

SettingsObserver example files have been attached to this post.

** some MM guide discussions begin here: http://forum.xda-developers.com/showpost.php?p=66480317&postcount=70
 

Attachments

  • Settings_Observer_examples.zip
    6 KB · Views: 1,472
Last edited:

aceqott

Senior Member
Mar 6, 2013
266
252
CA
How would it be to change in real time with this guide ?: [How-to Guide] Colorize main dialpad Android letters & digits L

Do I have to create the settings observer?
 

aceqott

Senior Member
Mar 6, 2013
266
252
CA
Add the smali DateView$SettingsObserver to smali/com/android/dialer/dialpad and change all the routes to which it belongs.

Changing the .class public.

Should I do anything else?
 

tdunham

Recognized Contributor
Jun 21, 2008
13,686
36,462
TampaBay
Add the smali DateView$SettingsObserver to smali/com/android/dialer/dialpad and change all the routes to which it belongs.

Changing the .class public.

Should I do anything else?
Its going to be pretty tough to add an observer to SecContacts, they chose to use letters for every single method so its going to be difficult to figure out where to place anything.
I'll look at it when I can but its probably not going to happen right away and like I said, I'm not having the dialpad color not changing instantly even without an observer so it is hard to tell if it will even work if I do find something.
 

aceqott

Senior Member
Mar 6, 2013
266
252
CA
Its going to be pretty tough to add an observer to SecContacts, they chose to use letters for every single method so its going to be difficult to figure out where to place anything.
I'll look at it when I can but its probably not going to happen right away and like I said, I'm not having the dialpad color not changing instantly even without an observer so it is hard to tell if it will even work if I do find something.

Well, too bad, anyway I do not understand, I have seen now a video of other ROMs where if the digit is changed and letters SecContact real time.
 

Kamy

Senior Member
Aug 29, 2012
5,335
19,304
Beijing
OK for start, I am asking to see whether if in theory I am understanding it correctly or not.
I am trying adding a new observe for battery color as once shared by @remuntada78.

I added this in my settings observer

Code:
    const-string v1, "battery_color"

    invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v1

    invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V


and

Code:
     iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/BatteryMeterView;

    invoke-virtual {v0}, Lcom/android/systemui/BatteryMeterView;->setBatteryColor()V


and then in

BatteryMeterView.smali


Code:
.class public Lcom/android/systemui/BatteryMeterView;
.super Landroid/view/View;
.source "BatteryMeterView.java"

# interfaces
.implements Lcom/android/systemui/DemoMode;
.implements Lcom/android/systemui/statusbar/policy/BatteryController$BatteryStateChangeCallback;


# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
	[COLOR="Red"]    Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;,[/COLOR]
        Lcom/android/systemui/BatteryMeterView$BatteryTracker;
    }
.end annotation


in the same smali:

Code:
.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
    .locals [COLOR="red"]2[/COLOR]

    const/4 v0, 0x0

    invoke-direct {p0, p1, p2, v0}, Lcom/android/systemui/BatteryMeterView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
	
[COLOR="red"]	    new-instance v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;

    new-instance v2, Landroid/os/Handler;

    invoke-direct {v2}, Landroid/os/Handler;-><init>()V

    invoke-direct {v1, p0, v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;-><init>(Lcom/android/systemui/BatteryMeterView;Landroid/os/Handler;)V

    invoke-virtual {v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->observe()V[/COLOR]

    return-void
.end method


and as my smali does not support mcontext I added following method in red

Code:
.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V  [COLOR="SeaGreen"]#last public constructor[/COLOR]
.
.
.
.end method

.method static synthetic access$000(Lcom/android/systemui/BatteryMeterView;)Landroid/os/Handler;
    .locals 1

    iget-object v0, p0, Lcom/android/systemui/BatteryMeterView;->mPostInvalidateHandler:Landroid/os/Handler;

    return-object v0
.end method

[COLOR="red"].method static synthetic access$001(Lcom/android/systemui/BatteryMeterView;)Landroid/content/Context;
    .locals 1

    invoke-virtual {p0}, Lcom/android/systemui/BatteryMeterView;->getContext()Landroid/content/Context;

    move-result-object v0

    return-object v0
.end method[/COLOR]

And lastly have done those samli modification described here I don't try it.
 
Last edited:

daxgirl

Senior Member
Jun 30, 2012
4,047
9,169
Jerusalem
OK for start, I am asking to see whether if in theory I am understanding it correctly or not.
I am trying adding a new observe for battery color as once shared by @remuntada78.

I added this in my settings observer

Code:
    const-string v1, "battery_color"

    invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v1

    invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V


and

Code:
     iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/BatteryMeterView;

    invoke-virtual {v0}, Lcom/android/systemui/BatteryMeterView;->setBatteryColor()V


and then in

BatteryMeterView.smali


Code:
.class public Lcom/android/systemui/BatteryMeterView;
.super Landroid/view/View;
.source "BatteryMeterView.java"

# interfaces
.implements Lcom/android/systemui/DemoMode;
.implements Lcom/android/systemui/statusbar/policy/BatteryController$BatteryStateChangeCallback;


# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
[COLOR="Red"]    Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;,[/COLOR]
        Lcom/android/systemui/BatteryMeterView$BatteryTracker;
    }
.end annotation


in the same smali:

Code:
.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
    .locals [COLOR="red"]2[/COLOR]

    const/4 v0, 0x0

    invoke-direct {p0, p1, p2, v0}, Lcom/android/systemui/BatteryMeterView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V

[COLOR="red"]    new-instance v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;

    new-instance v2, Landroid/os/Handler;

    invoke-direct {v2}, Landroid/os/Handler;-><init>()V

    invoke-direct {v1, p0, v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;-><init>(Lcom/android/systemui/BatteryMeterView;Landroid/os/Handler;)V

    invoke-virtual {v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->observe()V[/COLOR]

    return-void
.end method


and as my smali does not support mcontext I added following method in red

Code:
.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V  [COLOR="SeaGreen"]#last public constructor[/COLOR]
.
.
.
.end method

.method static synthetic access$000(Lcom/android/systemui/BatteryMeterView;)Landroid/os/Handler;
    .locals 1

    iget-object v0, p0, Lcom/android/systemui/BatteryMeterView;->mPostInvalidateHandler:Landroid/os/Handler;

    return-object v0
.end method

[COLOR="red"].method static synthetic access$001(Lcom/android/systemui/BatteryMeterView;)Landroid/content/Context;
    .locals 1

    invoke-virtual {p0}, Lcom/android/systemui/BatteryMeterView;->getContext()Landroid/content/Context;

    move-result-object v0

    return-object v0
.end method[/COLOR]

And lastly have done those samli modification described here I don't try it.

Look at the red class declaration. You added observer class that belongs to a different class. You need an observer for this class. Not for PhoneStatusBar.smali

Sent from my awesome g920f powered by 6thGear
 

Kamy

Senior Member
Aug 29, 2012
5,335
19,304
Beijing
Look at the red class declaration. You added observer class that belongs to a different class. You need an observer for this class. Not for PhoneStatusBar.smali

Sent from my awesome g920f powered by 6thGear

You are saying I need another observer to create as BatteryMeterView$SettingsObserver.smali right?
 

daxgirl

Senior Member
Jun 30, 2012
4,047
9,169
Jerusalem

daxgirl

Senior Member
Jun 30, 2012
4,047
9,169
Jerusalem
@daxgirl
Looking for an alternate method to add an observer where one wouldn't normally work. No rush on this. :)
Lol... hi there. On this side "looking forward to finishing properly handling assets and scripts for the new custom settings app so I cac concentrate on other things" ;)
Just to clarify the thing...
We have built a settings app a while ago for ourselves. Since we both work with java, we don't need it to be as automated as ficeto's app is. So now the biggest challenge is to make it available for all, by providing a code that wouldn't require an entire forum on xda to couch devs to use it and minimize your exposure to java where possible. Our goal is to provide as clean code is possible, so minimal changes to code would be required to operate the app. That is because we understand that most devs have minimal skills when it comes to original development. We dont want to force people to build special conditions and make huge changes to the java part of the app. So the automating part... It's taking time.... :)

We have so far fully automated and integrative nav drawer, where items can be added easily with little guiding, theme change support, automated preference fragments, automated scripts execution from the app assets and automated preference handling from the get go, no matter how deep the preference tree goes (as many nesting preference screens as you want). Right now I am working on handling those things in separate classes, so the devs wouldn't need to copy huge chunks of code when they want to create another new preference fragment for their drawer.... and as much as it's fun, little time is left for anything else for now... :p

Sent from my awesome g920f powered by 6thGear
 

Top Liked Posts

  • There are no posts matching your filters.
  • 24
    [Guide] How to add a SettingsObserver to your Rom


    This will allow you to add a settings observer to existing smali.
    Adding a settings observer allows you to create a real-time update to an existing mod such as colors and toggles so the modification takes effect instantly without any other user intervention such as reboots, etc.

    Huge credits @remuntada for all the information included in this guide.

    Probably the most utilized settings observer is present for the PhoneStatusBar.smali in SystemUI.apk so we will provide this as an example:

    Also see here for example of how to add a RegObserver to QSPanel
    RegObserver Guide


    SettingsObserver Guide
    SystemUI.apk smali edits:
    \smali\com\android\systemui\statusbar\phone\PhoneStatusBar.smali
    New code is in BLUE
    Code:
    # annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$PmsBrightnessEnableObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EasyModeEnableObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BrightnessEnableObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BatteryTextObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$DozeServiceHost;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$ShadeUpdates;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$FastColorDrawable;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyTicker;,
            [COLOR="Blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;,[/COLOR]
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EmergencyModeObserver;,
                }
    .end annotation
    Same smali, add new code in BLUE
    The edit is about halfway into the smali. Make sure the values of the new code match the surrounding values. Note that after that :cond_0 there may be additional code in your smali. Just insert the new code where indicated.
    Code:
    .method public start()V
    .
    .
    .
        :cond_0[COLOR="Blue"]
        new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/BaseStatusBar;->mHandler:Lcom/android/systemui/statusbar/BaseStatusBar$H;
    
        invoke-direct {v0, p0, v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;-><init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->observe()V[/COLOR]
    
        new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        iget-object v2, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mCastController:Lcom/android/systemui/statusbar/policy/CastControllerImpl;
    
        invoke-direct {v0, v1, v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;-><init>(Landroid/content/Context;Lcom/android/systemui/statusbar/policy/CastController;)V
    
        iput-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mIconPolicy:Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;
    Same smali, add YOUR new method.
    This is just an example method of a mod I added to change the dateview color that gets invoked from the SettingsObserver:
    Code:
    .method setDateTextViewColor()V
        .locals 8
    
        iget-object v1, p0, Lcom/android/systemui/SystemUI;->mContext:Landroid/content/Context;
    
        invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v2
    
        const-string v3, "pulldown_date_color"
    
        const v1, -0x111112
    
        invoke-static {v2, v3, v1}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
    
        move-result v7
    
        iget-object v5, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarWindow:Lcom/android/systemui/statusbar/phone/StatusBarWindowView;
    
        const v6, 0x7f0d02b8  ## [COLOR="Green"]<public type="id" name="date_expanded"
    [/COLOR]
        invoke-virtual {v5, v6}, Lcom/android/systemui/statusbar/phone/StatusBarWindowView;->findViewById(I)Landroid/view/View;
    
        move-result-object v4
    
        check-cast v4, Landroid/widget/TextView;
    
        invoke-virtual {v4, v7}, Landroid/widget/TextView;->setTextColor(I)V
    
        return-void
    .end method

    Add the PhoneStatusBar$SettingsObserver.smali file already attached at the bottom of this post to the same folder as PhoneStatusBar.smali.
    Now lets look in the PhoneStatusBar$SettingsObserver.smali to see how we made the changes to it.
    Note the text in BLUE, this where we check for changes to the key string and in the second method is where the new method gets launched to update the view if changes have been detected to that key.
    Note the text in GREEN, this is how you would add two more mods to the settings observer with two additional methods to invoke in PhoneStatusBar. They are only present as an example.
    Code:
    .class Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
    .super Landroid/database/ContentObserver;
    .source "PhoneStatusBar.java"
    
    
    # annotations
    .annotation system Ldalvik/annotation/EnclosingClass;
        value = Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    .end annotation
    
    .annotation system Ldalvik/annotation/InnerClass;
        accessFlags = 0x0
        name = "SettingsObserver"
    .end annotation
    
    
    # instance fields
    .field final synthetic this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
    
    # direct methods
    .method constructor <init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
        .locals 0
    
        iput-object p1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-direct {p0, p2}, Landroid/database/ContentObserver;-><init>(Landroid/os/Handler;)V
    
        return-void
    .end method
    
    
    # virtual methods
    .method observe()V
        .locals 3
    
        const/4 v2, 0x0
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        iget-object v1, v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v0
    
        [COLOR="Blue"]const-string v1, "pulldown_date_color"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver[/COLOR](Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
    
        [COLOR="Green"]const-string v1, "second_settings_key_goes_here"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
    	
        const-string v1, "third_settings_key_goes_here"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V[/COLOR]
    
        return-void
    .end method
    
    .method public onChange(Z)V
        .locals 1
    
       [COLOR="Blue"] iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setDateTextViewColor()V
    [/COLOR]
        [COLOR="Green"]iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setSecondMethod()V
    
        iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setThirdMethod()V
    
    [/COLOR]    return-void
    .end method


    Modifying and adding a Settings Observer to most other smalis:


    For smali where #annotations does not exist, add a new one right below the .source line like in this example. If #annotations already exist, add the line to #annotations as in the PhoneStatusBar.smali example above.
    Note the highlighted text in RED, this path must match the smali you are working in (the green highlighted path).
    Code:
    .class public [COLOR="Green"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];
    .super Landroid/widget/LinearLayout;
    .source "DialpadView.java"
    
    [COLOR="Blue"]# annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            [COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
        }
    .end annotation[/COLOR]
    Search for either one of these methods:
    Code:
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
    
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
    And add the new code in BLUE (and Red) before the return-void at the end of the method.
    Note that the paths in RED have to match the smali you're working in.
    Note that I had to increase the .locals value to accommodate the new entry which I did in this example.
    Code:
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
        [COLOR="Blue"].locals 3[/COLOR]
    
        const/4 v0, 0x0
    
        invoke-direct {p0, p1, p2, v0}, Lcom/android/incallui/dialpad/DialpadView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
    
        [COLOR="blue"]new-instance v1, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
    
        new-instance v2, Landroid/os/Handler;
    
        invoke-direct {v2}, Landroid/os/Handler;-><init>()V
    
        invoke-direct {v1, p0, v2}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;-><init>([COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];Landroid/os/Handler;)V
    
        invoke-virtual {v1}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;->observe()V
    [/COLOR]
        return-void
    .end method
    Important note:
    Wouldn't you know it, the smali I chose to use as an example does not support mcontext so I used getContext here and in the attached DateView$SettingsObserver.smali
    After the last .method public constructor method (or with the rest of the access$xxx methods, if they exist) insert this method.
    Note the path highlighted in RED must match the smali you are working with.
    Code:
    .method static synthetic access$001([COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];)Landroid/content/Context;
        .locals 1
    
        invoke-virtual {p0}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];->getContext()Landroid/content/Context;
    
        move-result-object v0
    
        return-object v0
    .end method
    Important note:
    Use this one instead if your smali DOES support mcontext:
    Code:
    .method static synthetic access$001([COLOR="red"]Lcom/android/keyguard/sec/SecKeyguardClockSingleView[/COLOR];)Landroid/content/Context;
        .locals 1
    
        iget-object v0, p0, [COLOR="red"]Lcom/android/keyguard/sec/SecKeyguardClockSingleView[/COLOR];->mContext:Landroid/content/Context;
    
        return-object v0
    .end method

    How to create a new YourFile$SettingsObserver

    I don't recommend using
    PhoneStatusBar$SettingsObserver.smali or DateView$SettingsObserver.smali
    as your templates. The first is specifically for PhoneStatusBar.smali and use DateView$SettingsObserver.smali if your smali does not support mcontext.

    Using one of the attached $SettingsObserver files as a template, do the following edits throughout the ENTIRE $SettingsObserver.smali (only highlighting first few lines for brevity).
    Find and replace all 14 of the paths to correspond with the smali you are working in.
    The .source line is the smali name only. Change this to match the smali you are working in also.
    The completed SettingsObserver.smali gets placed in the same folder as the parent smali we are working with.
    Code:
    .class public [COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
    .super Landroid/database/ContentObserver;
    .source "[COLOR="red"]DialpadView[/COLOR].java"

    SettingsObserver example files have been attached to this post.

    ** some MM guide discussions begin here: http://forum.xda-developers.com/showpost.php?p=66480317&postcount=70
    9
    [Guide] How to add a SettingsObserver to your Rom


    This will allow you to add a settings observer to existing smali.
    Adding a settings observer allows you to create a real-time update to an existing mod such as colors and toggles so the modification takes effect instantly without any other user intervention such as reboots, etc.

    Huge credits @remuntada for all the information included in this guide.

    Probably the most utilized settings observer is present for the PhoneStatusBar.smali in SystemUI.apk so we will provide this as an example:

    SettingsObserver Guide
    SystemUI.apk smali edits:
    \smali\com\android\systemui\statusbar\phone\PhoneStatusBar.smali
    New code is in BLUE
    Code:
    # annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$PmsBrightnessEnableObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EasyModeEnableObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BrightnessEnableObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BatteryTextObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$DozeServiceHost;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$ShadeUpdates;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$FastColorDrawable;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyTicker;,
            [COLOR="Blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;,[/COLOR]
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EmergencyModeObserver;,
                }
    .end annotation
    Same smali, add new code in BLUE
    The edit is about halfway into the smali. Make sure the values of the new code match the surrounding values. Note that after that :cond_0 there may be additional code in your smali. Just insert the new code where indicated.
    Code:
    .method public start()V
    .
    .
    .
        :cond_0[COLOR="Blue"]
        new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/BaseStatusBar;->mHandler:Lcom/android/systemui/statusbar/BaseStatusBar$H;
    
        invoke-direct {v0, p0, v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;-><init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->observe()V[/COLOR]
    
        new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        iget-object v2, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mCastController:Lcom/android/systemui/statusbar/policy/CastControllerImpl;
    
        invoke-direct {v0, v1, v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;-><init>(Landroid/content/Context;Lcom/android/systemui/statusbar/policy/CastController;)V
    
        iput-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mIconPolicy:Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;
    Same smali, add YOUR new method.
    This is just an example method of a mod I added to change the dateview color that gets invoked from the SettingsObserver:
    Code:
    .method setDateTextViewColor()V
        .locals 8
    
        iget-object v1, p0, Lcom/android/systemui/SystemUI;->mContext:Landroid/content/Context;
    
        invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v2
    
        const-string v3, "pulldown_date_color"
    
        const v1, -0x111112
    
        invoke-static {v2, v3, v1}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
    
        move-result v7
    
        iget-object v5, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarWindow:Lcom/android/systemui/statusbar/phone/StatusBarWindowView;
    
        const v6, 0x7f0d02b8  ## [COLOR="Green"]<public type="id" name="date_expanded"
    [/COLOR]
        invoke-virtual {v5, v6}, Lcom/android/systemui/statusbar/phone/StatusBarWindowView;->findViewById(I)Landroid/view/View;
    
        move-result-object v4
    
        check-cast v4, Landroid/widget/TextView;
    
        invoke-virtual {v4, v7}, Landroid/widget/TextView;->setTextColor(I)V
    
        return-void
    .end method

    Add the PhoneStatusBar$SettingsObserver.smali file already attached at the bottom of this post to the same folder as PhoneStatusBar.smali.
    Now lets look in the PhoneStatusBar$SettingsObserver.smali to see how we made the changes to it.
    Note the text in BLUE, this where we check for changes to the key string and in the second method is where the new method gets launched to update the view if changes have been detected to that key.
    Note the text in GREEN, this is how you would add two more mods to the settings observer with two additional methods to invoke in PhoneStatusBar. They are only present as an example.
    Code:
    .class Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
    .super Landroid/database/ContentObserver;
    .source "PhoneStatusBar.java"
    
    
    # annotations
    .annotation system Ldalvik/annotation/EnclosingClass;
        value = Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    .end annotation
    
    .annotation system Ldalvik/annotation/InnerClass;
        accessFlags = 0x0
        name = "SettingsObserver"
    .end annotation
    
    
    # instance fields
    .field final synthetic this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
    
    # direct methods
    .method constructor <init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
        .locals 0
    
        iput-object p1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-direct {p0, p2}, Landroid/database/ContentObserver;-><init>(Landroid/os/Handler;)V
    
        return-void
    .end method
    
    
    # virtual methods
    .method observe()V
        .locals 3
    
        const/4 v2, 0x0
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        iget-object v1, v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v0
    
        [COLOR="Blue"]const-string v1, "pulldown_date_color"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver[/COLOR](Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
    
        [COLOR="Green"]const-string v1, "second_settings_key_goes_here"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
    	
        const-string v1, "third_settings_key_goes_here"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V[/COLOR]
    
        return-void
    .end method
    
    .method public onChange(Z)V
        .locals 1
    
       [COLOR="Blue"] iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setDateTextViewColor()V
    [/COLOR]
        [COLOR="Green"]iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setSecondMethod()V
    
        iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setThirdMethod()V
    
    [/COLOR]    return-void
    .end method


    Modifying and adding a Settings Observer to most other smalis:


    For smali where #annotations does not exist, add a new one right below the .source line like in this example. If #annotations already exist, add the line to #annotations as in the PhoneStatusBar.smali example above.
    Note the highlighted text in RED, this path must match the smali you are working in (the green highlighted path).
    Code:
    .class public [COLOR="Green"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];
    .super Landroid/widget/LinearLayout;
    .source "DialpadView.java"
    
    [COLOR="Blue"]# annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            [COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
        }
    .end annotation[/COLOR]
    Search for either one of these methods:
    Code:
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
    
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
    And add the new code in BLUE (and Red) before the return-void at the end of the method.
    Note that the paths in RED have to match the smali you're working in.
    Note that I had to increase the .locals value to accommodate the new entry which I did in this example.
    Code:
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
        [COLOR="Blue"].locals 3[/COLOR]
    
        const/4 v0, 0x0
    
        invoke-direct {p0, p1, p2, v0}, Lcom/android/incallui/dialpad/DialpadView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
    
        [COLOR="blue"]new-instance v1, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
    
        new-instance v2, Landroid/os/Handler;
    
        invoke-direct {v2}, Landroid/os/Handler;-><init>()V
    
        invoke-direct {v1, p0, v2}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;-><init>([COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];Landroid/os/Handler;)V
    
        invoke-virtual {v1}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;->observe()V
    [/COLOR]
        return-void
    .end method
    Important note:
    Wouldn't you know it, the smali I chose to use as an example does not support mcontext so I used getContext here and in the attached DateView$SettingsObserver.smali
    After the last .method public constructor method (or with the rest of the access$xxx methods, if they exist) insert this method.
    Note the path highlighted in RED must match the smali you are working with.
    Code:
    .method static synthetic access$001([COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];)Landroid/content/Context;
        .locals 1
    
        invoke-virtual {p0}, [COLOR="red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR];->getContext()Landroid/content/Context;
    
        move-result-object v0
    
        return-object v0
    .end method
    Important note:
    Use this one instead if your smali DOES support mcontext:
    Code:
    .method static synthetic access$001([COLOR="red"]Lcom/android/keyguard/sec/SecKeyguardClockSingleView[/COLOR];)Landroid/content/Context;
        .locals 1
    
        iget-object v0, p0, [COLOR="red"]Lcom/android/keyguard/sec/SecKeyguardClockSingleView[/COLOR];->mContext:Landroid/content/Context;
    
        return-object v0
    .end method

    How to create a new YourFile$SettingsObserver

    I don't recommend using
    PhoneStatusBar$SettingsObserver.smali or DateView$SettingsObserver.smali
    as your templates. The first is specifically for PhoneStatusBar.smali and use DateView$SettingsObserver.smali if your smali does not support mcontext.

    Using one of the attached $SettingsObserver files as a template, do the following edits throughout the ENTIRE $SettingsObserver.smali (only highlighting first few lines for brevity).
    Find and replace all 14 of the paths to correspond with the smali you are working in.
    The .source line is the smali name only. Change this to match the smali you are working in also.
    The completed SettingsObserver.smali gets placed in the same folder as the parent smali we are working with.
    Code:
    .class public [COLOR="Red"]Lcom/android/incallui/dialpad/DialpadView[/COLOR]$SettingsObserver;
    .super Landroid/database/ContentObserver;
    .source "[COLOR="red"]DialpadView[/COLOR].java"

    SettingsObserver example files have been attached to this post.

    UPDATED for Android Marshmallow 6.0.1
    How to add a SettingsObserver to your Rom Android Marshmallow 6.0.1
    in example PhoneStatusBar.smali
    SystemUI.apk smali edits:
    \smali\com\android\systemui\statusbar\phone\PhoneS tatusBar.smali
    add new code is in BLUE
    Code:
    # annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$QuickConnectSoundPathViewObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$ButtonBackgroundObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$EmergencyModeObserver;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$DozeServiceHost;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$ShadeUpdates;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;,
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BatteryTextObserver;[COLOR="blue"][B][SIZE="3"],[/SIZE][/B][/COLOR]
            [COLOR="blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;[/COLOR]
        }
    .end annotation
    Note that, do not forget to insert a symbol ( , ) at the end in string Lcom/android/systemui/statusbar/phone/PhoneStatusBar$BatteryTextObserver;

    Same smali, in .method public start()V add new code in BLUE
    Code:
    .method public start()V
    .
    .
    .
        iput-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mVowifiController:Lcom/android/systemui/statusbar/phone/VoWiFiStatusController;
    [COLOR="Blue"]
        :goto_0
        new-instance v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
    
        iget-object v2, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mHandler:Lcom/android/systemui/statusbar/BaseStatusBar$H;
    
        invoke-direct {v1, p0, v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;-><init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
    
        .local v1, "observer":Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
        invoke-virtual {v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->observe()V[/COLOR]
    
        new-instance v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBarPolicy;
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    .
    .
    .
        iput-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mScreenPinningRequest:Lcom/android/systemui/recents/ScreenPinningRequest;
    
        return-void
    
    [COLOR="Blue"]    .end local v1    # "observer":Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
        move-exception v2
    
        goto/16 :goto_0
    [/COLOR].end method

    Add the PhoneStatusBar$SettingsObserver.smali file already attached at the bottom of this post to the same folder as PhoneStatusBar.smali.

    Now lets look in the PhoneStatusBar$SettingsObserver.smali to see how we made the changes to it.
    Note the text in BLUE, this where we check for changes to the key string and in the second method is where the new method gets launched to update the view if changes have been detected to that key.
    Note the text in GREEN, this is how you would add two more mods to the settings observer with two additional methods to invoke in PhoneStatusBar. They are only present as an example.
    Code:
    .class Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;
    .super Landroid/database/ContentObserver;
    .source "PhoneStatusBar.java"
    
    
    # annotations
    .annotation system Ldalvik/annotation/EnclosingClass;
        value = Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    .end annotation
    
    .annotation system Ldalvik/annotation/InnerClass;
        accessFlags = 0x0
        name = "SettingsObserver"
    .end annotation
    
    
    # instance fields
    .field final synthetic this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
    
    # direct methods
    .method constructor <init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;)V
        .locals 0
    
        iput-object p1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-direct {p0, p2}, Landroid/database/ContentObserver;-><init>(Landroid/os/Handler;)V
    
        return-void
    .end method
    
    
    # virtual methods
    .method observe()V
        .locals 3
    
        const/4 v2, 0x0
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        iget-object v1, v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v0
    
        [COLOR="Blue"]const-string v1, "pulldown_date_color"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver[/COLOR](Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
    
        [COLOR="Green"]const-string v1, "second_settings_key_goes_here"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
    	
        const-string v1, "third_settings_key_goes_here"
    
        invoke-static {v1}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v1
    
        invoke-virtual {v0, v1, v2, p0}, Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V[/COLOR]
    
        return-void
    .end method
    
    .method public onChange(Z)V
        .locals 1
    
       [COLOR="Blue"] iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setDateTextViewColor()V
    [/COLOR]
        [COLOR="Green"]iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setSecondMethod()V
    
        iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$SettingsObserver;->this$0:Lcom/android/systemui/statusbar/phone/PhoneStatusBar;
    
        invoke-virtual {v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setThirdMethod()V
    
    [/COLOR]    return-void
    .end method
    6
    I am totally open to alternate methods and critique on improving on this folks so don't be shy with the input. :)
    4
    Are you??? :p tomorrow we will add our observer then ???
    Awesome! :D
    I am fairly new to adding observers but I thought it was necessary to start this discussion with the established method and work our way up from there.
Our Apps
Get our official app!
The best way to access XDA on your phone
Nav Gestures
Add swipe gestures to any Android
One Handed Mode
Eases uses one hand with your phone