13

Used ViewPager for images sliding, each image onclick stream different MP3.

app including 50 pages(images) & 50 different mp3, all mp3 stored on app itself.

ex. First-page stream MP3(one), second-page stream MP3(two) and so on till page fifty.

FIRST:

its work fine just only one issue which is:

In any page --> clicking the image --> 

 PLAY MP3(one) --> click again--> PAUSE MP3 -->
 in paused state of MP3(one) SWIPE to next page --> 

--> in next page --> clicking the image -->
  PLAY MP3(two) --> click to pause the MP3(two)

   --> it doesn't respond to first click,it respond to second click to pause MP3(two).

SECOND:

the app contain 50 pages and 50 different MP3, does i need to repeat the mediaplayer code 50 times which i already did , or there is better approach to do that in single code applied to all 50 mediaplayer MP3 , as all has the same function cycle.

any advice please and how to apply it in coding .

MainActivity :

public class MainActivity extends Activity {

private ViewPager mViewPager;
MediaPlayer mp;
private boolean isPaused;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mViewPager= (ViewPager) findViewById(R.id.view_pager);
    ImageAdapter adapter = new ImageAdapter(this);
    mViewPager.setAdapter(adapter);

    final GestureDetector tapGestureDetector = new GestureDetector(this, new TapGestureListener());
    mViewPager.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            tapGestureDetector.onTouchEvent(event);
            return false;
        }
    });
}

private class TapGestureListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        if (mViewPager.getCurrentItem() == 0) {
            if (mp != null) {
                if (isPaused) {
                    mp.start();
                    isPaused = false;
                } else {
                    mp.pause();
                    isPaused = true;
                }
            } else {
                mp = MediaPlayer.create(MainActivity.this, R.raw.aa);
                mp.start();

                    }
                }

        if (mViewPager.getCurrentItem() == 1) {
            if (mp != null) {
                if (isPaused) {
                    mp.start();
                    isPaused = false;
                } else {
                    mp.pause();
                    isPaused = true;
                }
            } else {
                mp = MediaPlayer.create(MainActivity.this, R.raw.bb);
                mp.start();                  
            }
        }

        if (mViewPager.getCurrentItem() == 2) {
            if (mp != null) {
                if (isPaused) {
                    mp.start();
                    isPaused = false;
                } else {
                    mp.pause();
                    isPaused = true;
                }
            } else {
                mp = MediaPlayer.create(MainActivity.this, R.raw.cc);
                mp.start();                 
            }
        }

        if (mViewPager.getCurrentItem() == 3) {
            if (mp != null) {
                if (isPaused) {
                    mp.start();
                    isPaused = false;
                } else {
                    mp.pause();
                    isPaused = true;
                }
            } else {
                mp = MediaPlayer.create(MainActivity.this, R.raw.dd);
                mp.start();
            }
        }
      //AND SO ON FOR 50 PAGES//  
        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {   
                if (mp == null) {
                    return;
                }
                mp.release();
                mp = null;
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub                  
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
            }
        });

        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer m) {
                Toast.makeText(MainActivity.this, 
                        "COMPLETED", Toast.LENGTH_LONG).show();
                // Set the MainActivity member to null
                MainActivity.this.mp = null;
            }
        });

        return super.onSingleTapConfirmed(e);
       }
   }
}

ImageAdapter:

  public class ImageAdapter extends PagerAdapter {
Context context;
private int[] GalImages = new int[] {
    R.drawable.a,
    R.drawable.b,
    R.drawable.c,
    R.drawable.d,

};
ImageAdapter(Context context){
    this.context=context;
}
@Override
public int getCount() {
  return GalImages.length;
}

@Override
public boolean isViewFromObject(View view, Object object) {
  return view == ((ImageView) object);
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
  ImageView imageView = new ImageView(context);
  int padding = context.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin);
  imageView.setPadding(padding, padding, padding, padding);
  imageView.setScaleType(ImageView.ScaleType.CENTER);
  imageView.setImageResource(GalImages[position]);
  ((ViewPager) container).addView(imageView, 0);
  return imageView;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
  ((ViewPager) container).removeView((ImageView) object);
   }
 }

I'm new to android, I tried to fix it but with no success, its simple app just includes MainActivity & ImageAdapter.

i tried the below code also still the issue not resolved:

  mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {   
                if (mp != null) {
                    if (mp.isPlaying()) {
                        mp.stop();
                    }
                    mp.release();
                    mp = null;
                }
            }
            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub                  
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
            }
        });

