sound not playing in android > icecream sandwich - java

I was using following code to play sound. Everything worked fine before ICS. But on ICS and higher versions no sound is heard. There is no error, but no sound can be heard.
EDIT: Note, the following code is triggered by a broadcase receiver. BroadCast receiver invokes a async task. In the post process method of asycn task the following method is called.
What could the error possibly be?
public static void playSound(final Context context, final int volume,
Uri uri, final int stream, int maxTime, int tickTime) {
//stopPlaying();
/*
if (stream < 0 || stream > 100) {
throw new IllegalArgumentException(
"volume must be between 0 and 100 .Current volume "
+ volume);
}*/
final AudioManager mAudioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int deviceLocalVolume = getDeviceVolume(volume,
mAudioManager.getStreamMaxVolume(stream));
Log.d(TAG,
"device max volume = "
+ mAudioManager.getStreamMaxVolume(stream)
+ " for streamType " + stream);
Log.d(TAG, "playing sound " + uri.toString()
+ " with device local volume " + deviceLocalVolume);
final int oldVolume = mAudioManager.getStreamVolume(stream);
// set the volume to what we want it to be. In this case it's max volume
// for the alarm stream.
Log.d(Constants.APP_TAG, "setting device local volume to " + deviceLocalVolume);
mAudioManager.setStreamVolume(stream, deviceLocalVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
final MediaPlayer mediaPlayer = new MediaPlayer();
golbalMMediaPlayer = mediaPlayer;
try {
final OnPreparedListener OnPreparedListener = new OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
Log.d(TAG, "onMediaPlayercompletion listener");
mp.start();
countDownTimer.start();
}
};
mediaPlayer.setDataSource(context.getApplicationContext(), uri);
mediaPlayer.setAudioStreamType(stream);
mediaPlayer.setLooping(false);
mediaPlayer.setOnPreparedListener(OnPreparedListener);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.d(Constants.APP_TAG, "Entered onCompletion listener of mediaplayer");
mAudioManager.setStreamVolume(stream, oldVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
try{
if(mediaPlayer != null && mediaPlayer.isPlaying()){
mediaPlayer.release();
}
}catch(Exception ex){
Log.e(Constants.APP_TAG, "error on oncompletion listener" ,ex);
}
}
});
CountDownTimer timer = new CountDownTimer(maxTime*1000, tickTime*1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.d(TAG, "tick while playing sound ");
}
#Override
public void onFinish() {
Log.d(TAG, "timer finished");
stopPlaying();
}
};
countDownTimer = timer;
mediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e(TAG, "problem while playing sound", e);
} finally {
}
}
LOGS:
:07-01 00:00:00.030: D/beephourly(9500): device max volume = 7 for streamType 5
07-01 00:00:00.030: D/beephourly(9500): playing sound content://media/internal/audio/media/166 with device local volume 7
07-01 00:00:00.030: D/beephourly(9500): setting device local volume to 7
07-01 00:00:00.080: D/beephourly(9500): vibrating with pattern = [J#428bae20
07-01 00:00:00.090: D/beephourly(9500): will show normal notification
07-01 00:00:00.100: D/beephourly(9500): notification is enabled
07-01 00:00:00.100: D/usersettings(9500): hr = 0
07-01 00:00:00.110: D/beephourly(9500): onMediaPlayercompletion listener
07-01 00:00:00.451: D/beephourly(9500): tick while playing sound
07-01 00:00:20.460: D/beephourly(9500): timer finished
07-01 00:00:20.460: D/beephourly(9500): got request to stop playing
07-01 00:00:20.460: D/beephourly(9500): cancelling countdowntimer
07-01 00:00:20.460: D/beephourly(9500): releasing mediaplayer now

Try this :
Playing sound
public class PlaySound extends Activity implements OnTouchListener {
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View view = findViewById(R.id.textView1);
view.setOnTouchListener(this);
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// 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.sound1, 1);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Getting the user sound settings
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
}
return false;
}
}
Layout file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Click on the screen to start playing" >
</TextView>
</LinearLayout>
Source link : http://www.vogella.com/tutorials/AndroidMedia/article.html#sound

Sometimes MediaPlayer objects have to be declared as a public variable or they will be deleted by the Dalvik Heap.
public final MediaPlayer mediaPlayer = new MediaPlayer();

private MediaPlayer mPlayer;
....
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
int iTmp = sp.load(getBaseContext(), R.raw.windows_8_notify, 1);
sp.play(iTmp, 1, 1, 0, 0, 1);
mPlayer = MediaPlayer.create(getBaseContext(), R.raw.windows_8_notify);
mPlayer.start();
mPlayer.setLooping(true); }
First , where all your privates are , before the onCreate, put the first line, then, Inside the onCreate start the music, just make sure to change the "windows_8_notify" to the name of the song you want.

I would Wrap the call in an IllegalStateException, run it through the debugger and see what you get.
Things to try
Set the boolean isPlaying=mp.isPlaying(); and check its value.
Try a mp.reset() before starting and see if it works.
Implement MediaPlayer.OnErrorListener and register the method with the media player.
See what error you get. This might be helpful.

LOGS
...streamType 5
StreamType 5 means STREAM_NOTIFICATION.
(Called from notification?)
It should be STREAM_MUSIC (3)
To check it's not ICS/device specific problem,
- place a sound file (sound_01.ogg or sound_01.mp3) under res/raw/ folder
- place buttons named start_button and stop_button in main_layout
and try this.
(I've checked this code with API10 and API19 emulator and sounds are played.)
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity
// implements MediaPlayer.OnPreparedListener
{
private MediaPlayer mediaPlayer;
private boolean isPrepared;
private boolean isPlaying;
private View start_button;
private View stop_button;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
Init();
}
#Override
protected void onResume()
{
super.onResume();
Load();
}
#Override
protected void onPause()
{
super.onPause();
Unload();
}
private void Init()
{
setVolumeControlStream(AudioManager.STREAM_MUSIC);
start_button = findViewById(R.id.start_button);
stop_button = findViewById(R.id.stop_button);
start_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Play();
}
});
stop_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Stop();
}
});
}
private void Load()
{
Unload();
// load from resource (res/raw/xx.ogg or .mp3)
// It's better to use thread
mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound_01); // On success, prepare() will already have been called
// mediaPlayer.setOnPreparedListener(this); // cannot set this listener (MediaPlayer.create does not return before prepared)
isPrepared = true;
}
private void Unload()
{
isPrepared = false;
if (null != mediaPlayer)
{
mediaPlayer.release();
mediaPlayer = null;
}
}
// #Override
// public void onPrepared(MediaPlayer mp)
// {
// isPrepared = true;
// }
private void Play()
{
// If you got "start called in state xx" error, no sound will be heard.
// To reset this error, call reset(), setDataSource() and prepare()
// (for resources: call release() and create())
if (!isPrepared)
{
return;
}
mediaPlayer.start();
isPlaying = true;
}
private void Stop()
{
// Do not omit this check
// or you will get "called in wrong state" errors
// like "pause called in state 8"
// and error (-38, 0)
if (!isPlaying)
{
return;
}
isPlaying = false;
mediaPlayer.pause();
mediaPlayer.seekTo(0);
}
}
If it's ICS/device specific, these links may help. (A little old...)
after small sound is played, no sound will be heard
Issue 35861: Low Volume sound cut out - ICS Galaxy Note
audio focus bug
Issue 1908: No Audio with Android 4.0.4 ICS Galaxy Tab 10.1
device specific problem
No sound during calls (samsung galaxy s3 problem)

