try to do but can't loop my music from extranal on mobile
i don't know why not look at my code on setOnCompletionListener methods
sorry from my bad english ... Thx for watch
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_effects);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
updatePlaylist();
Uri video = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/Music/" + songs.get(0));
mMediaPlayer = MediaPlayer.create(this, video);
mMediaPlayer.start();
mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());
mEqualizer.setEnabled(true);
setupVisualizerFxAndUI();//อันนี้แสดง คลื่นเสียง
setupEqualizerFxAndUI();
mVisualizer.setEnabled(true);//อันนี้แสดง คลื่นเสียง
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mVisualizer.setEnabled(false);//อันนี้แสดง คลื่นเสียง
i++;
mMediaPlayer.reset();
if (i < songs.size()) {
try {
Uri video = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/Music/" + songs.get(i));
if (video != null) {
mMediaPlayer = MediaPlayer.create(AudioFxActivity.this, video);
// mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());
mMediaPlayer.start();
}
} catch (Exception ex) {
// report a crash
Log.v(getString(R.string.app_name), ex.getMessage());
}
} else {
// done with media player
mMediaPlayer.release();
mMediaPlayer = null;
}
}
});mMediaPlayer.start();
}
this is my problems
Related
I am trying to record calls on Android 8+ but getting error. Below is my code:
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/" + RECORDING_DIRECTORY);
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = getRecordingFileName() + "-";
//String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
recorder.start();
recordstarted = true;
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d(e);
} catch (IOException e) {
e.printStackTrace();
Log.d(e);
} catch (Exception ex) {
Log.d(ex);
}
I get the following error message:
2020-02-20 16:38:37.893 12635-12635/com.companyname.appname
W/System.err: java.lang.IllegalStateException: phoneIsInUse
2020-02-20 16:38:37.894 12635-12635/com.companyname.appname
W/System.err: at
android.media.MediaRecorder.start(MediaRecorder.java:1017)
Has anyone dealt with this or knows what is happening?
For recording Phone Calls on Android 8+.
API level 28 or higher, apps running in the background cannot access the microphone.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
The example activity below shows how to use MediaRecorder to record an audio file. It Also uses MediaPlayer to play the audio back.
public class AudioRecordTest extends AppCompatActivity {
private static final String LOG_TAG = "AudioRecordTest";
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
private static String fileName = null;
private RecordButton recordButton = null;
private MediaRecorder recorder = null;
private PlayButton playButton = null;
private MediaPlayer player = null;
// Requesting permission to RECORD_AUDIO
private boolean permissionToRecordAccepted = false;
private String [] permissions = {Manifest.permission.RECORD_AUDIO};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecordAccepted ) finish();
}
private void onRecord(boolean start) {
if (start) {
startRecording();
} else {
stopRecording();
}
}
private void onPlay(boolean start) {
if (start) {
startPlaying();
} else {
stopPlaying();
}
}
private void startPlaying() {
player = new MediaPlayer();
try {
player.setDataSource(fileName);
player.prepare();
player.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
private void stopPlaying() {
player.release();
player = null;
}
private void startRecording() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
recorder.start();
}
private void stopRecording() {
recorder.stop();
recorder.release();
recorder = null;
}
class RecordButton extends Button {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording);
if (mStartRecording) {
setText("Stop recording");
} else {
setText("Start recording");
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx) {
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
class PlayButton extends Button {
boolean mStartPlaying = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onPlay(mStartPlaying);
if (mStartPlaying) {
setText("Stop playing");
} else {
setText("Start playing");
}
mStartPlaying = !mStartPlaying;
}
};
public PlayButton(Context ctx) {
super(ctx);
setText("Start playing");
setOnClickListener(clicker);
}
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Record to the external cache directory for visibility
fileName = getExternalCacheDir().getAbsolutePath();
fileName += "/audiorecordtest.3gp";
ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
LinearLayout ll = new LinearLayout(this);
recordButton = new RecordButton(this);
ll.addView(recordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
playButton = new PlayButton(this);
ll.addView(playButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
}
#Override
public void onStop() {
super.onStop();
if (recorder != null) {
recorder.release();
recorder = null;
}
if (player != null) {
player.release();
player = null;
}
}
}
Make changes according to your project
this code referred from official website for more details follow official website
MediaRecorder overview
Need to pick another random track after stopping the previous one by clicking "stop" button
I'm playing a random track by clicking "play" button, stop it by clicking "stop" and then i need to randomize again, in other words, to pick another track.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button play36 = (Button) findViewById(R.id.threesix);
Button stop = (Button) findViewById(R.id.stop);
String[] listOfFiles = new String[0];
try {
listOfFiles = getAssets().list("");
final List<String> musicOnlyList = new ArrayList<>();
for (int i = 0; i < listOfFiles.length; i++) {
if (getExtension(listOfFiles[i]).equals("mp3"))
musicOnlyList.add(listOfFiles[i]);
}
final MediaPlayer mediaPlayer = new MediaPlayer();
play36.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int itemIndex = new Random().nextInt(musicOnlyList.size());
String file = musicOnlyList.get(itemIndex);
AssetFileDescriptor afd = null;
try {
afd = getAssets().openFd(file);
mediaPlayer.reset();
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mediaPlayer.stop();
mediaPlayer.reset();
}
});
} catch (IOException e) {
e.printStackTrace();
}
In this case i get the same track everytime i start and stop player, but need to randomize everytime by clicking "play" button
You need to pick a new random number inside the listener of play36:
Button play36 = (Button)findViewById(R.id.threesix);
Button stop = (Button)findViewById(R.id.stop);
String[] listOfFiles = new String[0];
try {
listOfFiles = getAssets().list("");
final List<String> musicOnlyList = new ArrayList<>();
for(int i = 0; i < listOfFiles.length; i++){
if (getExtension(listOfFiles[i]).equals("mp3"))
musicOnlyList.add(listOfFiles[i]);
}
final MediaPlayer mediaPlayer = new MediaPlayer();
play36.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int itemIndex = new Random().nextInt(musicOnlyList.size());
String file = musicOnlyList.get(itemIndex);
AssetFileDescriptor afd = null;
try {
afd = getAssets().openFd(file);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mediaPlayer.stop();
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
For some reason, the repeat and shuffle buttons are not doing anything.
The buttons previous and next work perfectly.
In my app I am communicating with my service through broadcasts.
mediaPlayer is a public static in my service class and I am importing it in other activity.
public static MediaPlayer mediaPlayer = new MediaPlayer(); (In Service.class)
Activity
This is the code for the buttons
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
tvSongListSize.setText((songIndex + 1) + "/" + songList.size());
updateProgressBar();
}
}
mBtnShuffle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isShuffle){
isShuffle = false;
Toast.makeText(getContext(), "Shuffle is off", Toast.LENGTH_SHORT ).show();
mBtnShuffle.setImageResource(R.drawable.ic_action_shuffle);
}else{
isShuffle = true;
Toast.makeText(getContext(), "Shuffle is on", Toast.LENGTH_SHORT).show();
mBtnShuffle.setImageResource(R.drawable.ic_shuffle_on);
isRepeat = false;
mBtnRepeat.setImageResource(R.drawable.ic_action_repeat);
}
}
});
mBtnRepeat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isRepeat){
isRepeat = false;
Toast.makeText(getContext(), "Repeat is off", Toast.LENGTH_SHORT).show();
mBtnRepeat.setImageResource(R.drawable.ic_action_repeat);
}else{
isRepeat = true;
Toast.makeText(getContext(), "Repeat is on", Toast.LENGTH_SHORT).show();
mBtnRepeat.setImageResource(R.drawable.ic_repeat_on);
isShuffle = false;
mBtnShuffle.setImageResource(R.drawable.ic_action_shuffle);
}
}
});
mBtnPlayPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
mBtnPlayPause.setImageResource(R.drawable.ic_action_play);
} else {
mediaPlayer.start();
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
mBtnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
nextSong();
}
});
mBtnPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prevSong();
}
});
Code in onCompletionListener
#Override
public void onCompletion(MediaPlayer mp) {
if (isRepeat){
//Store current songIndex in mSharedPreferences
StorageUtil storageUtil = new StorageUtil(getContext());
storageUtil.storeSongIndex(songIndex);
//Send media with BroadcastReceiver
Intent broadCastReceiverIntent = new Intent(Constants.ACTIONS.BROADCAST_PlAY_NEW_SONG);
if (getActivity() != null) {
getActivity().sendBroadcast(broadCastReceiverIntent);
}
}else if(isShuffle){
Random random = new Random();
songIndex = random.nextInt((songList.size() - 1) + 1);
tvSongListSize.setText((songIndex + 1) + "/" + songList.size());
//Store random songIndex in mSharedPreferences
StorageUtil storageUtil = new StorageUtil(getContext());
storageUtil.storeSongIndex(songIndex);
//Send media with BroadcastReceiver
Intent broadCastReceiverIntent = new Intent(Constants.ACTIONS.BROADCAST_PlAY_NEW_SONG);
if (getActivity() != null) {
getActivity().sendBroadcast(broadCastReceiverIntent);
}
}else if (songIndex < songList.size()-1){
mediaPlayer.reset();
nextSong();
tvSongListSize.setText((songIndex + 1) + "/" + songList.size());
}else{
songIndex = 0;
tvSongListSize.setText((1) + "/" + songList.size());
//Store random songIndex in mSharedPreferences
StorageUtil storageUtil = new StorageUtil(getContext());
storageUtil.storeSongIndex(songIndex);
//Send media with BroadcastReceiver
Intent broadCastReceiverIntent = new Intent(Constants.ACTIONS.BROADCAST_PlAY_NEW_SONG);
if (getActivity() != null) {
getActivity().sendBroadcast(broadCastReceiverIntent);
}
}
}
Broadcast receiver
private BroadcastReceiver NewSongBroadCastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
songList = new StorageUtil(getApplicationContext()).getSongs();
songIndex = new StorageUtil(getApplicationContext()).loadSongIndex();
if (songIndex != -1 && songIndex < songList.size()){
activeSong = songList.get(songIndex);
}else{
stopSelf();
}
stopSong();
mediaPlayer.reset();
if (mMediaSessionManager == null) {
try {
initMediaSession();
initMediaPlayer();
} catch (RemoteException e) {
e.printStackTrace();
stopSelf();
}
}
initMediaPlayer();
updateMetaData();
NotificationBuilder(PlaybackStatus.PLAYING);
}
};
The buttons mBtnShuffle and mBtnRepeat do not trigger onCompletion. They are just 2 ordinary buttons that you use to set the flags isShuffle and isRepeat.
onCompletion is triggered when a song has been completed.
So if you want something to happen when the 2 buttons are tapped you should put some code in their listeners.
I'm new to Android programming. I followed a mediaplayer tutorial but I'm now trying to make it more advance, the only problem is thats not working as expected.
When the song is finished it should start playing the next song, but doesn't update my seekbar (only updates Max) and it makes my buttons crash my app. I tried many things but can't fix it myself. If i press the next button however (before music track ends) the buttons and seekbar work.
What I'm want is my seekbar to reset for the new song and go again, and i want my buttons to work after the onCompletion next song.
Here my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
btPlay = (ImageButton) findViewById(R.id.btPlay);
btNxt = (ImageButton) findViewById(R.id.btNxt);
btPv = (ImageButton) findViewById(R.id.btPv);
btPlay.setOnClickListener(this);
btNxt.setOnClickListener(this);
btPv.setOnClickListener(this);
sb = (SeekBar) findViewById(R.id.seekBar);
updateSeekBar = new Thread() {
#Override
public void run() {
int TotalDuration = mp.getDuration();
int currentPosition = 0;
while (currentPosition < TotalDuration) try {
sleep(500);
currentPosition = mp.getCurrentPosition();
sb.setProgress(currentPosition);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
if (mp != null) {
mp.stop();
mp.release();
}
Intent i = getIntent();
Bundle b = i.getExtras();
mySongs = (ArrayList) b.getParcelableArrayList("songlist");
position = b.getInt("pos", 0);
u = Uri.parse(mySongs.get(position).toString());
mp = MediaPlayer.create(getApplicationContext(), u);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
try {
mp.stop();
mp.reset();
position = (position + 1) % mySongs.size();
u = Uri.parse(mySongs.get(position).toString());
mp = MediaPlayer.create(getApplicationContext(), u);
sb.setMax(mp.getDuration());
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
});
mp.start();
sb.setMax(mp.getDuration());
updateSeekBar.start();
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mp.seekTo(seekBar.getProgress());
}
});
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.btPlay:
if (mp.isPlaying()) {
mp.pause();
btPlay.setImageResource(R.drawable.play);
} else {
mp.start();
btPlay.setImageResource(R.drawable.pause);
}
break;
case R.id.btNxt:
try {
if (mp.isPlaying()) {
mp.stop();
mp.release();
position = (position + 1) % mySongs.size();
u = Uri.parse(mySongs.get(position).toString());
mp = MediaPlayer.create(getApplicationContext(), u);
mp.start();
sb.setMax(mp.getDuration());
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.btPv:
try {
if (mp.isPlaying()) {
mp.stop();
mp.release();
position = (position - 1 < 0) ? mySongs.size() - 1 : position - 1;
u = Uri.parse(mySongs.get(position).toString());
mp = MediaPlayer.create(getApplicationContext(), u);
mp.start();
sb.setMax(mp.getDuration());
}
} catch (Exception e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
Errors (in android Monitor):
java.lang.IllegalStateException
I m trying to play song by clicking a button in my application. There are two buttons in the application. Each button can play a different song. I allocated all those songs in Assets folder. There are total of two songs in the folder of Assets now.
public class AudioCollective implements MediaPlayer.OnPreparedListener, OnCompletionListener{
static String TAG = "AudioCollective====>";
Context mContext;
MediaPlayer mPlayer;
ArrayList<AssetFileDescriptor> array;
public AudioCollective(Context theContext){
mContext = theContext;
}
public void addSound(int SoundID){
array = new ArrayList<AssetFileDescriptor>();
AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(SoundID);
array.add(afd);
}
public void playSound() {
for (int i =0; i<array.size();i++) {
Log.i(TAG,"preparing audio " + array.get(i) );
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(array.get(i).getFileDescriptor());
} catch (IOException e) {
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
}
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
if (mPlayer != null) {
Log.d(TAG, "releasing audio now");
mPlayer.release();
mPlayer = null;
mediaPlayer.release();
//mediaPlayer = null;
}
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.i(TAG, "playing audio now");
mediaPlayer.start();
}
}
meanwhile in my MainActivity :
AudioCollective ac = new AudioCollective();
ac.addSounds(R.raw.na);
playButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
ac.playSound();
}
});
So, the problem is every time I clicked the button, the application play the two songs together instead of playing the required song. anyone can tell me why would this be happen?
Yes it because you are playing both of them at same in for loop.
Update your playSound() method pass value in it as argument.
To play first song pass 0 , To play second song pass 1 .
playSound(0) playSound(1)
public void playSound(int pos) {
Log.i(TAG,"preparing audio " + array.get(pos) );
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(array.get(pos).getFileDescriptor());
} catch (IOException e) {
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
}
}