Skip to content

Add support for new UnifiedPush specifications, and fallback to the previous ones. - #98

Merged
binwiederhier merged 5 commits into
binwiederhier:mainfrom
p1gp1g:UnifiedPush/AND_3
Dec 30, 2025
Merged

Add support for new UnifiedPush specifications, and fallback to the previous ones.#98
binwiederhier merged 5 commits into
binwiederhier:mainfrom
p1gp1g:UnifiedPush/AND_3

Conversation

@p1gp1g

@p1gp1g p1gp1g commented Nov 12, 2024

Copy link
Copy Markdown
Contributor

The specifications where updated recently: https://codeberg.org/UnifiedPush/specifications/pulls/1

Mainly the new specs adds

  • Add the capacity to set a default distributor per system (with the Link Activity)
  • VAPID support (not in this PR)
  • Ability to raise the connected app to the foreground
  • Reduce ability to impersonate another app to create a topic, used to rate limit number of registrations per user
  • Clarify some stuff, like the reasons why a registration fail

@redstrate

Copy link
Copy Markdown

Note that in order for BRING_TO_FOREGROUND to work in modern Android without being blocked by PackageManager, you need this in the AndroidManifests.xml:

    <queries>
        <intent>
            <action android:name="org.unifiedpush.android.distributor.RAISE_TO_FOREGROUND" />
        </intent>
    </queries>

Otherwise the receiving app is never visible, and it will never end up calling the Service :)

@p1gp1g

p1gp1g commented Dec 22, 2024

Copy link
Copy Markdown
Contributor Author

Indeed, that explain why it failed sometimes. Surprisingly:

  • It don't always fail, maybe it works after the targettted app sends an intent to ntfy ?
  • It works when filtering other actions, for instance the following. This is why I missed it, I didn't have to do it for NextPush
    <queries>
        <intent>
            <action android:name="org.unifiedpush.android.connector.NEW_ENDPOINT" />
        </intent>
    </queries>

@redstrate

Copy link
Copy Markdown

It don't always fail, maybe it works after the targettted app sends an intent to ntfy ?

In my case it was blocking actions from ntfy to the app, I'm not sure exactly why this specific intent was blocked while the others were fine. Unfortunately PackageManager doesn't explain itself when it blocks :D

@warioishere

Copy link
Copy Markdown

@binwiederhier mayb its time to finally update ntfy and ntfy server?
I guess will be switching to sunup soon if no care anymore is taken on ntfy.