UPDATE:

In any page:

let’s say page (one) ---> click to play MP3 ---> (playing) ---> click to pause MP3 ---> (paused) ---> swipe to any page Rt or Lf --->( swiped to page (two) for example ) ---> click to play MP3 on page (two) ---> (playing) ---> click to pause MP3 on page (two) ---> (paused) ---> (all previous onclick action working correctly) ---> click to resume playing MP3 in page (two) which already in paused state ====> BUT mistakenly when you click the image in page (two) to resume playing the MP3 , your finger not straight , its slightly tilted so the finger click lead to ( click on page (two) and in the same time swipe to page (three) ====> here is the issue the page (three) MP3 start playing by itself from the beginning .

I want if this happened occasionally or mistakenly not to start playing the MP3 in page (three) until I click the image in page (three) then start playing the MP3.

any help will be really appreciated.

frozenhill4
  • 157
  • 1
  • 9

3 Answers3

0

FIRST I believe your isPaused is staying true after pausing the first song, you may need to set it to false when the user change pages :

public void onPageSelected(int position) {   
            if (mp == null) {
                return;
            }
            mp.release();
            mp = null;
            isPaused = false;
        }

SECOND You can use a List<Integer> that you can initialize at the start of you app, so you can have a structure to store your songs, as it is the only thing that change in your code, example :

List<Integer> songs;

@Override
public void onCreate(Bundle savedInstanceState) {
...
    songs = new ArrayList<>();
    songs.add(R.raw.aa);
    songs.add(R.raw.bb);
//...etc
}

And then on your onSingleTapConfirmed method you can just access them by index just once :

        if (mp != null) {
            if (isPaused) {
                mp.start();
                isPaused = false;
            } else {
                mp.pause();
                isPaused = true;
            }
        } else {
            mp = MediaPlayer.create(MainActivity.this, 
                     songs.get(mViewPager.getCurrentItem()));
            mp.start();
            isPaused = false;
         }
Hugo sama
  • 899
  • 1
  • 9
  • 19
  • please i have small issue, if you have any advice , In any page ---> click to play ---> click to pause ---> swipe to any page Rt or Lf ---> click to play --->click to pause --->(working correctly) ---> click to resume but mistakenly swipe to next page ---> next page MP3 will play immediately without click on it, I want even if my finger click leads to mistakenly swipe to another page mp must play in response to click not by it self. – frozenhill4 Jul 20 '17 at 17:34
  • would you please check the update on the question, thanks – frozenhill4 Jul 21 '17 at 20:30
0

First Questions answer:-

Just copy paste this code and let me know I have not tested it but have a strong feeling it will work.

import java.lang.reflect.Field;
    public class MainActivity extends Activity {

        private ViewPager mViewPager;
        MediaPlayer mp;
        private boolean isPaused;
        private ArrayList<Integer> mMp3s;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            mViewPager = (ViewPager) findViewById(R.id.view_pager);
            ImageAdapter adapter = new ImageAdapter(this);
            mMp3s=getAllMp3FilesFromRaw();
            mViewPager.setAdapter(adapter);

            final GestureDetector tapGestureDetector = new GestureDetector(this, new TapGestureListener());
            mViewPager.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent event) {
                    tapGestureDetector.onTouchEvent(event);
                    return false;
                }
            });
        }

        private class TapGestureListener extends GestureDetector.SimpleOnGestureListener {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {

                    if (mp != null) {
                        if (isPaused) {
                            mp.start();
                            isPaused = false;
                        } else {
                            mp.pause();
                            isPaused = true;
                        }
                    } else {
                        mp = MediaPlayer.create(MainActivity.this, mMp3s.get(mViewPager.getCurrentItem()));
                        mp.start();
                        isPaused = false;
                    }


                //AND SO ON FOR 50 PAGES//
                mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        if (mp == null) {
                            return;
                        }
                        mp.release();
                        mp = null;
                        isPaused = true;
                    }

                    @Override
                    public void onPageScrollStateChanged(int arg0) {
                        // TODO Auto-generated method stub
                    }

                    @Override
                    public void onPageScrolled(int arg0, float arg1, int arg2) {
                        // TODO Auto-generated method stub
                    }
                });

                mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    public void onCompletion(MediaPlayer m) {
                        Toast.makeText(MainActivity.this, "COMPLETED", Toast.LENGTH_LONG).show();
                        // Set the MainActivity member to null
                        finish();
                        MainActivity.this.mp = null;
                    }
                });

                return super.onSingleTapConfirmed(e);
            }
        }

        /**
        *Do it on background thread if it blocks the UI.
        */
        private ArrayList<Integer> getAllMp3FilesFromRaw() {
            ArrayList<Integer> mp3s = new ArrayList<>();
            try {
                Field fields[] = R.raw.class.getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    Field f = fields[i];

                    int resIdentifier = getResources().getIdentifier(f.getName(), "raw", getPackageName());
                    mp3s.add(resIdentifier);
                }
                return mp3s;

            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }

The logic is get all the mp3 files resource id when you start the app if this process is taking too much time do it on background thread.

using those resorce id play your songs now there much be some issue with the list which you fetch like they may not match with your image or viewpager number for that you will have to apply some other logic if you encounter any error let me know.

Sec Questions answer:- Now I presume that when you want to click on the image to play the music at the same time by mistake page is getting swiped and when it reached to other page it start playing that page's music immediately. If I understood you question as I still don't know which code are you using I ll guide you through the methods based on that you can apply the logic.

when page changes to next one then

onPageChanged(int position)

method will be called https://stackoverflow.com/a/11294494/5492047 here you can apply the logic. Now how, if the music is playing and you are on the first page and you swiped on to the second one what you have to do in

onPageChanged(int position)
    {
     mp.release();
     mp=null;
    //Now initialiase it again with page two's music.
    mp = MediaPlayer.create(MainActivity.this, R.raw.aa);
    }

and don't call mp.start(); now when user clicks on the image in

 OnClickListener(View view){
    //use the same instance of mediaplayer and call mp.start();
    if(isPlaying){
       mp.pause();
    }else{
    mp.start();
 }
}

I assume you are using only one instance of MediaPlayer not like you have shown in your code.

Reyansh Mishra
  • 1,879
  • 1
  • 14
  • 26
  • please i have small issue, if you have any advice , In any page ---> click to play ---> click to pause ---> swipe to any page Rt or Lf ---> click to play --->click to pause --->(working correctly) ---> click to resume but mistakenly swipe to next page ---> start next page MP3 immediately without click it, I want even if my finger click leads to mistakenly swipe to another page to start on click not by it self. – frozenhill4 Jul 20 '17 at 12:42
  • okay if this answer helped you please accept it and award the bounty and your second question is not clear. Like when you swipe to next or previous page if should play the mp3 immediately or it should play after swiping on page and clicking on it? – Reyansh Mishra Jul 20 '17 at 14:06
  • 1
    @ReyanshMishra please don't impose your answer on OP & force to send you bounty, If he have doubts clear them. If problem is solved then he will surely accept and provide you the bounty. – Maveňツ Jul 21 '17 at 14:10
  • I am not imposing sorry you felt that I just asked if it solved your problem and I want to help that's why in the end I asked him to give the clarification of his problem as I don't know what he is implying and this could be entirely a new question which can not be explained in the comments by him. – Reyansh Mishra Jul 21 '17 at 14:25
  • @ReyanshMishra Mishra would you please check the update on the question, thanks – frozenhill4 Jul 21 '17 at 20:32
  • @ReyanshMishra where to apply OnClickListener(View view){ – frozenhill4 Jul 21 '17 at 21:58
  • @ReyanshMishra the code i use already on the question , only i have 2 class in the app , ImageAdapter & MainActivity : i just start in android development , i have no experiance at all , thanks for you help – frozenhill4 Jul 21 '17 at 22:01
  • @ReyanshMishra ITS SIMPLE APP as described on my question: ViewPager for images sliding, each image onclick stream different MP3. app including 50 pages(images) & 50 different mp3, all mp3 stored on app itself. ex. First-page stream MP3(one), second-page stream MP3(two) and so on till page fifty. – frozenhill4 Jul 21 '17 at 22:02
  • oh okay so when page will be switched onPageChanged(int position) method will be called and there you will have to reset the mediaplayer and initialize new on and there you are not suppose to call mp.start(); or else it would start playing. – Reyansh Mishra Jul 21 '17 at 22:05
  • @ReyanshMishra as you wrote in update answer you understand the issue correctly (Now I presume that when you want to click on the image to play the music at the same time by mistake page is getting swiped and when it reached to other page it start playing that page's music immediately.) but this happen if you swiped from page 1 for example after pause page 1 mp3 and go to page 2 then play page 2 mp3 then pause it then if you want to resume it, the mistake click happen shift you to page 3 , page 3 mp3 start immediately . thanks – frozenhill4 Jul 21 '17 at 22:07
  • @ReyanshMishra i applied your code so : onPageChanged(int position) method applied like this :public void onPageSelected(int position) { if (mp == null) { return; } mp.release(); mp = null; isPaused = true; } – frozenhill4 Jul 21 '17 at 22:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149851/discussion-between-reyansh-mishra-and-frozenhill4). – Reyansh Mishra Jul 21 '17 at 22:10
0

According to your description and my understanding, I list the demands that you want the program do.

Once you click the image or switch pages, MediaPlayer will response like rules below.

RULES:

  1. If NO song played before, you CLICK, player will START playing the song of current page.

  2. If A song played before and player is still PLAYING, you CLICK, player will PAUSE.

  3. If A song played before and player is still PLAYING, you SWITCH, player will RELEASE before and START playing the song of current page.

  4. If A song played before and player is paused, you CLICK, if current page IS NOT the page of the song paused before, the player will RELEASE before and START playing the song of current page.

  5. If A song played before and player is paused, you CLICK, if current page IS the page of the song paused before, the player will CONTINUE playing.

  6. If A song played before and player is paused, you SWITCH, NOTHING happens.

Reading words is incomprehensible, please check the picture below: (Rule 1 actually is the same as Rule 4.) rules

If there is no misunderstanding, I will begin answering the question. Or please let me know.

Now, we make it clear about how player response when you click or switch pages in the different situation(whether current page is the page of the song paused before).

Let we talk about how to avoid reduplicated code. As other answer said, use the list of songs and use index(num of page) to distinguish each of them.

So them are declared like that:

List<Integer> mMP3s = new ArrayList<Integer>() {
    {
        add(R.raw.mp3_0);
        add(R.raw.mp3_1);
        add(R.raw.mp3_2);
        add(R.raw.mp3_3);
        add(R.raw.mp3_4);
        //...
        //AND SO ON FOR 50 PAGES//  
    }
};

And when you click the image(set the OnClickListener on the image):

@Override
public void onClick(View view) {
    int position = mViewPager.getCurrentItem();
    if (mp != null) {
        if (isPaused) {
            if (pausedPage == position) {
                mp.start();
            } else {
                mp = MediaPlayer.create(MainActivity.this, mMP3s.get(position));
                mp.start();
            }
            isPaused = false;
        } else {
            mp.pause();
            isPaused = true;
            pausedPage = position;
        }
    } else {
        mp = MediaPlayer.create(MainActivity.this, mMP3s.get(position));
        mp.start();
        isPaused = false;
    }
    mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        public void onCompletion(MediaPlayer m) {
            Toast.makeText(MainActivity.this,
                    "COMPLETED", Toast.LENGTH_LONG).show();
            // Set the MainActivity member to null
            MainActivity.this.mp = null;
        }
    });
}

And when you SWITCH pages:

@Override
public void onPageSelected(int position) {
    if (!isPaused) {
        mp.release();
        mp = MediaPlayer.create(MainActivity.this, mMP3s.get(position));
        mp.start();
        tv.append("START page" + position + "\n");
    } else {
        //do nothing.
    }
}

If you are still puzzled about the code, please see here. I uploaded my code on github.

Relish Wang
  • 385
  • 1
  • 8
  • would you please check the update on the question, thanks – frozenhill4 Jul 21 '17 at 20:34
  • I may misunderstanding you question. But I think your logic is not comfortable for user to use. Just Imagine a scene like that, My Heart Will Go On is playing, I pause it and swipe pages to seek whether there are other songs interest me, after a period of searching, I decide to return the page of My Heart Will Go On, and click it to continue playing. Is that better? – Relish Wang Jul 22 '17 at 02:36
  • In your logic, My Heart Will Go On will start playing from the BEGINNING of this song rather than CONTINUE playing. And during my searching, MediaPlayer will be instantiated many times(as many as the number of pages I swiped). Don't think that's unnecessary consumption for memory? – Relish Wang Jul 22 '17 at 02:43
  • About your UPDATE: OnClickListener will performance better and avoid your issue. – Relish Wang Jul 22 '17 at 02:48