You might have a problem if you are using other AsyncTasks or the SerialExecutor in another task elsewhere in your program (and you may not even know it if you are using third party SDK's).
See the post here:
https://code.google.com/p/android/issues/detail?id=20941
I'm suggesting this because your sound "tick" isn't working either. So it isn't a matter of AudioPlayer executing with an incorrect setting necessarily, but rather some other task appears to be blocking it until that task stops, and it probably is a task that runs concurrently with when you expect to hear sound.

Related

Notification transport controls dont appear to be doing anything

I have created an app that can play audio using a MediaBrowserServiceCompat and a MediaSessionCompat. As per the instructions on the android developers website, I have created a notification in the MediaSessionCompat.Callback().onPlay() method that uses MediaStyle to provide transport controls which are supposed to connect to my media session when provided with the appropriate token. The in app controls for playing and pausing work as expected, even when the app is closed and opened again. The service appears to be running as expected.
The problem however, is that although the notification appears as expected, the included pause button is seemingly unable to do anything. And despite the fact that the android developers example indicates that a cancel button should be present, it is not. Furthermore the example also indicated that the service should be stoppable by swiping the notification away, and yet it does not.
Suffice it to say, nothing in the following code snippet is working correctly. Except that the notification does, in fact, appear.
private NotificationCompat.Builder getMediaNotificationBuilder() {
Intent contentIntent = new Intent(mContext, MainActivity.class);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingContentIntent = PendingIntent.getActivity(mContext, 0, contentIntent, 0);
MediaControllerCompat controller = mMediaSession.getController();
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, "PODCAST");
builder
.setContentTitle("PODCAST")
.setContentText("THIS IS A PLACE HOLDER.")
.setSubText("Still a place holder.")
// Enable launching the player by clicking the notification
.setContentIntent(pendingContentIntent)
// Stop the service when the notification is swiped away
.setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(mContext, PlaybackStateCompat.ACTION_STOP))
// Make the transport controls visible on the lockscreen
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
// Add an app icon and set its accent color
// Be careful about the color
.setSmallIcon(R.drawable.ic_launcher_background)
.setColor(ContextCompat.getColor(mContext, R.color.colorPrimaryDark))
// Add a pause button
.addAction(new NotificationCompat.Action(
R.drawable.ic_pause, "Pause",
MediaButtonReceiver.buildMediaButtonPendingIntent(mContext,
PlaybackStateCompat.ACTION_PAUSE)))
// Take advantage of MediaStyle features
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mMediaSession.getSessionToken())
.setShowActionsInCompactView(0)
// Add a cancel button
.setShowCancelButton(true)
.setCancelButtonIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(mContext,
PlaybackStateCompat.ACTION_STOP)));
return builder;
}
I then go on to pass this notification to
startForground(1, getMediaNotificationBuilder().build())
and then start the service.
I will be happy to share the entire app source code if it is necessary. I am sure that I have missed something very simple here.
As I suspected I was missing something very simple. In order for my MediaBrowserServiceCompat subclass to react to my notification controls, I needed to override onStartCommand from the Service base class and pass the Intent there in to my MediaSessionCompat object. After doing this, the MediaSessionCompat.Callback should handle the command assuming it has been programed to do so. This is what the code for that looks like, inside of my MediaBrowserService class.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(LOG_TAG, "onStartCommand(): received intent " + intent.getAction() + " with flags " + flags + " and startId " + startId);
MediaButtonReceiver.handleIntent(mMediaSession, intent);
return super.onStartCommand(intent, flags, startId);
}
After adding this code you should see the method in logcat as well. Just in case anyone out there is still missing something, you will at least know that the code is responding to your button presses.
EDIT:
As for stopping the Service by swiping the notification, I was misunderstanding the interaction between the notification and the user. The notification CAN be swiped away by the user but only if the media is PAUSED first. This paradigm is further supported by the standard media player app's notification controls. This makes sense as the user might accidentally swipe away the controls while in the middle of listening to something otherwise.
In addition I have decided to include the entire source code for my MediaBrowserServiceCompat class in hopes that this additional information will
provide some context for disscussion
public class MediaPlaybackService extends MediaBrowserServiceCompat {
private static final String LOG_TAG = "MediaPlaybackService";
private static final String MY_MEDIA_ROOT_ID = "media_root_id";
private static final String MY_EMPTY_MEDIA_ROOT_ID = "empty_root_id";
// Volume levels: Normal and Duck
// VOLUME_DUCK is the volume we set the media player to when we lose audio focus, but are allowed to reduce the volume instead of stopping playback.
public static final float VOLUME_DUCK = 0.2f;
public static final float VOLUME_NORMAL = 1.0f;
private MediaSessionCompat mMediaSession;
private MediaPlayer mMediaPlayer;
// Current local media player state
private PlaybackStateCompat.Builder mStateBuilder;
private int mState = PlaybackStateCompat.STATE_NONE;
private final class MediaSessionCallback extends MediaSessionCompat.Callback implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, AudioManager.OnAudioFocusChangeListener{
private Context mContext;
private AudioManager mAudioManager;
// Declare the "SHIT THAT'S LOUD" intent, any broadcast receiver
// that is connected to it will trigger when the headphones come unplugged
private IntentFilter shitThatsLoudIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BroadcastReceiver shitThatsLoudBroadcastReceiver = new BroadcastReceiver() {
// TODO: Put me in a separate class
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "SHIT THATS LOUD! The headphones have come unplugged!");
}
};
private MediaSessionCallback(Context context) {
super();
mContext = context;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
initMediaPlayer();
}
private void initMediaPlayer() {
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource("https://www.blogtalkradio.com/kylekulinski/2018/10/15/the-kyle-kulinski-show.mp3");
mMediaPlayer.setOnPreparedListener (this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnErrorListener (this);
mMediaPlayer.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, ".initMediaPlayer(): IOException: "+e.toString());
}
}
private void mediaPlay() {
registerReceiver(shitThatsLoudBroadcastReceiver, shitThatsLoudIntentFilter);
if (mAudioManager.requestAudioFocus(getAudioFocusRequest()) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d(LOG_TAG, "Audio focus request granted.");
mState = PlaybackStateCompat.STATE_PLAYING;
mStateBuilder.setActions(PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_STOP);
mStateBuilder.setState(mState, mMediaPlayer.getCurrentPosition(), 1.0f, SystemClock.elapsedRealtime());
mMediaSession.setPlaybackState(mStateBuilder.build());
mMediaSession.setActive(true);
mMediaPlayer.start();
startService(new Intent(mContext, MediaPlaybackService.class));
startForeground(1, getMediaNotificationBuilder().build());
}
}
private void mediaPause() {
unregisterReceiver(shitThatsLoudBroadcastReceiver);
mState = PlaybackStateCompat.STATE_PAUSED;
mStateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_STOP);
mStateBuilder.setState(mState, mMediaPlayer.getCurrentPosition(), 1.0f, SystemClock.elapsedRealtime());
mMediaSession.setPlaybackState(mStateBuilder.build());
mMediaPlayer.pause();
stopForeground(false);
}
private void releaseResources() {
mMediaSession.setActive(false);
mAudioManager.abandonAudioFocusRequest(getAudioFocusRequest());
unregisterReceiver(shitThatsLoudBroadcastReceiver);
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
}
stopSelf();
stopForeground(true);
}
private NotificationCompat.Builder getMediaNotificationBuilder() {
Intent contentIntent = new Intent(mContext, MainActivity.class);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingContentIntent = PendingIntent.getActivity(mContext, 0, contentIntent, 0);
MediaControllerCompat controller = mMediaSession.getController();
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, "PODCAST");
builder
.setContentTitle("PODCAST")
.setContentText("THIS IS A PLACE HOLDER.")
.setSubText("Still a place holder.")
// Enable launching the player by clicking the notification
.setContentIntent(pendingContentIntent)
// Stop the service when the notification is swiped away
.setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(mContext, PlaybackStateCompat.ACTION_STOP))
// Make the transport controls visible on the lockscreen
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
// Add an app icon and set its accent color
// Be careful about the color
.setSmallIcon(R.drawable.ic_launcher_background)
.setColor(ContextCompat.getColor(mContext, R.color.colorPrimaryDark))
// Add a pause button
.addAction(new NotificationCompat.Action(
R.drawable.ic_pause, "Pause",
MediaButtonReceiver.buildMediaButtonPendingIntent(mContext,
PlaybackStateCompat.ACTION_PLAY_PAUSE)))
// Take advantage of MediaStyle features
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mMediaSession.getSessionToken())
.setShowActionsInCompactView(0)
// Add a cancel button
.setShowCancelButton(true)
.setCancelButtonIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(mContext,
PlaybackStateCompat.ACTION_STOP)));
return builder;
}
#Override
public void onPlay() {
super.onPlay();
Log.d(LOG_TAG, "I tried to play music");
mediaPlay();
}
#Override
public void onPause() {
super.onPause();
Log.d(LOG_TAG, "I Tried to pause");
mediaPause();
}
#Override
public void onStop() {
super.onStop();
releaseResources();
}
private AudioFocusRequest getAudioFocusRequest() {
// Request audio focus for playback, this registers the afChangeListener
AudioAttributes attrs = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setOnAudioFocusChangeListener(this)
.setAudioAttributes(attrs)
.build();
return audioFocusRequest;
}
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
Log.d(LOG_TAG, "Audio focus has been restored after it was transiently arrested by and intrusive app. We can now start playing audio normally again.");
mMediaPlayer.setVolume(VOLUME_NORMAL, VOLUME_NORMAL);
mediaPlay();
break;
case AudioManager.AUDIOFOCUS_LOSS:
Log.d(LOG_TAG, "Audio focus was lost flat out. Save what we were doing so we don't forget about it later.");
mediaPause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Log.d(LOG_TAG, "Audio focus was lost (Transient) but we might get it back later, still stop and save though.");
mediaPause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.d(LOG_TAG, "Audio focus was lost but was just need to keep it down instead of stopping.");
mMediaPlayer.setVolume(VOLUME_DUCK, VOLUME_DUCK);
break;
default:
Log.d(LOG_TAG, "Ignoring unsupported audio focus change: "+focusChange);
break;
}
}
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(LOG_TAG, "MediaSessionCallback.onPrepared(): MediaPlayer is prepared!");
// The media player is done preparing. That means we can start playing if we
// have audio focus.
}
#Override
public void onCompletion(MediaPlayer mp) {
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(LOG_TAG, "Media player error: what=" + what + ", extra=" + extra);
return false; // true indicates we handled the error
}
}
#Override
public void onCreate() {
super.onCreate();
// Create a MediaSessionCompat
mMediaSession = new MediaSessionCompat(this, LOG_TAG);
// Set the session's token so that client activities can communicate with it.
setSessionToken(mMediaSession.getSessionToken());
// MediaSessionCallback() has methods that handle callbacks from a media controller
mMediaSession.setCallback(new MediaSessionCallback(this));
// Enable callbacks from media buttons and transport controls
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
);
// Set initial PlaybackState with ACTION_PLAY, so that media buttons start the player
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE
);
mMediaSession.setPlaybackState(mStateBuilder.build());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(LOG_TAG, "onStartCommand(): received intent " + intent.getAction() + " with flags " + flags + " and startId " + startId);
MediaButtonReceiver.handleIntent(mMediaSession, intent);
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public BrowserRoot onGetRoot(#NonNull String clientPackageName, int clientUid, #Nullable Bundle rootHints) {
return new BrowserRoot(MY_EMPTY_MEDIA_ROOT_ID, null);
}
#Override
public void onLoadChildren(#NonNull String parentMediaId, #NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
// Browsing not allowed
if (TextUtils.equals(MY_EMPTY_MEDIA_ROOT_ID, parentMediaId)) {
result.sendResult(null);
return;
}
// TODO: If in the future we decide that we do want this class to handle the podcast metadata
// Then we must adapt what ever data podcastFactory produces into a List of MediaBrowserCompat.MediaItem objects
// The constructor of MediaItem requires that a MediaDescription object be passed to it.
// MediaDescription has a builder class which contains methods for setting Title, Artist, Uri, etc...
// MediaDescription.Builder mMediaDescriptionBuilder = new MediaDescription.Builder();
// mMediaDescriptionBuilder.setTitle(String);
// mMediaDescriptionBuilder.setMediaUri(String);
// MediaDescription mMediaDescription = mMediaDescriptionBuilder.build()
// MediaBrowserCompat.MediaItem mMediaItem =
// new MediaBrowserCompat.MediaItem(
// mMediaDescription,
// int flags -> FLAG_BROWSABLE and/or FLAG_PLAYABLE
// );
// add MediaItem to SomeList
// result.sendResult(SomeList);
}

How to fade in and out music in MediaPlayer service

I am working on a mediaplayer service in the android studio and I want to fade in/out the sound when the service start/stop.
I have tried the solution from this thread :
Android Studio Mediaplayer how to fade in and out
, but it seems the code does not fit with my service. The music only plays for a split second then the music stopped.
BGMPlayer.java (Service)
public class BGMPlayer extends Service {
private MediaPlayer bgmusic1;
int volume = 0;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
bgmusic1 = MediaPlayer.create(this, R.raw.bgmusic1);
bgmusic1.setLooping(true);
bgmusic1.start();
FadeIn();
//we have some options for service
//start sticky means service will be explicity started and stopped
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
bgmusic1.stop();
}
private void FadeIn() {
final int FADE_DURATION = 3000; //The duration of the fade
//The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
final int MAX_VOLUME = 1; //The volume will increase from 0 to 1
int numberOfSteps = FADE_DURATION / FADE_INTERVAL; //Calculate the number of fade steps
//Calculate by how much the volume changes each step
final float deltaVolume = MAX_VOLUME / (float) numberOfSteps;
//Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
fadeInStep(deltaVolume); //Do a fade step
Log.d("DEBUG","MUSIC VOLUME IS NOW " + volume);
//Cancel and Purge the Timer if the desired volume has been reached
if (volume >= 1f) {
Log.d("DEBUG","MUSIC VOLUME REACHED 1");
timer.cancel();
timer.purge();
}
}
};
timer.schedule(timerTask, FADE_INTERVAL, FADE_INTERVAL);
}
private void fadeInStep(float deltaVolume) {
bgmusic1.setVolume(volume, volume);
volume += deltaVolume;
}
}
Activity.java
#Override
protected void onStart() {
super.onStart();
//music start
startService(new Intent(this, BGMPlayer.class));
Log.d("DEBUG","LoadingScreenStart");
}
#Override
protected void onStop() {
super.onStop();
//Stop the music
stopService(new Intent(this, BGMPlayer.class));
}
DEBUG Log
04-10 21:15:29.325 6147-6147/com.example.max.curerthegame D/DEBUG: LoadingScreenStart
04-10 21:15:29.643 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:29.893 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:32.159 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:32.410 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:32.660 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:34.672 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:34.927 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
04-10 21:15:49.765 6147-6183/com.example.max.curerthegame D/DEBUG: MUSIC VOLUME IS NOW 0
You could use a Runnable to repeatedly lower volume after a given time interval.
calling the function after writing it: musicVolumeF(0.2f);
MediaPlayer music;
//do this in onCreate
music = MediaPlayer.create(getApplicationContext(), R.raw.sunnybike2);
music.start();
Handler ha = new Handler();
Runnable mFadeRun;
Float musicVolumeF = 1.0f;
void musicFader(Float desiredVolume)
{
mFadeRun = new Runnable() {
#Override
public void run() {
// decrement the float value
musicVolumeF = musicVolumeF - 0.02f;
// so it does not go below 0
if (musicVolumeF < 0)
musicVolumeF = 0.0f;
// set the volume to the new slightly less float value
music.setVolume(musicVolumeF, musicVolumeF);
// so it stops if it's at about the desired volume
// you can change the 20 to make it go faster or slower
if (musicVolumeF > desiredVolume+0.02)
ha.postDelayed(mFadeRun,20);
}
};
// postDelayed re-posts the Runnable after the given milliseconds
ha.postDelayed(mFadeRun,20);
}

