Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of App.beep() for Android #2068

Merged
merged 9 commits into from
Aug 23, 2023

Conversation

t-arn
Copy link
Contributor

@t-arn t-arn commented Aug 7, 2023

This PR implements App.beep() for Android
The "window" example has been extended to demo this feature.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

@t-arn
Copy link
Contributor Author

t-arn commented Aug 7, 2023

@freakboy3742 Please review this PR

@mhsmith
Copy link
Member

mhsmith commented Aug 7, 2023

FYI: rather than waiting for GitHub to run the pre-commit checks, you can set it up on your own machine as shown here.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 7, 2023

@mhsmith Thanks for the hint :-)

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

When I run this on the Briefcase default emulator, I get:

D/Ringtone: Successfully created local player
E/FileSource: Failed to open file 'content://settings/system/notification_sound'. (No such file or directory)
E/AudioManager: hasHapticChannels failure:java.io.IOException: Failed to instantiate extractor.

This looks like it might be a limitation of the emulator - can you confirm whether you're seeing this as well?

From poking around looking for a quick fix for this, I also saw some suggestions that you should use MediaPlayer, rather than RingtoneManager to play sounds like this, because MediaPlayer will play over any existing sounds (e.g., music playing in the background), rather than interrupting audio.

self.scroller = toga.ScrollContainer(
horizontal=False,
vertical=True,
style=Pack(flex=1, padding=10),
Copy link
Member

Choose a reason for hiding this comment

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

This puts the padding on the outside of the scroll container, so there's a border around the scrolling content. We don't need any padding there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, removed padding.

style=Pack(flex=1, padding=10),
)
self.scroller.content = self.inner_box
self.main_box.add(self.scroller)
Copy link
Member

Choose a reason for hiding this comment

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

The widget layout you've got here is: content -> main_box -> scroller -> inner_box -> *buttons

AFAICT, the main box isn't adding anything. You should be able to add the scroller directly as the main content.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, removed main_box and renamed scroller to main_scroller, so it becomes obvious that the scroller represents the main content.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 8, 2023

E/FileSource: Failed to open file 'content://settings/system/notification_sound'. (No such file or directory)

This is strange. It works on my emulator and I had the code running on my phone as well (in pyPlayground).
I'll try to run the example on the phone again.

@freakboy3742
Copy link
Member

FWIW: It does beep on my physical Android device; it's only my emulator where it raises an error. Even there, the app doesn't crash - it's just a bit noisy in the logs. If we can establish that this is a quirk of (some) emulators, I can live with that; if we can catch the error and log something a little more helpful, that's even better.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 19, 2023

From poking around looking for a quick fix for this, I also saw some suggestions that you should use MediaPlayer, rather than RingtoneManager to play sounds like this, because MediaPlayer will play over any existing sounds (e.g., music playing in the background), rather than interrupting audio.

I think that interrupting existing sounds is what we want in this case: the user should get notified. If we play the beep over the running sound, it might go unnoticed by the user.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 19, 2023

@freakboy3742 Please re-review this PR.

@mhsmith
Copy link
Member

mhsmith commented Aug 19, 2023

I have a few devices of various ages, so I can test this one.

Copy link
Member

@mhsmith mhsmith left a comment

Choose a reason for hiding this comment

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

I got the same "Failed to open file" error on the Briefcase default emulator with API level 31, and a Pixel 7 with API level 33. But in both cases, the sound still worked, so I think the message is harmless. It's not throwing an exception to us, so there's no way to suppress it.

It also works on an older device and emulator. However, I have noticed that emulators sometimes stop producing any sound at all. You can usually get it back by rebooting the emulator:

  • Close the emulator.
  • Open Android Studio and go to Tools > Device Manager.
  • Open the ellipsis menu next to the emulator in question, and choose "Cold boot now".

The interaction with background music seems reasonable: the notification is clearly audible, but it doesn't interrupt the music any more than necessary.

So I'm fine with this, except for one thing:

Comment on lines 213 to 217
uri_obj = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
uri = java.cast(Uri, uri_obj)
ring_obj = RingtoneManager.getRingtone(self.native.getApplicationContext(), uri)
ring = java.cast(Ringtone, ring_obj)
ring.play()
Copy link
Member

Choose a reason for hiding this comment

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

I don't think these cast calls are necessary. Why did you add them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right: we already get the correct class instances. Somehow, I thought we get Objects back... I'll fix this.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 19, 2023

I got the same "Failed to open file" error on the Briefcase default emulator with API level 31, and a Pixel 7 with API level 33. But in both cases, the sound still worked, so I think the message is harmless. It's not throwing an exception to us, so there's no way to suppress it.

Do you also have the error message on real devices?

@mhsmith
Copy link
Member

mhsmith commented Aug 19, 2023

I got the error message on a real Pixel 7 with API level 33, but not on a Nexus 5X with API level 27. The sound worked on both devices.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 23, 2023

I got the error message on a real Pixel 7 with API level 33, but not on a Nexus 5X with API level 27. The sound worked on both devices.

Yes, the problem with the error message seems to depend on the Android version. With API level 30, there is no error message. Starting with API level 31, the error message appears. The peep sound works on both API levels.

@t-arn
Copy link
Contributor Author

t-arn commented Aug 23, 2023

@mhsmith
I managed to get rid of the error message on Android 13 :-)
Please re-review.

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

Looks good; after restarting the emulator as suggested by @mhsmith, I'm now getting a beep (or a twinkle, or whatever you want to call that sound :-).

Interestingly, I'm not getting any file errors any more - I get a warning about offset/length being adjusted:

W/FileSource: offset/length adjusted from 0/576460752303423487 to 0/16905

but the audio plays fine, so I'll call that a win.

I've renamed the changefile to a misc - since the beep() API was added in this release, it will already have a feature indicator (#2018); we don't need a separate feature for Android.

@freakboy3742 freakboy3742 merged commit 127e8f7 into beeware:main Aug 23, 2023
40 checks passed
@t-arn t-arn deleted the beep_android_1744a34 branch August 24, 2023 17:35
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.

3 participants