I made an android app that plays sounds when clicking the button. These sounds can be also shared via messenger. All of these buttons (their look and position) are specified in activity_main.xml. The problem is, when I scroll up or down in my app, it looks terrible, because it's not smooth and my app seems to be laggy.
Here's my code with some buttons and imageviews for example
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/r1">
<Button
android:text="#string/sound1"
android:layout_marginTop="33dp"
android:id="#+id/sound1"
android:layout_width="210dp"
android:background="#drawable/backgroundbuttons"
android:layout_height="50dp"
android:layout_alignRight="#+id/sound3"
android:layout_alignEnd="#+id/sound3"
android:textSize="13sp" />
<Button
android:text="#string/sound2"
android:layout_width="210dp"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:id="#+id/sound2"
android:background="#drawable/backgroundbuttons"
android:layout_below="#+id/sound1"
android:layout_alignLeft="#+id/sound1"
android:layout_alignStart="#+id/sound1"
android:textSize="13sp" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
app:srcCompat="#drawable/sharebutton"
android:id="#+id/share_button1"
android:layout_alignBottom="#+id/sound1"
android:layout_toRightOf="#+id/sound1"
android:layout_toEndOf="#+id/sound1" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
app:srcCompat="#drawable/sharebutton"
android:id="#+id/share_button2"
android:layout_alignBottom="#+id/sound2"
android:layout_toRightOf="#+id/sound2"
android:layout_toEndOf="#+id/sound2" />
There are in total 25 buttons and 25 imageviews in my activity_main that look like this. All of these imageviews are based on one file (sharebutton.jpg).
EDIT:
Main Activity class:
public class MainActivity extends AppCompatActivity {
private MediaPlayer mp;
private MessengerThreadParams mThreadParams;
private boolean mPicking;
private static final int REQUEST_CODE_SHARE_TO_MESSENGER = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button s1 = (Button) findViewById(R.id.sound1);
Button s2 = (Button) findViewById(R.id.sound2);
findViewById(R.id.share_button1).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
onMessengerButtonClicked1();
}
});
findViewById(R.id.share_button2).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
onMessengerButtonClicked2();
}
});
Intent intent = getIntent();
if (Intent.ACTION_PICK.equals(intent.getAction())) {
mThreadParams = MessengerUtils.getMessengerThreadParamsForIntent(intent);
mPicking = true;
}
s1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onPause();
mp = MediaPlayer.create(MainActivity.this, R.raw.a1);
mp.start();
}
});
s2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onPause();
mp = MediaPlayer.create(MainActivity.this, R.raw.a2);
mp.start();
}
private void onMessengerButtonClicked1() {
// The URI can reference a file://, content://, or android.resource.
Uri uri =
Uri.parse("android.resource://" + getPackageName()+ "/raw/" +R.raw.a1);
ShareToMessengerParams shareToMessengerParams =
ShareToMessengerParams.newBuilder(uri, "audio/mpeg")
.setMetaData("{ \"audio\" : \"a1\" }")
.build();
if (mPicking) {
MessengerUtils.finishShareToMessenger(this, shareToMessengerParams);
} else {
MessengerUtils.shareToMessenger(
this,
REQUEST_CODE_SHARE_TO_MESSENGER,
shareToMessengerParams);
}
}
private void onMessengerButtonClicked2() {
Uri uri =
Uri.parse("android.resource://" + getPackageName()+ "/raw/" +R.raw.a2);
ShareToMessengerParams shareToMessengerParams =
ShareToMessengerParams.newBuilder(uri, "audio/mpeg")
.setMetaData("{ \"audio\" : \"a2\" }")
.build();
if (mPicking) {
MessengerUtils.finishShareToMessenger(this, shareToMessengerParams);
} else {
MessengerUtils.shareToMessenger(
this,
REQUEST_CODE_SHARE_TO_MESSENGER,
shareToMessengerParams);
}
}
protected void onPause() {
super.onPause();
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
}
https://developer.android.com/guide/components/activities/activity-lifecycle.html
Above is a general outline that can be used in broad areas including your situation.
As for your code you can implement the following:
#Override
public void onResume() {
mp.onResume();
// Setup the player
mp.resume();
}
#Override
public void onDestroy() {
if(mp != null) {
mp.release();
}
super.onDestroy();
}
s1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mp != null)
{
mp.stop();
mp.release();
}
finish();
}
});
}
If it helps, use logs to help you see the lifecycle
try{
if(mp !=null && mp.isPlaying()){
Log.d("TAG------->", "player is running");
mp.stop();
Log.d("Tag------->", "player is stopped");
mp.release();
Log.d("TAG------->", "player is released");
}
}catch(Exception e){
//Throw the error
}
Related
I am making a music player application in android. The application has
MainActivity.java (with corresponding XML File:activity_main): This Activity has a listview that displays the list of all songs available.
PlayerScreen.java (with corresponding XML File:activity_player_screen): When a song is clicked on the first activity, this activity is launched and it plays that particular song. This activity has 3 Buttons (Play/Pause, NextSong, PreviousSong) and a seekbar.
Now this is where I am facing the problem
I have created a separate class (SeekBarThread.java) for implementing seekbar of the activity_player_screen using Threading.
The Problem is that when I call the start method for my thread class from PlayerScreen.java, nothing happens. No exception is thrown. The song keeps on playing but the widgets of the activity_player_screen stop working i.e. I can't pause the song aur play the next song. The seekbar also doesn't work.
I think I am not able to link the activity_player_screen file with both PlayerScreen.java and SeekBarThread.java properly.
This is the call to the Thread class from PlayerScreen.java
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
I don't really have an idea to get rid of the anomaly so I passed the seekbar object and mediaplayer object reference and the current context reference to the SeekBarThread class. But it didn't work.
Here is the SeekBarThread.java class code:
public class SeekBarThread implements Runnable{
private PlayerScreen myPlayerScreen;
private SeekBar seekBar;
private MediaPlayer mp;
private Context context;
public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
this.context = context;
this.seekBar = seekBar;
this.mp = mp;
}
public void run() {
((Activity)context).setContentView(R.layout.activity_player_screen);
seekBar.setMax(mp.getDuration());
seekBar.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());
}
});
int totalduration = mp.getDuration();
int currentposition = 0;
while(currentposition < totalduration) {
try {
sleep(500);
currentposition = mp.getCurrentPosition();
seekBar.setProgress(currentposition);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
activity_player_screen XML File:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_player_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="prakhar.simplemusicplayer20.PlayerScreen">
<Button
android:id="#+id/play_pause"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:background="#drawable/pause" />
<Button
android:id="#+id/next_song"
android:layout_height="42dp"
android:layout_width="42dp"
android:background="#drawable/next"
android:layout_marginEnd="25dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" />
<Button
android:id="#+id/prev_song"
android:layout_height="42dp"
android:layout_width="42dp"
android:background="#drawable/previous"
android:layout_marginStart="25dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
<Button
android:text="F"
android:layout_width="42dp"
android:layout_height="42dp"
android:id="#+id/forward_song"
android:layout_alignParentBottom="true"
android:layout_toStartOf="#+id/next_song"
android:layout_marginEnd="22dp" />
<Button
android:text="R"
android:layout_width="42dp"
android:layout_height="42dp"
android:id="#+id/rewind_song"
android:layout_marginEnd="23dp"
android:layout_alignParentBottom="true"
android:layout_toStartOf="#+id/play_pause" />
<SeekBar
android:id="#+id/seek_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginBottom="26dp"
android:layout_above="#+id/play_pause"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="146dp"
android:id="#+id/details_text_view" />
</RelativeLayout>
Here is the PlayerScreen.java class:
public class PlayerScreen extends AppCompatActivity implements View.OnClickListener{
private Button playPause, nextSong, prevSong;
public SeekBar mySeekBar;
private int count = 0;
public MediaPlayer mediaPlayer;
private Bundle newBundle = new Bundle();
private Intent newIntent;
private int pos;
private ArrayList<String> name;
private ArrayList<String> path;
private SeekBarThread mySeekBarThread;
private Thread myThread;
private TextView detailsTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_screen);
playPause = (Button)findViewById(R.id.play_pause);
nextSong = (Button)findViewById(R.id.next_song);
prevSong = (Button)findViewById(R.id.prev_song);
mySeekBar = (SeekBar)findViewById(R.id.seek_bar);
detailsTextView = (TextView)findViewById(R.id.details_text_view);
playPause.setOnClickListener(this);
nextSong.setOnClickListener(this);
prevSong.setOnClickListener(this);
newIntent = this.getIntent();
newBundle = newIntent.getExtras();
name = newBundle.getStringArrayList("title");
path = newBundle.getStringArrayList("songpath");
pos = newBundle.getInt("post");
detailsTextView.setText(name.get(pos));
mediaPlayer = new MediaPlayer();
setMediaPlayer(pos);
}
public void setMediaPlayer(int position) {
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
File mySong = new File(path.get(pos));
mediaPlayer = new MediaPlayer();
FileInputStream is = null;
try {
is = new FileInputStream(mySong);
}
catch(FileNotFoundException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.setDataSource(is.getFD());
}
catch(IOException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.prepare();
}
catch(IOException ex) {
ex.printStackTrace();
}
finally {
if(is != null) {
try {
is.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}
mediaPlayer.start();
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.play_pause:
count++;
if(count%2 == 0) {
v.setBackgroundResource(R.drawable.pause);
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
mediaPlayer.start();
}
else {
v.setBackgroundResource(R.drawable.play);
mediaPlayer.pause();
}
break;
case R.id.next_song:
mediaPlayer.stop();
pos = pos + 1;
setMediaPlayer(pos);
break;
case R.id.prev_song:
mediaPlayer.stop();
pos = pos - 1;
setMediaPlayer(pos);
break;
}
}
}
Most of the onCreate() code for this is class is dealing with which song to play based on the user's choice from the previous activity. And since the song is being played, i don't think there is a problem in that part of the code.
#prakhar, Going through the code, I have found the following issues:
1) In SeekBarThread class in run() method setContentView() should not set,as it is already set in the activity class, as your are not reinitializing the click listeners.
2) Also the seekbarchangeListener should not be set in run() method and should be set in the main activity itself, as it doesn't need reinitalizing all the time.
3) The important point here is that your are initializing the SeekBarThread class before the initialization of MediaPlayer and hence there is no action even after seeking the seekbar.
A detailed code with the above modifications rectified.
public class PlayerScreen extends AppCompatActivity implements View.OnClickListener {
private Button playPause, nextSong, prevSong;
public SeekBar mySeekBar;
private int count = 0;
public MediaPlayer mediaPlayer;
private Bundle newBundle = new Bundle();
private Intent newIntent;
private int pos;
private ArrayList<String> name;
private ArrayList<String> path;
private SeekBarThread mySeekBarThread;
private Thread myThread;
private TextView detailsTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playPause = (Button) findViewById(R.id.play_pause);
nextSong = (Button) findViewById(R.id.next_song);
prevSong = (Button) findViewById(R.id.prev_song);
mySeekBar = (SeekBar) findViewById(R.id.seek_bar);
detailsTextView = (TextView) findViewById(R.id.details_text_view);
playPause.setOnClickListener(this);
nextSong.setOnClickListener(this);
prevSong.setOnClickListener(this);
mySeekBar.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) {
mediaPlayer.seekTo(seekBar.getProgress());
}
});
newIntent = this.getIntent();
newBundle = newIntent.getExtras();
name = newBundle.getStringArrayList("title");
pos = newBundle.getInt("post");
detailsTextView.setText(name.get(pos));
mediaPlayer = new MediaPlayer();
setMediaPlayer(pos);
}
public void setMediaPlayer(int position) {
File mySong = new File(path.get(pos));
mediaPlayer = new MediaPlayer();
FileInputStream is = null;
try {
is = new FileInputStream(mySong);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.setDataSource(is.getFD());
} catch (IOException ex) {
ex.printStackTrace();
}
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepare();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
is.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
mediaPlayer.start();
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play_pause:
count++;
if (count % 2 == 0) {
v.setBackgroundResource(R.drawable.pause);
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
mediaPlayer.start();
} else {
v.setBackgroundResource(R.drawable.play);
mediaPlayer.pause();
}
break;
case R.id.next_song:
mediaPlayer.stop();
pos = pos + 1;
setMediaPlayer(pos);
break;
case R.id.prev_song:
mediaPlayer.stop();
pos = pos - 1;
setMediaPlayer(pos);
break;
}
}
}
public class SeekBarThread implements Runnable{
private SeekBar seekBar;
private MediaPlayer mp;
private Context context;
public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
this.context = context;
this.seekBar = seekBar;
this.mp = mp;
}
public void run() {
seekBar.setMax(mp.getDuration());
int totalduration = mp.getDuration();
int currentposition = 0;
while(currentposition < totalduration) {
try {
sleep(500);
currentposition = mp.getCurrentPosition();
seekBar.setProgress(currentposition);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
I am working on an app that is used to stream songs online. I am able to play the song on clicking on it.
The problem with me is that I have a CircularSeekBar in all the Activities and I need to manage it on all the screens. If a song is played from any activity CircularSeekBar should be visible on all the screens. What I am able to do is When a song is played I am able to show the seekbar on that particular activity but not able to manage that seekbar on any other activity.
Below is the sample of one of my xml files:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical">
</LinearLayout>
<include layout="#layout/seek_bar_layout"></include>
</android.support.design.widget.CoordinatorLayout>
Please let me know how to manage that Seekbar on all the Activities.
Thanks in Advance.
You can't manage activity view when other is visible.
You can solve it by any boolean flag (for example: isSongPlaying = false). When you start playing your song set it to true. In each activity in onResume check that flag and show / hide your SeekBar.
Try to avoid using public static and use any other way.
EDIT:
According to your comments i created very simple example how you can solve your problem using service. Remember this code need much improvements.
SongService
public class SongService extends Service {
ActivityManager activityManager;
IBinder iBinder;
boolean playingSong = false;
Worker worker;
public SongService() {
iBinder = new MyBinder();
}
private void playSong(String path) {
if(worker != null) {
worker.cancel(true);
}
worker = new Worker();
worker.execute();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return iBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private class Worker extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
playingSong = true;
}
#Override
protected Void doInBackground(Void... params) {
for (int i = 100; i > -1; i--) {
publishProgress(i);
try {
Thread.sleep(100l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (activityManager != null) {
activityManager.publishProgress(values[0]);
}
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
playingSong = false;
activityManager.onSongFinish();
}
}
public class MyBinder extends Binder {
public SongService getSongService() {
return SongService.this;
}
public void BindView(ActivityManager activityManager) {
SongService.this.activityManager = activityManager;
}
public void playSong(String path) {
SongService.this.playSong(path);
}
public boolean isPlayingSong() {
return playingSong;
}
}
public interface ActivityManager {
void publishProgress(int progress);
void onSongFinish();
}
}
MainActivity:
public class MainActivity
extends AppCompatActivity
implements ServiceConnection, SongService.ActivityManager {
TextView progress;
Button play;
Button next;
SongService.MyBinder myBinder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = (TextView) findViewById(R.id.progress);
play = (Button) findViewById(R.id.play);
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(myBinder != null) {
//Your path to song
myBinder.playSong("");
play.setEnabled(false);
}
}
});
next = (Button) findViewById(R.id.next);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
Intent mIntent = new Intent(this, SongService.class);
bindService(mIntent, this, BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
unbindService(this);
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
if(service instanceof SongService.MyBinder) {
myBinder = (SongService.MyBinder) service;
myBinder.BindView(this);
if (myBinder.isPlayingSong()) {
play.setEnabled(false);
}
else {
play.setEnabled(true);
}
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
myBinder = null;
}
#Override
public void publishProgress(int progress) {
this.progress.setText("Progress: " + progress);
}
#Override
public void onSongFinish() {
play.setEnabled(true);
}
}
MainActivity2
This activity class looks exacly the same like MainActivity but have different layout file.
MainActivity - Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.aszymanski2.serviceanddelegatepatternexample.MainActivity">
<TextView
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="Play"
android:id="#+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
<Button
android:text="SecondActivity"
android:id="#+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
MainActivity2 - Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.aszymanski2.serviceanddelegatepatternexample.MainActivity">
<TextView
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="Play"
android:id="#+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
<Button
android:text="Back"
android:id="#+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
I am playing an audio (mySound) as background music. On clicking a button, the background audio should stop and a different audio (mySound11) should start playing. After this audio gets done, the background music should automatically resume from where it had left. I have tried this code, but the background audio doesn't resume after mySound11 is over. Please help. Thanks in advance.
MainActivity.java
public class MainActivity extends ActionBarActivity {
MediaPlayer mySound;
MediaPlayer mySound11;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySound11 = MediaPlayer.create(this, R.raw.tiktik);
mySound = MediaPlayer.create(this, R.raw.jhakmaarke);
mySound.setLooping(true);
mySound.start();
}
public void playMusic (View view){
mySound.pause();
mySound11.start();
}
#Override
public void onResume() {
super.onResume();
mySound.start();
}
#Override
protected void onPause() {
super.onPause();
mySound.release();
mySound11.release();
finish();
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Dabaa be"
android:onClick="playMusic"
android:id="#+id/button"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="72dp" />
I Solved your problem with the help of Thread.
I tested it working as you wished.
int mySound11Duration;
MediaPlayer mySound;
MediaPlayer mySound11;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySound11 = MediaPlayer.create(this, R.raw.tiktik);
mySound = MediaPlayer.create(this, R.raw.jhakmaarke);
mySound.setLooping(true);
mySound.start();
}
public void playMusic(View view) {
if (mySound.isPlaying()) { //check mysound is playing or not
mySound11Duration = mySound11.getDuration();
Thread thread=new Thread() {
#Override
public void run() {
try {
mySound.pause();
int mySoundPausePosition = mySound.getCurrentPosition();//get the time where the song is paused.
mySound11.start();
sleep(mySound11Duration);//sleep method causes the currently executing thread to sleep for specified number of time(miliseconds).
mySound.seekTo(mySoundPausePosition);
mySound.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
}
I'm trying to make my application play a sound when I click on the picture drawn in the Array. What I want to do is play a different sound when you click a different picture.
This my Java code so far:
public class gorendis extends Activity implements MediaPlayer.OnCompletionListener{
private ImageView play;
private ImageView a2;
private MediaPlayer mp;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.huruf);
play=(ImageView)findViewById(R.id.a1);
a2=(ImageView)findViewById(R.id.a2);
//gambar=(ImageButton)findViewById(R.id.gambar);
//gambar.setImageResource(R.drawable.a1);
play.setOnClickListener( new View.OnClickListener() {
public void onClick(View view) {
play();
}
});
a2.setOnClickListener( new View.OnClickListener() {
public void onClick(View view) {
play();
}
});
setup();
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void onCompletion(MediaPlayer mp) {
stop();
}
private void stop() {
// TODO Auto-generated method stub
}
private void play() {
mp.start();
play.setEnabled(true);
}
private void loadClip() {
try {
mp=MediaPlayer.create(this, R.raw.doajodoh);
mp.setOnCompletionListener(this);
} catch (Throwable t) {
goBlooey(t);
}
}
private void setup() {
loadClip();
play.setEnabled(true);
}
private void goBlooey(Throwable t) {
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("Exception!")
.setMessage(t.toString())
.setPositiveButton("OK", null)
.show();
}
}
Main layout XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView>
<LinearLayout>
<ImageView
android:id="#+id/play"
android:layout_width="wrap_content"
android:layout_height="53px"
android:background="#android:color/transparent"
android:scaleType="fitCenter"
android:src="#drawable/a1" >
</ImageView>
<ImageView
android:id="#+id/a2"
android:layout_width="wrap_content"
android:layout_height="53px"
android:background="#android:color/transparent"
android:scaleType="fitCenter"
android:src="#drawable/a2" >
</ImageView>
</LinearLayout>
</ScrollView>
If you simply want to play different sounds on buttonclick, then i would advise this:
Use the setTag() method of your buttons. Like button1.setTag(0);
or button1.setTag("guitarmusic");
You will notice that the View.OnClickListener's onClick() method
gets a View as parameter.
You know, that you set this OnClickListener only to buttons, so you
can cast this View in the onClick() method to Button like
Button clicked = (Button) view;
Then you can access the tag, you set earlier to your buttons, and
cast them too, like: Integer buttonTag = (Integer)
clicked.getTag();
Then you can decide in a simple switch, wich sound you want to
play, like: switch(buttonTag){case 0: play first sound... break;
...}
This way you wont need a separate OnClickListener to every sound you want to play :)
finaly I found this sollution..
THIS WORK AND EVEN WITH THE LONG CODE !!
public class part1 extends Activity implements MediaPlayer.OnCompletionListener{
/** Called when the activity is first created. */
private ImageView a2;
private ImageView a3;
private ImageView a4;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
a2=(ImageView)findViewById(R.id.a2);
a3=(ImageView)findViewById(R.id.a3);
a4=(ImageView)findViewById(R.id.a4);
a2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
a2();
}
});
setup();
a3.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
a3();
}
});
setup2();
a4.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
a4();
}
});
setup3();
public void onCompletion(MediaPlayer mp) {
stop();
}
private void stop() {
mp.stop();
}
private void a2() {
mp.stop();
loadClip();
mp.start();
a2.setEnabled(true);
}
private void a3() {
mp.stop();
loadClip2();
mp.start();
a3.setEnabled(true);
}
private void a4() {
mp.stop();
loadClip3();
mp.start();
a4.setEnabled(true);
}
private void loadClip() {
try {
mp=MediaPlayer.create(this, R.raw.a2);
mp.setOnCompletionListener(this);
}
catch (Throwable t) {
goBlooey(t);
}
}
private void loadClip2() {
try {
mp=MediaPlayer.create(this, R.raw.a3);
mp.setOnCompletionListener(this);
}
catch (Throwable t) {
goBlooey(t);
}
}
private void loadClip3() {
try {
mp=MediaPlayer.create(this, R.raw.a4);
mp.setOnCompletionListener(this);
}
catch (Throwable t) {
goBlooey(t);
}
}
private void setup() {
loadClip();
a2.setEnabled(true);
}
private void setup2() {
loadClip2();
a3.setEnabled(true);
}
private void setup3() {
loadClip3();
a4.setEnabled(true);
}
private void goBlooey(Throwable t) {
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder
.setTitle("Exception!")
.setMessage(t.toString())
.setPositiveButton("OK", null)
.show();
}
I am using media player to stream a video. It only plays the audio but not the video. Could anyone help? My code is below.
public class VideoViewApplication extends Application {
#Override
public void onCreate() {
}
#Override
public void onTerminate() {
}
}
public class VideoViewDemo extends Activity implements
OnErrorListener,OnBufferingUpdateListener, OnCompletionListener,
MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {
private static final String TAG = "VideoViewDemo";
private MediaPlayer mp;
private EditText mPath;
private SurfaceHolder holder;
private ImageButton mPlay;
private ImageButton mPause;
private ImageButton mReset;
private ImageButton mStop;
private String current;
private SurfaceView mPreview;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
mPreview = (SurfaceView) findViewById(R.id.surface);
mPath = (EditText) findViewById(R.id.path);
mPath.setText("rtsp://video2.americafree.tv/AFTVHorrorH26496.sdp");
mPlay = (ImageButton) findViewById(R.id.play);
mPause = (ImageButton) findViewById(R.id.pause);
mReset = (ImageButton) findViewById(R.id.reset);
mStop = (ImageButton) findViewById(R.id.stop);
mPlay.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
playVideo();
}
});
mPause.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (mp != null) {
mp.pause();
}
}
});
mReset.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (mp != null) {
mp.seekTo(0);
}
}
});
mStop.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (mp != null) {
current = null;
mp.stop();
mp.release();
}
}
});
// getWindow().setFormat(PixelFormat.TRANSPARENT);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setFixedSize(100, 100);
runOnUiThread(new Runnable(){
public void run(){
playVideo();
}
});
}
private void playVideo() {
try {
final String path = mPath.getText().toString();
Log.v(TAG, "path: " + path);
if (path.equals(current) && mp != null) {
mp.start();
return;
}
current = path;
mp = new MediaPlayer();
mp.setOnErrorListener(this);
mp.setOnBufferingUpdateListener(this);
mp.setOnCompletionListener(this);
mp.setOnPreparedListener(this);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setScreenOnWhilePlaying(true);
mp.setDisplay(mPreview.getHolder());
mp.setDataSource(path);
mp.prepare();
Log.v(TAG, "Duration: ===>" + mp.getDuration());
mp.start();
} catch (Exception e) {
Log.e(TAG, "error: "+ e.getMessage(), e);
if (mp != null) {
mp.stop();
mp.release();
}
}
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.d(TAG, "surfaceChanged called");
}
public void surfaceCreated(SurfaceHolder arg0) {
Log.d(TAG, "surfaceCreated called");
}
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.d(TAG, "surfaceDestroyed called");
}
public void onPrepared(MediaPlayer arg0) {
Log.d(TAG, "onPrepared called");
}
public void onCompletion(MediaPlayer arg0) {
Log.d(TAG, "onCompletion called");
}
public void onBufferingUpdate(MediaPlayer mediaPlayer, int percent) {
Log.d(TAG, "onBufferingUpdate called ---> percent:" + percent);
}
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
Log.e(TAG, "onError---> what:"+what+" extra:"+extra);
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
return true;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText android:id="#+id/path"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</SurfaceView>
<LinearLayout
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
>
<ImageButton android:id="#+id/play"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/play"/>
<ImageButton android:id="#+id/pause"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/pause"/>
<ImageButton android:id="#+id/reset"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/reset"/>
<ImageButton android:id="#+id/stop"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/stop"/>
</LinearLayout>
</LinearLayout>
I had this problem and solved it by setting the type using this depreciated method.
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Worth a try, and if it works you could investigate why the type isn't automatically set as it is supposed to be.
I had the same problem and it was due to the surface not being ready to play back video.
You should try and call playVideo() from the surfaceCreated() handler.
public void surfaceCreated(SurfaceHolder holder) {
runOnUiThread(new Runnable(){
public void run(){
playVideo();
}
});
}
I had this problem and solved it by adding in my release function visible=gone to surfaceview:
public void release() {
if (mMediaPlayer != null) {
setVisibility(View.GONE);
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
mCurrentState = STATE_IDLE;}
}
and set visible=visible in onprepared function:
videoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
audio=false; video=false; int ty=mp.getTrackInfo().length;
for (int i=0; i<ty;i++)
{
if (mp.getAudioTrack()>-1) {audio=true;}
if (mp.getVideoTrack()>-1) {video=true;}
}
if (((audio==false)&&(skip==true))||((video==false)&&(skip2==true))||((video==true)&&(skip4==true)))
{ notifybar("...");
nexttr();} else {
if (vis==true) {
if (video==false) {
if (mVisualizerView.getVisibility()!=View.VISIBLE) {mVisualizerView.setVisibility(View.VISIBLE);}
mVisualizerView.link(videoView.getAudioSessionId());
vis2=true;
} else if (vis2==true){
mVisualizerView.release();
mVisualizerView.setVisibility(View.GONE);
vis2=false;
}}
//this
if (video==true) {
if (videoView.getVisibility()!=View.VISIBLE) {videoView.setVisibility(View.VISIBLE);}
} else {if (videoView.getVisibility()!=View.INVISIBLE) {videoView.setVisibility(View.INVISIBLE);}
}