I'm very new to Android development and would like to know how to play a SoundPool sound within a broadcastreceiver?
I read somewhere that using SoundPool is the way go play the sound but I don't know how to set it up properly.
I have some sound files such as wave and mp3 files in my Eclipse res\raw folder. I would like to play a file called half.wav
Can you show example code I need to place into my broadcastreceiver?
Here is a first attempt at the code but I do get an error stating that soundID = soundPool.load(this, R.raw.half, 1);
"The Method Load(Context, Int, Int) In The Type SoundPool Is Not Applicable..."
Here is the code for the class:
package ChimeMe.BigBen;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import android.os.Bundle;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
public class AlarmReceiver extends BroadcastReceiver {
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
#Override
public void onReceive(Context context, Intent intent) {
try {
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.half, 1);
Toast.makeText(context, "This is the alarm.", Toast.LENGTH_SHORT)
.show();
} catch (Exception e) {
Toast.makeText(
context,
"There was an error somewhere, but we still received an alarm",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
Thanks in advance.
Truly,
Emad
If it is just one sound you want to play I think using the MediaPlayer would be quicker and easier...
This is the code from an app of mine that plays a beep every 30 minutes when this Broadcastreceiver runs
public class Gameloop extends BroadcastReceiver {
MediaPlayer mp = null;// Here
private static final String TAG = "VPET";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Loop running");
if (Pet.isAlive == true) {
mp = MediaPlayer.create(context, R.raw.beep);//Onreceive gives you context
mp.start();// and this to play it
} else {
}
}
}
}
Related
Getting an error in intellij that states I have not defined a onPrepared method in my setOnPreparedListener class. Have reviewed the documentation and my code for the onPrepared method matches what's defined.
Code:
import android.app.IntentService;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.util.Log;
import java.io.IOException;
/**
* Created by tim on 4/19/2017.
*
*/
public class TonePlayerIntentService extends IntentService implements MediaPlayer.OnErrorListener,
MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener{
private static final String LOG_TAG = "actotracker " + TonePlayerIntentService.class.getSimpleName();
MediaPlayer mMediaPlayer = null;
Uri chime = null;
public TonePlayerIntentService() {
super(LOG_TAG);
}
/**
* called everytime an intent is launched
*/
#Override
public void onCreate() {
super.onCreate();
chime = Uri.parse("android.resource://"+getApplicationContext().getPackageName()+"//raw//chime.mp3");
}
/**
* Handles incoming intents.
* #param intent The Intent is provided (inside a PendingIntent) when requestActivityUpdates()
* is called.
*/
#Override
protected void onHandleIntent(Intent intent) {
Log.d(LOG_TAG,"IN onHandleIntent");
this.onStartCommand();
}
public int onStartCommand(){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setLooping(false);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mMediaPlayer.setDataSource(getApplicationContext(), chime);
}catch (IOException ie){
DatabaseProcessor.getInstance().logErrorEvent(ie);
}
mMediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener(){
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
cleanUpPlay();
return true;
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
cleanUpPlay();
}
});
return 1;
}
public void cleanUpPlay(){
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
The error message states that onPrepared(MediaPlayer) must be defined in the setOnPreparedListener class.
Would appreciate information on what I did wrong. Happily provide more information if requested.
Updated with complete code.
Try calling mMediaPlayer.prepareAsync(); after you have set your OnPreparedListener
Edit: remove implements and the classnames behind it. Your class is not implementing any interfaces, since you are implementing them inline, and remove this line as well.
mMediaPlayer.setOnCompletionListener(this);
I'm making game in OpenGL 2.0 and I have problems with sounds, because sounds slow down my application and FPS decrease about 20 frames. I implement service for sounds and run it on new thread, but problem is same. MediaServer use more CPU than my application with lot of sprites.
I play only three sounds with total size less than 0.5 MB.
This is my code:
package com.filsoft.mouse;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
public class Sound extends Service implements OnCompletionListener {
private final IBinder mBinder = new LocalBinder();
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
MediaPlayer[] mediaPlayer=new MediaPlayer[3];
public ServiceHandler(Looper looper) {
super(looper);
mediaPlayer[0] = MediaPlayer.create(getApplicationContext(), R.raw.sound1);
mediaPlayer[0].setLooping(true);
mediaPlayer[1] = MediaPlayer.create(getApplicationContext(), R.raw.sound1);
mediaPlayer[1].setLooping(true);
mediaPlayer[2] = MediaPlayer.create(getApplicationContext(), R.raw.sound1);
mediaPlayer[2].setLooping(true);
try {
for(int i=0;i<3;i++)
mediaPlayer[i].prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void handleMessage(Message msg) {
play(msg.arg1);
}
public void stopAll()
{
if (mediaPlayer[0].isPlaying()) {
mediaPlayer[0].pause();
}
if (mediaPlayer[1].isPlaying()) {
mediaPlayer[1].pause();
}
if (mediaPlayer[2].isPlaying()) {
mediaPlayer[2].pause();
}
}
public void play(int idx)
{
stopAll();
if (!mediaPlayer[idx].isPlaying()) {
mediaPlayer[idx].start();
}
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("Audio",
Process.THREAD_PRIORITY_URGENT_AUDIO);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
public void startPlay(int idx)
{
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = idx;
mServiceHandler.sendMessage(msg);
}
public class LocalBinder extends Binder {
public Sound getService() {
return Sound.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public void onDestroy() {
}
public void onCompletion(MediaPlayer _mediaPlayer) {
stopSelf();
}
}
Instead of creating multiple MediaPlayers, you should use a SoundPool - a class specifically designed to play multiple streams simultaneously such as found in games. Looping sounds is also very easy:
Sounds can be looped by setting a non-zero loop value. A value of -1 causes the sound to loop forever. In this case, the application must explicitly call the stop() function to stop the sound. Any other non-zero value will cause the sound to repeat the specified number of times, e.g. a value of 3 causes the sound to play a total of 4 times.
I tried to play an audio file from res/raw folder, here is the code, which I used to play the file, this is not generating any error and my device volume is max, but not getting any sound. I tried MP3 and WAV files.
public void btnPlay(View v) {
MediaPlayer mPlayer = MediaPlayer.create(con, R.raw.horse);
try {
mPlayer.start();
}catch (Exception e) {
e.printStackTrace();
Toast.makeText(con,e.toString(),Toast.LENGTH_SHORT).show();
}
}
I'm getting following message on LogCat after start
02-07 17:50:42.331: I/MediaPlayer(16345): Don't send intent. msg.arg1 = 0, msg.arg2 = 0
Help me to resolve this issue and it will be appreciated.
int resID = getResources().getIdentifier("name of sound" , "name of folder", getPackageName());
MediaPlayer mediaPlayer = MediaPlayer.create(getBaseContext(), resID);
mediaPlayer.start();
If you want an easy way to play audio from the raw folder, try this code:
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
public class Main2Activity extends AppCompatActivity {
MediaPlayer mplayer;
public void play(View view) {
mplayer.start();
}
public void pause(View view) {
mplayer.pause();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mplayer =MediaPlayer.create(this, R.raw.ab);
}
}
m using service to play a audio file in background.
This is my PreviewServices class .
package com.hungama.myplay.activity;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.MediaController;
import android.widget.Toast;
public class PreviewServices extends Service {
private static final String TAG = "PreviewServices";
public static MediaPlayer player;
protected DataManager dataManager = DataManager.getInstance();
String song_uri, url;
private IBinder myBinder;
private boolean isplaying;
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class MyBinder extends Binder {
PreviewServices getService() {
return PreviewServices.this;
}
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate " + song_uri);
}
#Override
public void onDestroy() {
player.stop();
}
public void onPause() {
player.pause();
}
public double duration() {
return player.getDuration();
}
public void onStart(Intent intent, int startid) {
Bundle b = intent.getExtras();
song_uri = b.getString("song_uri");
Uri path = Uri.parse(song_uri);
player = MediaPlayer.create(this, path);
player.setLooping(false); // Set looping
player.start();
/ *player.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.d("song is completed","song is not playing now");
dataManager.setPreview_play(true);
}
});
*/
}
}
My PreviewServices is working fine,
in My Activity i want to show a message when my song will complete.
m using this code for this purpose.
PreviewServices preview=new PreviewServices();
MusicScreen.this.preview.player.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.d("song is complete","song complete");
}
});
I dont know Y its throws Null Pointer Exception in this line
MusicScreen.this.preview.player.setOnCompletionListener(new OnCompletionListener()
please suggest me where is problem.
thanks in advance.
Gaurav Gupta
I'm sure you'll get more responses if your code is displayed properly. Every line of code needs to have four spaces or a tab at the start of it. Try editing to fix it.
A simple thing you can do is break up the line like this (where you specify appropriate classes for x, y and z):
x = MusicScreen.this
y = x.preview
z = y.player
z.setOnCompletionListener(ETC.
Then you can see where it breaks down. Other than that, I don't understand your program so I can't help...
I need to increase voice, recorder from microphone on Android device.
I try to read buffer from AudioRecord and then write it to AudioTrack... It works, but with delay, because min buffer size, returned bu method AudioRecord.getMinBufferSize with frequency like 44100 is 4480 bytes.
Any ideas?
Thanks.
I have this code
AudioRecord and AudioTrack latency
But it happens to that there is a 20ms delay, and I need to solve it,
The code above seems that plays something but there is no mic input, does it work?
Thanks!
I noticed there is no threading code. I would recommend trying to thread the recording and playback aspects and see if that better avoids the latency. Fill the buffer in from the mic one thread, and read it out to the speaker in the other. Avoid buffer overflows and underruns by handling those situations with some action (e.g. clearing the buffer for overflows). In theory, one should keep up with the other.
package org.example.audio;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class AudioDemo extends Activity implements OnClickListener {
private static final String TAG = "AudioDemo";
private static final String isPlaying = "Media is Playing";
private static final String notPlaying = "Media has stopped Playing";
MediaPlayer player;
Button playerButton;
public void onClick(View v) {
Log.d(TAG, "onClick: " + v);
if (v.getId() == R.id.play) {
playPause();
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//player = MediaPlayer.create(this, R.raw.robotrock);
player.setLooping(false); // Set looping
// Get the button from the view
playerButton = (Button) this.findViewById(R.id.play);
playerButton.setText(R.string.stop_label);
playerButton.setOnClickListener(this);
// Begin playing selected media
demoPlay();
// Release media instance to system
player.release();
}
#Override
public void onPause() {
super.onPause();
player.pause();
}
// Initiate media player pause
private void demoPause(){
player.pause();
playerButton.setText(R.string.play_label);
Toast.makeText(this, notPlaying, Toast.LENGTH_LONG).show();
Log.d(TAG, notPlaying);
}
// Initiate playing the media player
private void demoPlay(){
player.start();
playerButton.setText(R.string.stop_label);
Toast.makeText(this, isPlaying, Toast.LENGTH_LONG).show();
Log.d(TAG, isPlaying);
}
// Toggle between the play and pause
private void playPause() {
if(player.isPlaying()) {
demoPause();
} else {
demoPlay();
}
}
}