val reconnectTime = Calendar.getInstance()
reconnectTime.add(Calendar.SECOND, seconds)
alarmManager.setExact(AlarmManager.RTC_WAKEUP, reconnectTime.timeInMillis, RECONNECT_TAG, { start() }, null)
if (Build.VERSION.SDK_INT < 31 || alarmManager.canScheduleExactAlarms()) {

@CoelacanthusHex CoelacanthusHex Jul 15, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if-else may be wrong. setExact() doesn't need SCHEDULE_EXACT_ALARM.1 So we need to call setExactAndAllowWhileIdle() on first branch (and remove maxSdkVersion from SCHEDULE_EXACT_ALARM) and call setExact() in else branch. But since we don't use setExactAndAllowWhileIdle() before, just call setExact() unconditionally is the same as before.

Footnotes

  1. https://developer.android.com/develop/background-work/services/alarms/schedule#exact-permission-declare

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following Android doc: https://developer.android.com/about/versions/14/changes/schedule-exact-alarms

The SCHEDULE_EXACT_ALARM permission is required to initiate exact alarms via the following APIs or a SecurityException will be thrown:

Existing best-practices for the SCHEDULE_EXACT_ALARM permission still apply, including the following:

@Eskuero

Eskuero commented Aug 19, 2025

Copy link
Copy Markdown
Contributor

This doesn't seem to apply cleanly anymore after the recent merges

@p1gp1g

p1gp1g commented Aug 25, 2025

Copy link
Copy Markdown
Contributor Author

The conflicts are very simple to resolve, it shouldn't play for its adoption

@CoelacanthusHex

Copy link
Copy Markdown

The conflicts are very simple to resolve, it shouldn't play for its adoption

Yeah. But it may be harmful for review, since the diff is not between main and PR.

@p1gp1g

p1gp1g commented Aug 26, 2025

Copy link
Copy Markdown
Contributor Author

It honestly doesn't change anything. Actually, they just have implemented something that I have implemented here, so it is a duplicate on a few lines

Comment thread app/build.gradle

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this repo owner allowed to you change compatibility requirements?

@CoelacanthusHex

Copy link
Copy Markdown

I have rebased and sorted out the content of this PR to facilitate the maintainer to review and merge.
https://github.com/CoelacanthusHex/ntfy-android/tree/unifiedpush-andv3-tidy
@p1gp1g If you don't want to spend time on rebase and resolving conflicts, you can use it directly.

@binwiederhier

Copy link
Copy Markdown
Owner

@p1gp1g Do you want to update this PR for the latest main?

@englut

englut commented Oct 23, 2025

Copy link
Copy Markdown

Any movement on merging this?

@englut

englut commented Nov 20, 2025

Copy link
Copy Markdown

I have rebased and sorted out the content of this PR to facilitate the maintainer to review and merge. https://github.com/CoelacanthusHex/ntfy-android/tree/unifiedpush-andv3-tidy @p1gp1g If you don't want to spend time on rebase and resolving conflicts, you can use it directly.

@binwiederhier if we don't hear from @p1gp1g... would it be cool for @CoelacanthusHex to open a PR for their branch and merge that in?

@binwiederhier

Copy link
Copy Markdown
Owner

I am doing some Material 3 work, then more SDK updates, and then I'll address open PRs.

@p1gp1g

p1gp1g commented Nov 20, 2025

Copy link
Copy Markdown
Contributor Author

Rebase done, all the conflict were exactly the same changes

@Eskuero

Eskuero commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

Just built from main using this patch and works rock solid still

@binwiederhier

Copy link
Copy Markdown
Owner

@p1gp1g asked me to pull in 23e061a into the next release of the Android app. I am happy to accomodate more changes later, but I have to get the Material change out first.

May I kindly ask that somebody explain this commit to me? What is it for?

@p1gp1g

p1gp1g commented Dec 4, 2025

Copy link
Copy Markdown
Contributor Author

This is this point of the specs: https://unifiedpush.org/developers/spec/android/#link-activity

Some users have multiple push services (distributors) installed on their system, this activity allows them to define a default one, and to use the system picker to select another one

Here is the view when the user can select their default distrib, by selecting "always":

image

Here is view for a system picker:

image

@binwiederhier

Copy link
Copy Markdown
Owner

See #137 for the urgent distributor selection. I'll polish this and make a test release tonight.

@binwiederhier

Copy link
Copy Markdown
Owner

📢 For those willing to test the new ntfy Android version 1.18.0, check out https://play.google.com/store/apps/details?id=io.heckel.ntfy or https://play.google.com/apps/testing/io.heckel.ntfy and sign up for open testing.

This includes the LinkActivity. Please test.

@seang96

seang96 commented Dec 5, 2025

Copy link
Copy Markdown

@binwiederhier I'd be happy to test it as a prerelease via Github if you can release it that way. I assume signatures are different / rather not use Google services as much as possible.

@binwiederhier

Copy link
Copy Markdown
Owner

@seang96 I uploaded the .apk files here: https://github.com/binwiederhier/ntfy-android/releases/tag/rc-v1.18.0 -- The -debug ones have a different package name, so you can install them alongside the main app.

@binwiederhier

Copy link
Copy Markdown
Owner

@p1gp1g I am now happy to get this into the next release if you want to rebase/merge the changes. ❤️

@p1gp1g

p1gp1g commented Dec 21, 2025

Copy link
Copy Markdown
Contributor Author

Done 👍

@binwiederhier

Copy link
Copy Markdown
Owner

Awesome. So I looked at the PR, and I tried to read the spec, but it's quite the difficult literature for someone who's out of the loop. I am happy to merge this, but I must understand what I merge, because it's my app :-)

Can you help me either

  1. Understand it by explaining it more
  2. Or show me how to test it

I'm also happy to chat on Discord/Matrix.

@p1gp1g

p1gp1g commented Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

The 2 first commits are pretty simple:

  • 3655b28 The requesting packageId is resolved with the shared identity with SDK34+, or with a pending intent. There is a fallback to the previous extra for now, but it should be removed in the future
  • 544bb24 The failed reason is now using hardcoded values

And finally, the PR also adds the "service to raise to the foreground". This is a mechanism to allow the receiving application to start a foreground service from the background, to have the same capacity than the play services with high priority notifications. They use a privileged API, but the same behavior is possible by binding an application with foreground importance to a service

To test this service, you can use UP-Example:

  • Register with ntfy
  • Enable the developer mode
  • Enable the "Fg service on message"
  • Open the test page in a browser
  • Then swipe out UP-Example from recent apps (it will kill the app, but not force-kill it)
  • Then, from the test page, send a notification

With this PR, you will see a notification "run in foreground". You can stop this service by clicking on "stop foreground service". Without the PR, you won't have the foreground service

@binwiederhier

Copy link
Copy Markdown
Owner

Thank you for this explanation. I've reviewed and run it, and it works as you describe. I'll spend more time with it to understand it more. If you can document the code to explain the WHAT and WHY in docblocks above the classes, that'd be helpful for Future-Phil.

What is the purpose of the Raise to Foreground and the Foreground Service? What are legitimate use cases? Are there any apps that make use of this yet?

@binwiederhier

Copy link
Copy Markdown
Owner

I think I would love to have a conversation about this, @p1gp1g. Whenever you are around on Matrix/Discord, ping me. I re-reviewed the PR and it looks to me as though you are now the RaiseAppToForegroundFactory.raiseAndSend() thing will

  1. Check if the app is in the foreground
  2. If not, queue it
  3. If yes, send it like before

I probably misunderstood. But that's why I want to have a convo.

@szimszon

szimszon commented Dec 29, 2025

Copy link
Copy Markdown

Hi @binwiederhier ,

You asked for app and use case benefitting from raise app to foreground. Maybe this qualifies: element-hq/element-x-android#4828 (comment) here a recommendation to use SunUp instead of Ntfy to get notification more reliable, because it can raise app to foreground.

Happy holidays!

@binwiederhier
binwiederhier merged commit f35390f into binwiederhier:main Dec 30, 2025
@binwiederhier

Copy link
Copy Markdown
Owner

I think I understand it all. Thank you @p1gp1g for the detailed explanations in the DMs and such. And to everyone for the patience. This should be released as part of 1.21.x, which will be in ~1-2 weeks I believe.

@p1gp1g I added a few clarifying commits, see #148 -- In particular, would you mind reading this https://github.com/binwiederhier/ntfy-android/blob/main/app/src/main/java/io/heckel/ntfy/up/RaiseAppToForeground.kt#L18-L109 and telling me if this is correct? I fed our conversation and all the docs and the code to Cursor and it explained and generated this. It helped a LOT to understand what the flow is. Please verify that it is accurate. Future-Phil will thank you. And so will Present-Phil.

I also verified that stuff works with UP-Example the way you described it. UP-Example is able to create a foreground service. I also selected "ntfy (debug)" as push provider for Element-X, though I don't think I've received any notifications on Matrix yet.

@binwiederhier

Copy link
Copy Markdown
Owner

Hm, I tried with Element X and it wasn't working... I will do some debugging tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants