Android Media Player Threading/Concurrency - java

I am using the default Android Media Player in an Activity, trying to play back a couple of video files. However I have a problem with programming what I want. The desired program outcome would be the following:
A video file is played back
After that, a dialog is shown, asking the user something
A pause of 5 seconds occurs
The next video is shown
and so forth
How am I to program this? Currently, I use a paradigm like the following:
I have a method that sets up the player for theĀ a file, e.g. playVideo(int) So I pass it the first file.
When the player is prepared, it will be started in onPrepared(MediaPlayer).
When the video is finished, the onCompletion(MediaPlayer) listener of the media player shows the dialog to the user by calling showDialog().
The user accepts the dialog. Before calling dismiss() on the dialog, the player object is started for the next file by calling playVideo(int).
This works, but it feels a bit quirky and not clean. And it's of course very procedural. The problems are:
that I can't figure out how to insert a pause after the dialog is dismissed.
that I maybe want to change the presentation order of dialogs and videos and this ain't too easy now
Has anyone got an idea?

For the pause, you could use the AlarmManager to schedule an alarm five seconds from now. It will launch an intent, and that intent could call playVideo(int).

Related

How not to interrupt the current process in the application when the user clicks on push?

on one screen in my application, I am recording audio.
Scenario: User records audio on this screen. A push comes from our application. The user clicks on this push and another push processing activity is launched.
Result: The user loses his session.
Question: what are the options for handling this case so that the user does not lose his session? Ideally, before switching to a new activity, the application would ask the user if he is sure that he wants to go to another screen, because the session will be lost. But how to track it?
Thanks a lot for your advice
The best solution I have found is to clear all old push notifications in the notification shade when going to the recording screen.
val notificationsManager = getSystemService<Any>(Context.NOTIFICATION_SERVICE) as NotificationManager?
notificationsManager!!.cancelAll()
Further during the recording, if a push notification arrives, I receive this in my service inherited from FirebaseMessagingService in onMessageReceived().
If the recording screen is currently open, I do not show a notification in the notification shade. But I show a widget on the recording screen with the push text and if the user presses it I ask if the user wants to go to another screen because the recording will end.
I hope my experience helps someone. Similarly implemented in Intercom

Looking for an easy way to capture images on an Android phone as a background service

I'm trying to create an application that automatically clicks pictures as you carry your phone around, the point is that it clicks pictures as you do your own business.
This question is basically what I'm looking for with the added functionality of taking pictures every n seconds. I wanted to know if there was something more efficient than this method (shrinking the preview window to 1x1).
background service is not recommended. You can use foreground service for this job.
You need to give media and camera access permission in the code. Then you can run the capture function with n second delay and while loop as many times as you want.
there are some examples, i don't want to repeat them.
capture, save and show example
take photo without ui

Java - Use music playback control buttons

Usually on keyboards there is buttons to stop the current track, go to the next track, or to the previous one. When I'm playing sound on YouTube for example, and press the F10 key, the video stops.
I'm creating a Java/Kotlin music player. What currently happens when I have music playing, and then I click F10, is that the last YouTube video I have in an open tab starts playing, and the music player does not get effected at all.
What I want is: When I click F10 (or the other control keys), I want my music player to get affected by them, not YouTube.
How can I achieve that?
If I understand correctly, you have an application for playing back sound, but when control keys (e.g., F10 in particular) are pressed, your browser is receiving the key, not your application.
If that is the case, the question seems is about how to use the Swing KeyListener. The KeyEvent API shows that the keycode for the key to be VK_F10. Are you having problems with implementing this? Kotlin might have it's own way of doing key listening, though. I did find this SO question on Kotlin KeyListeners.
As far as starting or stopping a sound, that is usually accomplished by wrapping the audio playback class (Clip or SourceDataLine) in a class that can receive and handle commands to start, stop or continue. Are you having problems with implementing this?
The code that links these two functional areas should be loosely coupled. With that, pursing the two matters as two separate questions will be beneficial.
If your issue is a specific OS implementation question, it would be best to clarify that in the question with additional information.

Why does an activity playing a sound disturb the user interface?

I would like to show a notification and play a sound when the user taps onto that notification. It works somehow when I use an activity to play the sound, as I have written in my own answer to this question: How can I create a notification that plays an audio file when being tapped? (in this question and answer there is also the source code showing how I create the notification and how my PlaySoundActivity looks like.
Yet, I have realized, that while the sound is playing, the appearance of my main application changes and it will not be restored without closing the application.
I have created my application from the "Tabbed Activity" project template.
This is how it looks after being started:
And this is how it looks when I have tapped onto the sound notification (the sections are gone):
Can anyone explain why this happens? Is it a wrong approach to play sound using an activity? But it does not work here when I use a service, I hear nothing! How to solve that?
According to the Android developer reference, "almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View)".
I had not done this. Therefore a new window was displayed, but there was no content.
The better solution for playing a sound is to use a PlaySoundService (service!!!) instead of an activity. It contains almost the same code as an activity would do, but the pending intent is created with PendingIntent.getService(...) instead of PendingIntent.getActivity(...). Using the wrong method does not result in an obvious error message, but the service won't work as expected.

Android Sound Resetting

My app plays a coin sound every time a button is pressed.
coin_sound.start();
You can easily press faster than the coin sound. When this happens I want the coin sound to start from the beginning ever time the button is pressed.
if(coin_sound.isPlaying()){
coin_sound.reset();
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
}
coin_sound.start();
The problem with this is that loading a media file tiny as it may be is still a relatively slow process. When you start to click the button really fast the app lags hard.
Are there any solutions to my problem? The only idea I have is to do something with an array of coin_sounds, but this method seems like it will be messy and gross...
The other answer posted here is somewhat correct. You should not call create over and over.
The code in that answer has a problem, though. The reset method sends the MediaPlayer into the idle state, where it is illegal to call most other methods. If you were to go that route, you have to call methods in the following order:
coin_sound.reset();
coin_sound.setDataSource(...);
coin_sound.prepare();
coin_sound.start();
The difference between calling create and the previous sequence of method calls is simply the creation of a new instance. That, however, is not the quickest way to do what should be done.
You should simply call coin_sound.seekTo(0); when you want the current playing sound to restart. So do something like:
if (coin_sound.isPlaying()) coin_sound.seekTo(0);
else coin_sound.start();
That assumes you have left the MediaPlayer in the prepared state so start can be called. You can accomplish that by calling reset, setDataSource, and prepare in the onCompletion listener. Also, make sure to call release when the sound is no longer needed.
It is because you are initiating coin_sound in the button click event, try this
initiate this variable in your oncreate method
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
then make this your code for your button
if(coin_sound.isPlaying()){
coin_sound.reset();
}
coin_sound.start();
the problem is you are recreating a new media player each time the button is clicked so the new media player doesnt think there is a sound
and do you need to start it again with coin_sound.start();? doesnt restart stop then start the sound for you?

Categories

Resources