Play audio with more than one file - java

How do i play audio
In more than one file
Where I can move between pages without stopping sounds
I see it a lot in games
I hope to get your answer

It depends on callback function onDestroys() because your App works as a process in the Androids OS when you change the Activity the stopService() kill the music playing in your current activity.
Do not call the stopService() method.

Create MediaPlayer object outside onCreate()
public static MediaPlayer mediaPlayer;
Then do create inside onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.dali); //R.raw.dali is directory from folder raw that i made and the file name is dali
mediaPlayer.start(); //start the song
mediaPlayer.setLooping(true); //set the song to loop if you want it play forever (true) and if you dont want to loop (false)
}
(let say this code is in MainActivity.class) whenever activity that you dont want to play the song just call
MainActivity.mediaPlayer.stop();

Related

android - Why MediaPlayer delayes in playing mp3 audio?

I made a small app to practice audio playing in android using MediaPlayer, the app works great but there is a small delay of 1 second after clicking the play button and it's noticeable, I noticed this happens only when starting the audio file, when paused it resumes immediately with no delay,I googled around and seen people suggests using SoundPool instead of MediaPlayer but SoundPool is recommended for short audio clips while my app is playing a full song, what's the cause of this delay? is there a fix or work around this issue?
Here's my code:
private MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMediaPlayer = MediaPlayer.create(this,R.raw.this_is_america);
Button btnPlay = findViewById(R.id.btnPlay);
Button btnPause = findViewById(R.id.btnPause);
Button btnStop = findViewById(R.id.btnStop);
btnPlay.setOnClickListener(this);
btnPause.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnPlay:
Toast.makeText(getApplicationContext(), "Playing song",
Toast.LENGTH_SHORT).show();
mMediaPlayer.start();
break;
case R.id.btnPause:
Toast.makeText(getApplicationContext(), "Pausing song",
Toast.LENGTH_SHORT).show();
mMediaPlayer.pause();
break;
case R.id.btnStop:
Toast.makeText(getApplicationContext(), "Song stopped",
Toast.LENGTH_SHORT).show();
mMediaPlayer.reset();
mMediaPlayer = MediaPlayer.create(this,R.raw.this_is_america);
break;
}
}
Update: Turned out to be the mp3 audio file had silent pause at the beginning , tried another song and it works fine no noticeable delays , thank you greeble31 for suggesting to check that.
Your song has a silent pause at the beginning ;)
As #Lucefer mentioned, the Android platform has some small unavoidable latency due to the implementation of the audio stack. Or, at least it did a few years back, not sure what the current state of affairs is. At any rate, this delay is generally far too small (~10ms) to notice at the beginning of an audio file; it has more to do with response times for apps that simulate musical instruments and the like.
There is an audio latency issue in the Android operating system. There is a few milliseconds delay while audio recording and audio playing. You can learn more about this by navigating below URLs. And this latency is related to the device types.
https://developer.android.com/ndk/guides/audio/audio-latency
https://source.android.com/devices/audio/latency/measurements
You can use a native toolkit or native program (C, C++ ndk base) to minimize this latency. But you cannot do reduce it to 0Seconds. only minimize the latency.
There is https://superpowered.com/superpowered-android-media-server . You can get support from this but as I know you need to pay for it. I didn't try it. Therefore i don't know how much it reduced the latency.
If you want to remove silent part from your mp3. you can use ffmpeg wrapper for it. Go to https://github.com/WritingMinds/ffmpeg-android-java link there is a working ffmpeg wrapper for Android. you can easily use it.
using FFMPEG with silencedetect to remove audio silence you can find relevant FFmpeg command for it by navigating to this.
in the wrapper you don't need ffmpeg part. You need to replace it from -y. You can get those details when navigate to that wrapper

Strange issue with intent startActivity causing my scanner to not work properly

