UI not responding on screen orientation -Android - android

I am developing an application with mediaplayer. I have handled screen orientation with two layouts. I have used onsavedInstancestate and onrestoreinstancesstate. On screen rotation the layout changes and the mediaplayer state is retained but UI is not responding.
I have saved and retained the state of mediaplayer object
public Object onRetainNonConfigurationInstance()
{
HashMap<String,Object> player = new HashMap<String,Object>();
MediaPlayer instance = mp;
mp = null;
MediaPlayer instance1 = mp1;
mp1 = null;
player.put("mp", instance);
player.put("mp1", instance1);
return player;
}
if(getLastNonConfigurationInstance()!=null)
{
playerhandle = (HashMap<String, Object>) getLastNonConfigurationInstance();
mp = (MediaPlayer)playerhandle.get("mp");
if (mp == null)
{
mp = new MediaPlayer();
}
mp1 = (MediaPlayer)playerhandle.get("mp1");
if (mp1 == null)
{
mp1 = new MediaPlayer();
}
}
and also retained the data with onsavedinstancestate and onrestoreinstancestate .The mediaplayer retains the state after screen orientation(audio plays without interpretation on screen orientation) but the UI is not responding after orientation change. Unable to figure out the problem .....

Related

How to stop mediaplayer while playing on background?

I am developing a music player on android and the app has two activities (MainActivity and PlayActivity). In the MainActivity I have a listview with a list of songs and in the PlayActivity I have a button to listen and pause the music. The problem is that when go back to MainActivity and I select a new song from the listview, the first one keeps playing on background while the second one also starts playing. How can I stop the first song when I select a new one?
(I don't want to stop mediaplayer onBackPressed, I just want to stop the music when another song it's selected from listview and play a fresh song in PlayActivity)
EDIT: I'm using AsyncTask to start mediaplayer on PlayActivity: mp.prepareAsync();
You could try to stop MediaPlayer when onBackPressed()
MediaPlayer mp ; // mp is your MediaPlayer
#Override
public void onBackPressed() {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
super.onBackPressed();
}
private void playMusic() {
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
mp.release();
MediaPlayer copyMp = new MediaPlayer();
try {
copyMp.setDataSource("/path");
mp = copyMp;
mp.prepare();
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
From here
MediaPlayer is not thread-safe. Creation of and all access to player
instances should be on the same thread.
That means you have to maintain one media player instance throughout your whole application(As per your requirement). I don't know how you implemented the media player(Service/AsyncTask etc.). When you select a new song, you need to access that instance and replace the existing song with the selected one.

Android : Not able to stop the audio from the same button

I'm working on an app in which there is a grid layout with 8 buttons and each attached to a sound. Now I'm able to play the audio on the click of a button but when I press the same button again the audio doesn't stop.
All my buttons are attached to a common onClick method and the class file retrieves the id of the button and matches with the sound file present in the raw folder.
I'm using a flag for this but don't know where I'm going wrong.
My Code
boolean play = true;
MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonTapped(View view)
{
int id = view.getId();
String ourID = "";
ourID = view.getResources().getResourceEntryName(id);
int resourceID = getResources().getIdentifier(ourID, "raw", "com.starprojects.gridlayoutdemo");
mediaPlayer = MediaPlayer.create(this,resourceID);
if(play)
{
mediaPlayer.start();
play = false;
}
else {
// mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
// play = true;
}
// mediaPlayer = null;
Log.i("button tapped",ourID);
}
}
define mediaPlayer outsite of function, then do that
public void buttonTapped(View view) {
int id = view.getId();
String ourID = "";
ourID = view.getResources().getResourceEntryName(id);
int resourceID = getResources().getIdentifier(ourID, "raw", "com.starprojects.gridlayoutdemo");
stopPlayer();
mediaPlayer = MediaPlayer.create(this,resourceID);
if (mediaPlayer != null)
mediaPlayer .start();
}
public void stopPlayer() {
if (mediaPlayer != null) {
mediaPlayer .stop();
mediaPlayer .release();
}
mediaPlayer = null;
}
thats all :)
This may or may not be related to your problem, but don't forget to call
mediaPlayer.release();
mediaPlayer = null;
when you are finished. If you do not, resources get built up and start affecting sound outside of the app. Keep in mind a new MediaPlayer is being allocated every time you press the button. I have done this in a previous app and the sound stopped working after a few minutes.
Let me know if this changes anything.
As a matter of fact, you can try making your MediaPlayer a member of the class (defined outside the function) since you only need one sound playing at once. If it isn't null or .isPlaying(), release it. Otherwise, create and play.