RTSP streaming IP camera MediaPlayer: error (100, 0)

Im trying to show a live stream from an ACTI IP camera on an android phone. The ACTI camera is set to stream H.264 Baseline with 320x240 resolution. An error keeps popping up after prepareAsync() is called.
W/IMediaDeathNotifier: media server died
W/AudioSystem: AudioFlinger server died!
E/MediaPlayer: Error (100,0)
E/MediaPlayer: error (100, 0)
I checked the URL format, tried removing the "?". I also tried the stream URL in VLC and it worked. Im running this on an Android Jelly Bean. Code is below
final static String RTSP_URL = "rtsp://192.168.34.52:7070?/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vo_ipphone);
mySurfaceView = findViewById(R.id.surface);
Log.i(TAG, "prepare surface holder");
_surfaceHolder = mySurfaceView.getHolder();
_surfaceHolder.addCallback(this);
_surfaceHolder.setFixedSize(320, 240);
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.i(TAG, "Prepared!");
_mediaPlayer.start();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.i(TAG, "Surface created");
_mediaPlayer = new MediaPlayer();
_mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
_mediaPlayer.release();
//create another mediaplayer preferrably in another thread
return false;
}
});
_mediaPlayer.setDisplay(_surfaceHolder);
Context context = getApplicationContext();
Map<String, String> headers = getRtspHeaders();
Uri source = Uri.parse(RTSP_URL);
try {
// Specify the IP camera's URL and auth headers.
Log.i(TAG, "Set data source");
_mediaPlayer.setDataSource(context, source, headers);
//_mediaPlayer.setDataSource(this, source);
// Begin the process of setting up a video stream.
Log.i(TAG, "set on prepared listener");
_mediaPlayer.setOnPreparedListener(this);
Log.i(TAG, "prepare async");
_mediaPlayer.prepareAsync();
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
_mediaPlayer.release();
}
It's looks like all line is true but Maybe error comes from wrong URL , url should like below
final static String RTSP_URL = "rtsp://192.168.34.52:7070/";
try this url without '?'
And also check your device internet and permission
Add to permission in AndroidManifest.xml if is not exist
<uses-permission android:name="android.permission.INTERNET" />
I hope it work