So, after I finish my scanner activity with
btn_take_photo.setOnClickListener(new FloatingActionButton.OnClickListener() {
#Override
public void onClick(View view) {
String carde = cardnumberbox.getText().toString().trim();
if (carde.matches("")) {
Toast.makeText(getApplicationContext(), getString(R.string.Skan_Udfyld_Kort_Nummer), Toast.LENGTH_SHORT).show();
cardnumberbox.requestFocus();
return;
}
Intent i = new Intent(ScanActivity.this, CameraActivity.class);
i.putExtra("EXTRA_SESSION_ID", carde);
startActivity(i);
}
});
to go to my cam activity so I can take some pictures and go back with
public void btn_aprove2(View view) {
Intent i = new Intent(CameraActivity.this, ScanActivity.class);
String counts = count.getText().toString().trim();
i.putExtra("EXTRA_SESSION_IDs", counts);
String carde = cardnumberbox2.getText().toString().trim();
i.putExtra("EXTRA_SESSION_ID", carde);
startActivity(i);
finish();
to the scanneractivity again. My scanner does not work properly
but if I then press the back button it does go back to the scanneractivity again instead of my menu so it seems like the scanneractivity is running twice and only 1 of them are functional but is here where it confuses me
cause if do not press the btn_aprove2 button and just use the back button instead
i gets the exact same issue but here my scanneractivity is not runned twice as when i press the back button it just takes me back to the menu
a video of the issue
by removing my screen orientation from the manifest (so i can rotate it)
my scanner do now work but only if i first rotate to landscape and rotate it back to potrait
and i see in the log is that it is only calling the oncreate when rotating and only on resume and pause on the button's(startactivity/finnish)
I am totally lost on how to get this to work.
on github with api demo and documentation in the wiki and with thoose classes that are being used
If you just jump to the Camera activity to get some data, I'd recommend you to start the activity for a result (startActivityForResult) without finishing the Scanner activity at all. This would give you a proper working back stack (using back button to go back from Camera to Scanner).
Besides that why are you using i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);? You are starting a new activity and finishing the old one. I don't see why this flag is really needed. What is your android:launchMode in your manifest and are you sure you know what FLAG_ACTIVITY_NEW_TASK is doing and it is what you want?
Anyways from what you told us it looks like your example really should utilize startActivityForResult() without calling finish():
Press menu button on some activity
Start camera and do something
Press some button to start Scanner
Scan something and finish the scanner with the result (or cancel the scanner by clicking back)
Retrieve the result of the scanner in the camera and do something with it or continue with the previous workflow when scanner was cancelled
Once you are finished with your workflow, finish the camera so you end up in your activity where you started the camera

Android QR Scanner: How to quit ZXingScannerView.ResultHandler to get back to where I came from

In my first steps in exploring Android I now start with QR scanning.
Works all pretty well. But I am not able to come back from the ResultHandler after read the QR successfully to my MainActivity.
public class MainActivity extends AppCompatActivity implements
ZXingScannerView.ResultHandler
{
private ZXingScannerView mScannerView
....
#Override
public void handleResult(Result rawResult)
{
// my results are ok in rawResult
// the scanner does not scan anymore but it is still there
// how to go back to my main activity???
}
public void ClickButton (View view)
{
mScannerView = new ZXingScannerView(this);
setContentView(mScannerView);
mScannerView.setResultHandler(this);
mScannerView.startCamera();
}
}
}
I tried
mScannerview.stopCameraPreview
mScannerView.stopCamera
this.finish
setContentView(R.layout.activity_main); // shows my activity_main
// but I can not click anything
Thanks!!
EDIT
I added some code to describe it a bit better. The idea is from
https://www.numetriclabz.com/android-qr-code-scanner-using-zxingscanner-library-tutorial/
Your question isn't clear but I'm assuming you want to restart the scan process. Normally, you'd have to restart the SurfaceHolder to be in preview mode. Luckily for you the ZXingScannerView already has a method to do that. Call mScannerView.resumeCameraPreview(this) to restart the scan process.
Otherwise can you clarify? You say you want to go back but you're already in MainActivity
If you want to go back into activities/fragments stack you can try Activity.onBackPressed()
if you are in a fragment you must call this method against attached Activity
What do you want is not going back to your activity. You want to restore activity's layout.
I think the better choice is to add ScannerView to your activity's layout file with android:visibility="gone". Then in on click you can get this view and change it's visibility to VISIBILE.
Then when you have handled scanning result, you can reset yuoir ScannerView to visibility = GONE
I too was stuck with this problem for an hour, just like you. And later realised..
To solve this problem DON NOT implementing the ZXingScannerView in the same activity or fragment. Instead start a new activity when you click the button and this activity is just for the ZXingScannerView
Once the Scan is done finish and pass the data back to your activity or fragment
Just restart your MainActivity before this.finish()
the code below will start your main activity through intent...
worked fine for me
startActivity(new Intent(this,MainActivity.class));
this.finish();
remove from onCreate method this line setContentView(your layout) and when you finish scan write it after you stoped the camera then you can use your layout after scan
I had a bit of a look into android concepts and activities.
I put the QR handling in a 2nd activity and it worked well with the finish ().
Thanks for help anyway!!
I think it's too late, but I came with the same problem and I had so find a solution by myself.
You were on the right way, you need two steps more.
I called the methods where I link and set the listener of any buttons
There are the methods
Basically you were right where you set the content view, but you need to give the buttons their functionality back.
(I know its late, but better late than never). Good luck!

