[MOD][GUIDE]Enable Heads Up Notifications

231 posts
Thanks Meter: 816
 
By moonknightus, Senior Member on 10th September 2014, 04:01 PM
Post Reply Email Thread
This guide was written based on the Sprint Samsung Galaxy S3 ND8 KitKat stock ROM but with the proper modifications may work for other KitKat ROMs. Please don't ask me to modify this to work with ROM xyz or to compile this for you into a ROM. I won't do it.

Background Info
As you know, Android 4.4 has a heads-up notification feature built in but disabled with no way to enable it from settings. While there are various Xposed modules that will enable this for you as well as give some additional functionality (such as whitelisting), I personally don't use Xposed because it causes conflicts on my ROM so I decided to figure out how to enable it myself. Simply enabling Heads Up notifications caused all sorts of force closes any time an ongoing notification presented itself so that had to be worked out as well.

Requirements
  • apktool 2.0 beta 9 and the knowledge of how to use it. There are various guides on how to use apktool on XDA. Find one and read it. Make sure to read the information on the apktool site as well since some of the options in 2.0 may be different from the guides you find.
  • A text editor that supports Unix-style text files. I recommend Notepad++.

Files
You'll be working with the following apks:
  • SystemUI.apk
  • SecSettings.apk

SystemUI.apk
Decompile SystemUI.apk using apktool.

Open smali\com\android\systemui\statusbar\BaseStatusBar .smali in your preferred text editor.

Find .method protected shouldInterrupt(Landroid/service/notification/StatusBarNotification;)Z.

This method is of no use to us in it's current form and is what causes the force closes/ongoing notification issues so we are going to completely remove it and replace it with the following:
Code:
.method protected shouldInterrupt(Landroid/service/notification/StatusBarNotification;)Z
    .locals 12
    .param p1, "sbn"    # Landroid/service/notification/StatusBarNotification;

    .prologue
    const/4 v8, 0x0

    const/4 v9, 0x1

    .line 1292
    invoke-virtual {p1}, Landroid/service/notification/StatusBarNotification;->isOngoing()Z

    move-result v4

    if-nez v4, :cond_0

    iget-object v10, p0, Lcom/android/systemui/statusbar/BaseStatusBar;->mPowerManager:Landroid/os/PowerManager;

    invoke-virtual {v10}, Landroid/os/PowerManager;->isScreenOn()Z

    move-result v1

    :goto_0
    return v1

    :cond_0
    move v1, v8

    goto :goto_0
.end method
Save the file and recompile SystemUI using apktool. Don't forget to re-sign the APK (either use an APK signer if you have a ROM that has 3rd-party system app signatures enabled or copy the AndroidManifest.xml file and META-INF folder from the original to the new APK).

That's it for SystemUI.apk.


SecSettings.apk
Decompile SecSettings.apk with apktool.

First, we need to add the title and summary for the setting to enable Heads Up notifications. Open res\values\Strings.xml in your preferred text editor.

Add the following lines to the bottom of the file:
Code:
    <string name="heads_up">Heads up notifications</string>
    <string name="heads_up_desc">Enable heads up notifications</string>
Save the file and close it.

Next we need to add the setting entry. Open res\xml\display_settings.xml in your preferred text editor.

Add the following line underneath your preferred setting category (I chose to place it under "General" in my ROM):
Code:
<CheckBoxPreference android:title="@string/heads_up" android:key="heads_up_setting" android:widgetLayout="@touchwiz:layout/preference_widget_twcheckbox" />
Save the file and close it.

Finally, we will add the code to enable/disable Heads Up notifications. Open smali\com\android\settings\DisplaySettings.smali in your preferred text editor.

Find # instance fields and add the following line (on a new line) somewhere before # direct methods:

Code:
.field private mHeadsUp:Landroid/preference/CheckBoxPreference;
Find .method private updateState()V, then locate the section of code that looks similar to this:

Code:
    :cond_0
    invoke-direct {p0}, Lcom/android/settings/DisplaySettings;->updateInformativeScreenSummary()V

    .line 1374
    iget-object v3, p0, Lcom/android/settings/DisplaySettings;->mDisplayBatteryLevel:Landroid/preference/CheckBoxPreference;

    invoke-virtual {p0}, Lcom/android/settings/DisplaySettings;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v0

    const-string v4, "display_battery_percentage"

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

    move-result v0

    if-eqz v0, :cond_2

    move v0, v1

    :goto_0
    invoke-virtual {v3, v0}, Landroid/preference/CheckBoxPreference;->setChecked(Z)V