Activity whith pitch detect TarsosDSP no restart

I wrote a guitar tuner in music application. The main activity launch the tuner when click on button. The tuner works fine. But if I come back to main activity.
The Tuner activity start, but pitch detection does not.
The thread don't stop for the recorder.
I launch an activity Act_Accordage from the main activity with
public void clicAccordage(View v){
Intent intentAct_Accordage = new Intent(this, Act_Accordeur .class);
startActivity(intentAct_Accordage);
}
Here is my Act_Accordage activity
public final AudioDispatcher dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(22050, 2048, 0);
....
dispatcher.addAudioProcessor(new PitchProcessor(PitchEstimationAlgorithm.YIN, 22050, 2048, new PitchDetectionHandler() {
#Override
public void handlePitch(PitchDetectionResult pitchDetectionResult,
AudioEvent audioEvent) {
final float pitchInHz = pitchDetectionResult.getPitch();
if (Logo.interrupted()) {
return;
}
if (pitchInHz > -1) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// display name note and cursor ou UI thread
textFreqNote.setText(String.valueOf(pitchInHz) + " CREATE ");
Affcurseur(pitchInHz);
});
}
}
}));
new Thread(dispatcher, "Audio Dispatcher");
2***/I come back main with button or backbutton
public void onclicSetBackMain(View v) {
Act_Accordeur.this.finish();
Toast.makeText(Act_Accordeur.this, "Guitare accordée", Toast.LENGTH_LONG).show();}
Use dispatcher.stop(); to stop the Audio Dispatcher thread.It took me a long time in the official documentation but it was worth it.

Alarm ringing stops when cleared from ram

I am making an alarm clock which asks user to do a particular work in order to close the alarm when it rings. It is working fine but the problem is that if the user closes the alarm app from the recent activities while the alarm is ringing, the alarm stops ringing. I want that even if the user clears the app while its ringing, it should not stop ringing. It should only stop once the task given is completed. How can I implement this?
Edit #1: Activity that is called when alarm rings
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(LOG_TAG, "in AlarmAlert");
unlockScreen();
setContentView(R.layout.activity_alarm_alert);
Bundle bundle = this.getIntent().getExtras();
alarm = (Alarm) bundle.getSerializable("alarm");
alarmDatabase = new AlarmDatabase(this);
//Uri uri = alarm.getRingtonePath();
question = (TextView)findViewById(R.id.question);
answer = (TextView) findViewById(R.id.answer);
oldColors = answer.getTextColors();
diff = alarm.getDifficulty().toString();
questionString = GenerateMathsQuestion.generateQuestion(diff);
question.setText(questionString);
actualAnswer = EvaluateString.evaluate(questionString);
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int result = am.requestAudioFocus(focusChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setLooping(true);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
try {
mediaPlayer.setDataSource(this, Uri.parse(alarm.getRingtonePath()));
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
if(alarm.getIsVibrate()) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
long[] pattern = {1000, 200, 200, 200};
vibrator.vibrate(pattern, 0);
}
}
public void closeAlarm(){
Log.v(LOG_TAG, "will now stop");
mediaPlayer.stop();
if(vibrator!=null)
vibrator.cancel();
Log.v(LOG_TAG, "will now release");
mediaPlayer.release();
Log.v(LOG_TAG, "id of ringing alarm: " + alarm.getAlarmId());
alarm.setIsActive(false);
alarmDatabase.updateData(alarm);
cursor = alarmDatabase.sortQuery();
while(cursor.moveToNext()){
int id = cursor.getInt(cursor.getColumnIndex(AlarmDatabase.COLUMN_UID));
currentAlarm = alarmDatabase.getAlarm(id);
Log.v(LOG_TAG, "id of next alarm " + id);
if(currentAlarm != null) {
if (currentAlarm.getIsActive() == true) {
currentAlarm.scheduleAlarm(this, true);
break;
}
}
}
this.finish();
}
You should use Services. Take a look at it, that is what you want it. Generally you can make it to run an operation, and a service wont return any result. But it runs indefinitely even when you kill the app from task manager or free RAM.
I suggest this tutorial for reading about services.
UPDATE
Implement your activity with the service in the following way so it can talk with the layout and stops the alarm when required.
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}

Categories