When bringing Android activities from the stack to the front, how do I refresh (reinitialize) them? So to run onCreate again etc

If I'm bringing Android activities from the stack to the front, how do I refresh them? So to run onCreate again etc.
My code below, in conjunction with setting activities in the Android manifest to android:launchMode="singleTask" allows me to initiate an activity if that activity is not already active within the stack, if it is active within the stack it is then brought to the front.
How do I then, if the activity is brought to the front refresh it so that onCreate is ran again etc.
Intent intent = new Intent(myActivity.this,
myActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
I think FLAG_ACTIVITY_CLEAR_TOP will resolved your problem:
Intent intent = new Intent(myActivity.this, myActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
I don't think there is an explicit way to refresh onCreate, perhaps you may want to add the code you want reloaded into onResume.
This workaround may work if you want to keep your code in onCreate.
finish();
startActivity(getIntent());
If all you want to do is refresh the content, you should override the onResume method, and add in the code to perform the refresh in this method. To do this, use the following code within the activity that you want to perform the refresh, (ie, not the same activity that you are calling startActivity() from):
#Override
protected void onResume(){
super.onResume();
//add your code to refresh the content
}
Tip: If you are using Android Studio, press Alt+Insert (while you have the Java file open), then click Override Methods, find onResume, and it should provide you with a basic template for the method.
The diagram I added shows the order that the methods are run (this is known as the Activity Lifecycle). onCreate() is run whenever an Activity is first created, followed by onStart(), followed by onResume(). As you can see, when a user returns to an Activity, onCreate() is not run again. Instead, onResume() is the first method that is called. Therefore, by putting your code into the onResume() method, it will be run when the user returns to the activity. (Unlike onCreate(), which will not be run again).
Extra info: Since you will be initially setting the data in onCreate() and then refreshing it within onResume(), you might want to consider moving all of your code used to initially set the data to onResume() as well. This will prevent redundancy.
Edit: Based on your following comment, I can give the following solution:
I'm wanting to properly refresh the page, e.g. if there is a variable count initialised at 0. And though running the activity it's has became equal to 300. When the activity is called (intent) then refreshed, count will once again be equal to it's initial value. Do you know how to do this?
Without your current activity's code, there is not much to work with, but here is some pseudo-code as to how I would accomplish your problem:
public class MyActivity extends Activity {
TextView numberTextView;
int numberToDisplay;
#Override
protected void onCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(myContent);
numberTextView = (TextView) findViewById(R.id.numberTextView);
numberTextView.setText(numberToDisplay+"")//converts the integer to a string
}
#Override
protected void onResume(){
super.onResume();
numberToDisplay = 0;
numberTextView.setText(numberToDisplay+"");
}
}

How to navigate back to main activity without a button

I'm accustomed to using an intent to launch a new activity when a button is pressed.
But the app that I'm making uses a list view, which means I want to be able to go back from my searching activity to the main activity by using the phone's back button.
I was reading and experimenting with different types of android methods, this one in particular which seemed simple but doesn't work, or perhaps I'm doing something completely different.
public void onBackPressed()
{
Intent setIntent = new Intent(this,MainActivity.class);
startActivity(setIntent);
finish();
}
Doesn't Android's onBackPressed method respond to any android phone's back button?
Thank you for your help.
You forgot to call super.onBackPressed() inside onBackPressed() method, you dont need to start a new intent to go back.
In your search activity override the onBackPressed() method and call it from wherever you want in the activity.
it should be like this.
#Override
public void onBackPressed(){
super.onBackPressed();
}

Categories

Resources