Your variables (v#'s), conditionals (cond_#'s), gotos (goto_#'s), and .line #'s may differ. Under the line invoke-virtual {v3, v0}, Landroid/preference/CheckBoxPreference;->setChecked(Z)V, add:

Code:
    iget-object v3, p0, Lcom/android/settings/DisplaySettings;->mHeadsUp:Landroid/preference/CheckBoxPreference;

    invoke-virtual {p0}, Lcom/android/settings/DisplaySettings;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v0

    const-string v4, "heads_up_enabled"

    invoke-static {v0, v4, v2}, Landroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v0

    if-eqz v0, :cond_8

    move v0, v1

    :goto_6
    invoke-virtual {v3, v0}, Landroid/preference/CheckBoxPreference;->setChecked(Z)V
You'll want to change the variables to match the ones in the prior code section if they are different for you. Also make sure to change the conditional and goto labels to one hexadecimal numeral higher than the highest one already present in the method (for example, in stock ND8, the highest conditional is cond_7 so we choose cond_8 for the conditional here and the highest goto is goto_5 so we chose goto_6).

Scroll down to the end of the method and add the following above .end method:

Code:
    :cond_8
    move v0, v2

    goto/16 :goto_6
Make sure to change v2 to whatever variable is defined at the beginning of the method as 0x0 (ie. const/4 v2, 0x0 in this case).

Find .method public onCreate(Landroid/os/Bundle;)V, then locate the section of code that looks similar to the following:

Code:
    const-string v0, "display_battery_level"

    invoke-virtual {p0, v0}, Lcom/android/settings/DisplaySettings;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

    move-result-object v0

    check-cast v0, Landroid/preference/CheckBoxPreference;

    iput-object v0, p0, Lcom/android/settings/DisplaySettings;->mDisplayBatteryLevel:Landroid/preference/CheckBoxPreference;
Again, your variables (v#'s) may differ. Beneath the line iput-object v0, p0, Lcom/android/settings/DisplaySettings;->mDisplayBatteryLevel:Landroid/preference/CheckBoxPreference;, add the following:

Code:
    const-string v0, "heads_up_setting"

    invoke-virtual {p0, v0}, Lcom/android/settings/DisplaySettings;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

    move-result-object v0

    check-cast v0, Landroid/preference/CheckBoxPreference;

    iput-object v0, p0, Lcom/android/settings/DisplaySettings;->mHeadsUp:Landroid/preference/CheckBoxPreference;
Make sure to change the variable #'s to match the ones in the prior code section.

Find .method public onPreferenceTreeClick(Landroid/preference/PreferenceScreen;Landroid/preference/Preference;)Z and locate the section of code that looks similar to:

Code:
    :cond_a
    iget-object v0, p0, Lcom/android/settings/DisplaySettings;->mDisplayBatteryLevel:Landroid/preference/CheckBoxPreference;

    invoke-virtual {p2, v0}, Ljava/lang/Object;->equals(Ljava/lang/Object;)Z

    move-result v0

    if-eqz v0, :cond_c

    .line 1530
    iget-object v0, p0, Lcom/android/settings/DisplaySettings;->mDisplayBatteryLevel:Landroid/preference/CheckBoxPreference;

    invoke-virtual {v0}, Landroid/preference/CheckBoxPreference;->isChecked()Z

    move-result v0

    .line 1531
    invoke-virtual {p0}, Lcom/android/settings/DisplaySettings;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v1

    const-string v4, "display_battery_percentage"

    if-eqz v0, :cond_b

    move v3, v2

    :cond_b
    invoke-static {v1, v4, v3}, Landroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z

    goto :goto_3

    .line 1533
    :cond_c
As usual, your variables (v#'s), conditionals (cond_#'s), gotos (goto_#'s), and .line #'s may differ. Under :cond_c, add the following:

Code:
    iget-object v0, p0, Lcom/android/settings/DisplaySettings;->mHeadsUp:Landroid/preference/CheckBoxPreference;

    invoke-virtual {p2, v0}, Ljava/lang/Object;->equals(Ljava/lang/Object;)Z

    move-result v0

    if-eqz v0, :cond_2b

    .line 1530
    iget-object v0, p0, Lcom/android/settings/DisplaySettings;->mHeadsUp:Landroid/preference/CheckBoxPreference;

    invoke-virtual {v0}, Landroid/preference/CheckBoxPreference;->isChecked()Z

    move-result v0

    .line 1531
    invoke-virtual {p0}, Lcom/android/settings/DisplaySettings;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v1

    const-string v4, "heads_up_enabled"

    if-eqz v0, :cond_2c

    move v3, v2

    :cond_2c
    invoke-static {v1, v4, v3}, Landroid/provider/Settings$Global;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z

    goto/16 :goto_3

    :cond_2b
Again, you'll want to change the variables to match the ones in the prior code section if they are different for you and make sure to change the conditional labels to one hexadecimal numeral higher than the highest one already present in the method. Change the goto/16 :goto_3 to match the one in the previous code section.

Save the file and close it.

That's it for SecSettings.apk. Recompile and re-sign it.


Install both files to your phone using your preferred method. You should already know this but I'll say it anyway, THESE FILES CANNOT BE INSTALLED LIKE NORMAL SIDE-LOADED APKs. I prefer to reboot to recovery and use ADB to push the files to the system, but you can use whatever method is easiest for you (ie. Aroma file manager, flashable zip, etc.).
The Following 19 Users Say Thank You to moonknightus For This Useful Post: [ View ] Gift moonknightus Ad-Free
10th September 2014, 05:02 PM |#2  
bigwillyg's Avatar
Senior Member
Thanks Meter: 2,359
 
Donate to Me
More
So I guess those of us that aren't very good at this will have to wait then? Lol

Sent from my SPH-L710 using Tapatalk
The Following 2 Users Say Thank You to bigwillyg For This Useful Post: [ View ] Gift bigwillyg Ad-Free
10th September 2014, 08:02 PM |#3  
talkingmonkeys's Avatar
Recognized Contributor / Themer
Thanks Meter: 4,435
 
Donate to Me
More
Great tutorial man! Thank you looking forward to add this to all my releases soon. Great job!
10th September 2014, 10:37 PM |#4  
Senior Member
Flag MILAN
Thanks Meter: 317
 
More
Great, it compiles without mistakes with Dn3 4.4.2 for N7105, but I was playing with my 4 years old daughter and I'm sure something will be wrong, lol!

I just had to use cond 8 instead of 7, but I will report very likely my failure... It will take longer for me to let it work.

Anyway, it is a very useful tutorial and it's the only one here.
11th September 2014, 08:39 AM |#5  
Senior Member
Flag MILAN
Thanks Meter: 317
 
More
Mismatch?
I think there is a typo in the code for statusbar, it says mismatched input "p1" expecting END_METHOD_DIRECTIVE

I took this one from your original code (the one inside your rom) and it compiles fine

.method protected shouldInterrupt(Landroid/service/notification/StatusBarNotificationZ
.locals 12
.parameter "sbn"

.prologue
const/4 v8, 0x0

const/4 v9, 0x1

.line 1292
invoke-virtual {p1}, Landroid/service/notification/StatusBarNotification;->isOngoing()Z

move-result v4

if-nez v4, :cond_0

iget-object v10, p0, Lcom/android/systemui/statusbar/BaseStatusBar;->mPowerManager:Landroid/os/PowerManager;

invoke-virtual {v10}, Landroid/os/PowerManager;->isScreenOn()Z

move-result v1

:goto_0
return v1

:cond_0
move v1, v8

goto :goto_0
.end method


I will re-check the next steps, because last night I was unable to get everything working (I am not a dev).

Thanks again.
11th September 2014, 02:34 PM |#6  
moonknightus's Avatar
OP Senior Member
Thanks Meter: 816
 
More
Quote:
Originally Posted by lucaoldb

I think there is a typo in the code for statusbar, it says mismatched input "p1" expecting END_METHOD_DIRECTIVE

I took this one from your original code (the one inside your rom) and it compiles fine

.method protected shouldInterrupt(Landroid/service/notification/StatusBarNotificationZ
.locals 12
.parameter "sbn"

.prologue
const/4 v8, 0x0

const/4 v9, 0x1

.line 1292
invoke-virtual {p1}, Landroid/service/notification/StatusBarNotification;->isOngoing()Z

move-result v4

if-nez v4, :cond_0

iget-object v10, p0, Lcom/android/systemui/statusbar/BaseStatusBar;->mPowerManager:Landroid/os/PowerManager;

invoke-virtual {v10}, Landroid/os/PowerManager;->isScreenOn()Z

move-result v1

:goto_0
return v1

:cond_0
move v1, v8

goto :goto_0
.end method


I will re-check the next steps, because last night I was unable to get everything working (I am not a dev).

Thanks again.

The code in the guide is taken straight from my ROM. All this method does is check to see if the notification is ongoing or not, then check to make sure the screen is on. also, I highly recommend using the latest version of apktool.
The Following 4 Users Say Thank You to moonknightus For This Useful Post: [ View ] Gift moonknightus Ad-Free
11th September 2014, 09:12 PM |#7  
Senior Member
Flag MILAN
Thanks Meter: 317
 
More
First of all, thank you.

I still have to edit the files by myself, but I have tested both your system ui and your secsettings on to the rom I am using (Dn3 4.4.2 for N7105) and they work fine, including heads up notifications... So I will keep these settings for some days, until I have the time to learn more about this matter.

Btw, I will try some of yor themed apps I found inside your rom, which are very good looking.
12th September 2014, 04:15 AM |#8  
bigwillyg's Avatar
Senior Member
Thanks Meter: 2,359
 
Donate to Me
More
So what does the hud look like and how does it work? Not familiar with it.

Sent from my SPH-L710 using Tapatalk
12th September 2014, 07:06 AM |#9  
talkingmonkeys's Avatar
Recognized Contributor / Themer
Thanks Meter: 4,435
 
Donate to Me
More
Works great. Thank you moonknightus
Attached Images
File Type: jpg 1410501971431.jpg - [Click for QR Code] (44.0 KB, 905 views)
The Following 2 Users Say Thank You to talkingmonkeys For This Useful Post: [ View ] Gift talkingmonkeys Ad-Free
12th September 2014, 03:52 PM |#10  
marcran75's Avatar
Senior Member
Flag Syracuse,NY
Thanks Meter: 1,564
 
More
Deleted
13th September 2014, 04:19 AM |#11  
bigwillyg's Avatar
Senior Member
Thanks Meter: 2,359
 
Donate to Me
More
Quote:
Originally Posted by marcran75

Deleted

???

Sent from my SPH-L710 using Tapatalk
Post Reply Subscribe to Thread

Tags
development

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes