Bangle.js: Intents - continue extending functionality #2826
No reviewers
Labels
No Label
device mi band 7
activity post processing
activity/health
Android 12
Android 13
android integrations
architecture
Bangle.js
bug
changes requested
charts
details not provided
developer documentation
device amazfit band 5
device amazfit bip
device amazfit cor
device Casio
device fossil
device garmin
device gtr 2e
device gts 2 mini
device h30
device hplus
device huami
device Huawei
device liveview
device mi band
device mi band 2
device mi band 3
device mi band 4
device mi band 5
device mi band 6
device no.1 f1
device pace
device pebble
device pebble 2
device pinetime infinitime
device request
device sony
device support
device watch 9
device xiaomi
discussion
documentation
duplicate
enhancement
feature request
Gadgetbridge
good first issue
help wanted
i am developing my own app can you help
icebox
intent api
internationalisation
invalid
needs work
network companion app
new device
no feedback
not a bug
notifications
one of the 1000 issues about disconnection
pairing/connecting
potentially fixed / confirm and close
question
research
security
seems abandoned
Solved, waiting for F-Droid release
suggest to close
task
user interface / UX
wear os
weather
wontfix
Zepp OS
No Milestone
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Freeyourgadget/Gadgetbridge#2826
Loading…
Reference in New Issue
No description provided.
Delete Branch "Ganblejs/Gadgetbridge:Intents"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is a continuation of PR #2769.
DONE:
Reorder code to follow this order "target, action, flags, categories, package, class, mimetype, data and extra". As to group them with some kind of logic. (The target isn't actually part of the intent. The flags say how an action should behave. categories, package and class specifies what app(s)/activity/class can or should be used for the action. mimetyp, data and extra are used to supply information to act on.)
Add support for setting flags for intents.
Add ability for GB to wake the device and leave the lock screen to start activities when the device is sleeping. (The password can be bypassed if the user adds the Bangle.js as a trusted device) (This works now with the help of a new waking activity,
but needs some further work to be reliable when launching follow up activity. I believe that as it is now the waking activity will not always have the time to wake and unlock the phone before the next activity tries to launch, so nothing happens in that case.SEE "Improve waking ability"-point below.)Add support for setting multiple categories for an intent.
Possibly remove imports I introduced which are maybe not needed.
Improve waking ability. (send the intent you want for starting activity you want, then send intent for waking the android device. Sending only the waking intent twice will open the android device on the activity active when it went to sleep.) (how to send waking intent from Bangle.js:
Bluetooth.println(JSON.stringify({t:"intent", target:"activity", flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_CLEAR_TASK", "FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS", "FLAG_ACTIVITY_NO_ANIMATION"], package:"gadgetbridge", class:"nodomain.freeyourgadget.gadgetbridge.activities.WakeActivity"}));
)
Add service intent support.
(Think this is implemented now, but have not tested it yet.)(Started testing this, doesn't seem to work yet..)(Works at least for explicit intents. From my testing it doesn't work for implicit intents, see this stackoverflow question. Tested and working with sending the following from Bangle.js to Gadgetbridge to control the music app Poweramp:Bluetooth.println(JSON.stringify({t:"intent", target:"foregroundservice", action:"com.maxmpz.audioplayer.API_COMMAND", package:"com.maxmpz.audioplayer", extra:{cmd:"TOGGLE_PLAY_PAUSE"}}));
)
Add dismiss-button to 'display over other apps' permission pop up, add instruction to the message on how to disable 'Check permission status'.
Here's the Bangle.js app I use for testing. And here's its js-code.
FUTURE WORK FOR ANOTHER PR:
WIP: Bangle.js: Continued extension of intents functionalityto WIP: Bangle.js: Intents - continue extending functionality726c223bbb
to29d9f8b9d6
@ -750,0 +777,4 @@
and android.content.Intent.FLAG_RECEIVER_OFFLOAD_FOREGROUND
*/
// Commented out some cases below that Android Studio said it could not resolve, mainly those starting with "android.content.Intent.".
switch (flag) {
I'd replace this switch with a map:
Ok! I will look at doing that. I don't know the advantages of switch vs map myself. I'll just trust your judgement! :P
I just find it more readable / less error-prone, but it may be a bit personal preference.
I just realized there is no need for this new function really. I can just add an instruction in the espruino docs to supply the "Constant Value" of flags, which are integers, instead of the name of them (example: FLAG_ACTIVITY_NEW_TASK Constant Value is 268435456).
On the other hand, having the function might improve readability of Bangle.js app code where it's easier to understand/remember what the string "FLAG_ACTIVITY_NEW_TASK" implies rather than the integer 268435456...
Thoughts on this? @joserebelo @gfwilliams
I like the idea of sending the flag names, it does make it easier / the code more readable, people will end up having to create the constants on the Bangle.js app code anyway.
We could also use reflection to avoid declaring all of them on Gadgetbridge side and keep it compatible going forward. I would say that this code is not performance-critical, so it should not be too bad:
With some more error-checking, of course.
Just my 2 cents, I got no strong feelings :)
I tried this just testing it out:
and got this:
I've looked at "Intent.class" where this line (334) exist:
You need to put all of that inside a
try ... catch
, since aNoSuchFieldException
will be thrown if the user sends an invalid flag.Ah, ok - thanks!
affacc12a7
to5254c00642
I'm looking at moving the "permission to display over other apps" to appear when toggling the setting in "Device specific settings" instead. But I'm having a hard time finding where to hook into this.
I've found this on line 187 in BanglejsCoordinator.java:
But that's about as far as I get searching in android studio. Is there a way to know when the setting is toggled and display the pop-up then?
You can hook into that on
DeviceSpecificSettingsFragment
, see thesetChangeListener
function.WIP: Bangle.js: Intents - continue extending functionalityto Bangle.js: Intents - continue extending functionalityI think the PR is ready for review now. If/when the code seems adequate I can rebase and squash the commits in preparation for merging.
Android Studio warn about using getApplicationContext(), so I changed to only using getContext() when executing the bangle.js intents. I've been mimicing the original implementation of broadcasts until now where getApplicationContext() was used. Is there a specific reason for using getApplicationContext(), @gfwilliams? From the testing I've done I don't notice any difference in function.
EDIT: Also, from a little testing it seems I can drop the "this." in front of getContext(), without breaking sending broadcasts or starting activities.
Android studio said:
6226895c87
to25e4791f0a
I'm testing intents for startings services without success.
Testing with this:
From here.
Using that with tasker works for the action "play/pause" in the music player Poweramp. But so far I'm not able to make Gadgetbridge do the same.
EDIT: I've introduced (locally)
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
to AndroidManifest as per this stackoverflow answer.EDIT: Opened a question on stackoverflow.
EDIT: By adding package information to the intent, making it explicit, it can control poweramp. As per these instructions.
From my point of view the PR is almost ready for merging now, again. Maybe just wait until @gfwilliams have chimed in re getApplicationContext().
If/when the code seems adequate I can rebase and squash the commits in preparation for merging.
@ -52,1 +52,4 @@
<!-- Used for starting services from all other packages with intents when targeting Android API level 30 or later on devices running Android 11 or later.
https://support.google.com/googleplay/android-developer/answer/10158779?hl=en#zippy=%2Cpermitted-uses-of-the-query-all-packages-permission%2Cexceptions -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
It might be hard to convince Google Play Store to allow this permission. Hopefully not. @gfwilliams
Sorry for the delay - was on holiday.
Not at all, no. I think maybe I'd seen it used in an example somewhere
This is already in
app/src/banglejs/AndroidManifest.xml
since it was needed anyway for SDK 30 that the Bangle.js build has... So you may not want this in the main AndroidManifest?No worries what so ever! Sorry if I seem impatient, just wanted to catch you when you got back! :)
Ok! Didn't catch that. Yes, I think that makes sense for now at least then. Since the main flavor doesn't target api level 30 or above there should not be an issue for people on that flavor that also want this service intents functionality. But if main flavor will target api level 30 or higher, then I would suggest adding it in to the main AndroidManifest.xml file instead.
What do @joserebelo, @vanous think? Should it be moved to the main manifest now or should it wait (or never :p)?
It seems like a magic trap each time - they promise some extra more functionality but behind the scenes you loose some functionality as well and this has causes new regressions lately... this comes up from time to time, unfortunately i did not link the original issues and cannot find them now... i previously compiled the issues into this: info https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Developer-Documentation#currently-used-sdk-versions
Ok! I'm not arguing for bumping the sdk version of either compile, min or target. For this PR it might be better not to.
I was just thinking that if it is bumped in the future, the service intent functionality introduced in this PR will most likely break for people who use the main build version/flavour on Android 11 and up. So it would be a preemptive fix to move QUERY_ALL_PACKAGES permission to the main build manifest now. I think this is a good idea after just having tested building a main nightly version and installed it on my device (Xiaomi MI A2 lite running Android 10) - it worked with no hiccups.
On the other hand, applying the 'don't fix what ain't broken' mindset might be better. And then move the permission in to main build if/when target sdk version is bumped.
e9b70dc8d0
tof8b0dcdd0a
Rebased and squashed commits.
f8b0dcdd0a
to0c16a8e448
0c16a8e448
tofdf113ce2d
Rebased.
There is another reason for not bumping the sdk version: We can never go back. That's impossible.
So if SDK 30 breaks things without workaround, it is bad.
If SDK 30 does not show any regression then we can bump.
Candidates for regressions are:
etc.
@ashimokawa
Yes, I understand and agree with your reasoning! :)
And just to be clear, as I said I don't argue for bumping the SDK version. This PR, as it's coded now, is not dependent on it being bumped.
QUERY_ALL_PACKAGES-permission was already present in the Bangle flavour AndroidManifest because Bangle flavour was bumped to SDK 30 earlier.
The reason I suggest instead moving the permission to the main build version now is so that if at some point in the future the main build is also bumped to SDK 30+ then the functionality in this PR remains intact for the main Gadgetbridge build version.
I have tested this PR, as it is coded now, on the Gadgetbridge main build (SDK 29) on my Xiaomi Mi A2 lite running Android 10 without problems. So it doesn't break any functionality today what I can see. It should only future-proof the service intent-feature introduced.
But with that said, I'm ok with keeping the QUERY_ALL_PACKAGES permission in the Bangle build version AndroidManifest if you think it is better? But then someone will maybe have to do a fix later on.
Thanks for chiming in! 👍
fdf113ce2d
to7ad60eedd6
Rebased.
7ad60eedd6
toe70fc6526a
Reverted moving QUERY_ALL_PACKAGES-permission, now back in Banglejs flavour AndroidManifest.
@gfwilliams
What do you think? Merge?
Yes, thanks! This looks good to me!
About SDK 30: It seems that SDK 30 works ok on the Bangle.js version but then I have only tested it with Bangles so haven't really used every codepath.
However the only reason to have SDK 30 on there is because of Google's Arbitrary rule for the Play Store. So in a way, it seems there are no benefits to changing the main Gadgetbridge right now - only potential downsides of things getting broken :)
At least maybe in the future if it is useful, the Bangle.js build will have been able to have provided some advanced testing though :)
e70fc6526a
toc15bb08a87
Rebased.
c15bb08a87
toa2e9f78f92
Rebased.
Thanks again for all help on this!
@Ganblejs
@gfwilliams
This will make Android < 8.0 crash
Did not notice when merging.
@ashimokawa
Oh, that's not good! Sorry about that then... Do you have a hint of how I could remedy this? Is it that foreground services were introduced with android 8.0? EDIT3: So reading the documentation in EDIT2 seems to indicate this is the problem. I will try to fix it.
EDIT: I presume my change from using
this.getContext().getApplicationContext().
to onlygetContext().
for getting the context isn't the problem?EDIT2: Here's the documentation for startForegroundService(): https://developer.android.com/reference/android/content/Context#startForegroundService(android.content.Intent)
@ashimokawa
I will try using startService() together with startForeground() instead when API level is below 26: https://developer.android.com/reference/android/app/Service#startForeground(int,%20android.app.Notification)
But use startForgroundService() if API level is 26 or higher. Will use if/else-statement for this.
@Ganblejs
The link you sent says "Added in API level 26"
I would suggest using startService() when API is below 26
Something like:
@Ganblejs
This happened not the first time with PRs. It is a general problem that people use more modern java language or API features than available with what we have as a minimum requirement (right now Android 5.0).
Do you use Android Studio? It would have told you. I do not like it but at least it shows you all those hidden problems.
@ashimokawa
Yes, sorry about that and thank you!
Yes, weirdly I do use Android Studio but I don't get that same warning you print screened? (I haven't used Android Studio before doing these two PRs re Banglejs and intents, and am new to java and android programming...) EDIT: Or do you have to enter some kind of special mode to see that warning?
I don't know in the top right corner you should see this, if you are in reader mode than you should exit it.
This is BangleJSSupport, the file with the most warnings afaik :P
Yes I exited reader mode (which I don't remember consiously entering) and now I get the same error/warning. Thanks!
@ashimokawa PR with fix at #2911.
Argh, sorry, that's not good. When I get a bit of time I'll see what I can do about sorting out some of those