How to release media player while preparing

I am working on music player app where I am doing streaming of music using MediaPlayer. Streaming is working fine but now I want If user press back button of the activity then it should stop preparing & release media player immediately.
Currently when it is preparing and if activity is being destroyed then I am releasing the MediaPlayer like this but when it release it then it hangs the application & show ANR.
#Override
protected void onDestroy() {
super.onDestroy();
if(mediaPlayer!=null) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
I am initializing MediaPlayer like below
mediaPlayer = null;
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource("http://www.samisite.com/sound/cropShadesofGrayMonkees.mp3");
Now I want when it start preparing then on back press when I am releasing in onDestory then it should not hang the app & release the media player smoothly.
Please help me what is the best way to do this. Thanks in advance
mediaPlayer.prepareAsync();
Check the answer here. And the MediaPlayer State Diagram from android code.
Edit:
#TGMCians I showed him the provided link, So, if the playback is still not ready or preparing, he can not call stop() until it's called onPrepared. I'm not sure that onPrepared keep called after the app onDestroy called. So, The full snip I think is:
private boolean mPrepared = false;
private boolean mCancel = false;
public void onPrepared(MediaPlayer player){
mPrepared = true;
if(mCancel){
player.release();
mPrepared = false;
mCancel = false;
//nullify your MediaPlayer reference
mediaPlayer = null;
}
}
private void cancelMedia(){
mCancel = true;
}
#Override
protected void onDestroy() {
super.onDestroy();
cancelMedia();
if (mediaPlayer != null && mPrepared) {
mediaPlayer.stop();
mediaPlayer.release();
mPrepared = false;
mediaPlayer = null;
}
}

Videoview gets stuck to blackscreen after restoring the app and plays the video after tapping on it

I want to play two videos on two separate class. but Videoview gets stuck to blackscreen after restoring the app and plays the video after tapping on it.
i have tried with seekto and getposition but again received the same result.
Have you tried with Resuming video on resume?
Also
#Override
public Object onRetainNonConfigurationInstance() {
ArrayList<Object> sessionObject = new ArrayList<Object>();
sessionObject.add(videoView.isPlaying());
sessionObject.add(videoView.getCurrentPosition());
sessionObject.add(videoView.getTag());
return sessionObject;
}
in Oncreate activity
ArrayList<Object> initialPosition = new ArrayList<Object>();
initialPosition.add(false);
initialPosition.add(0);
initialPosition.add(0);
#SuppressWarnings("unchecked")
ArrayList<Object> currentPositionObject = (ArrayList<Object>) (getLastNonConfigurationInstance() != null ? getLastNonConfigurationInstance()
: initialPosition);
int currentPosition = Integer.parseInt(currentPositionObject.get(1)
.toString());
Boolean isPlaying = (Boolean) currentPositionObject.get(0);
Now you can seek your video to position you want to and can start it as follows.
if (currentPosition != 0) {
if (isPlaying) {
videoView.start();
videoView.seekTo(currentPosition);
} else {
videoView.seekTo(currentPosition);
videoView.pause();
}
}
But still i have a problem with slight delay in orientation change.
You can save same elements in onPause method and add to bundle and on resume you can access the variables.

save the object's state during screen rotation

i have two objects for mediaplayer mp and mp1.
Both objects save the state of the media player.Here is the code
public Object onRetainNonConfigurationInstance()
{
HashMap<String,Object> player = new HashMap<String,Object>();
MediaPlayer instance = mp;
player.put("mp", instance);
mp = null;
MediaPlayer instance1 = mp1;
player.put("mp1", instance1);
mp1 = null;
return player;
}
this is my prob:
State of mp1 is saved.That is when i rotate the screen,the instance of mp1 continues from where it was.
Whereas mp restarts when i rotate the screen.Help me out please
For a MediaPlayer, you should really consider handling its state in a service and not in an activity :
its lifecycle is very different from the one of your activity (for example you may want to keep playing sounds when the user leave the app) and it has nothing to do in the UI thread.
It would also save the configuration changes handling.

Categories

Resources