I'm trying to make my app to play intro clip for only when I start activities.
But from my code it's always play the clip after wakeup before resume to app although I did not closed the app. What can I do to fix this prob?
From main:
startActivity(new Intent(this, MyIntro.class));
From MyIntro:
public class MyIntro extends Activity implements OnCompletionListener {
int a;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.intro);
playIntro();
}
public void onConfigurationChanged(Configuration newConfig) {
setContentView(R.layout.intro);
}
public void onCompletion(MediaPlayer arg0) {
// TODO Auto-generated method stub
this.finish();
}
private void playIntro(){
setContentView(R.layout.intro);
VideoView video = (VideoView) this.findViewById(R.id.VideoView01);
Uri uri = Uri.parse("android.resource://real.app/" + R.raw.intro);
video.setVideoURI(uri);
video.requestFocus();
video.setOnCompletionListener(this);
video.start();
}
}
What function have you overridden in your main Activity - the one where you call
startActivity(new Intent(this, MyIntro.class))
?
I would assume it's onResume() and the line above is executed too many times, because of that. Read again the explanation of Activity lifecycle here, it's the first thing I do, when I have problems like that.
Get back to us with a little more info about the main Activity.
Evil hack:
Add a static pointer to your own activity, fill or override it when "onCreate" gets called. If it's null, play your movie, otherwise, don't.
You could do the same with a static boolean really.
private static boolean isRunning = false;
protected void onCreate(Bundle bundle) {
super.onCreate(bundle)
if(!isRunning)
{
isRunning = true;
//Play your video here
}
}
There are much more elegant and correct ways of doing this, but if you're in a hurry this will probably work.
Related
I'd like to play music across Activities and I'm using a simple class to implement it. This class ( BackgroundMusic ) starts the music with MediaPlayer when I call the startMusic() method and stops it when I call the stopMusic() method. When I use it only in one Activity it works perfectly. OnCreate calls startMusic() method and onPause calls stopMusic() method and the MediaPlayer behave on the right way. The problem starts when I'd like to move to another Activity. When I'd like to stop the music it throws me NullPointerExepction for the mediaplayer.stop() . So it looks like the app thinks that I want to stop a never started MediaPlayer. I tried to call the startMusic() method in every onCreate method but the music starts again and again and I'd like to play only one music which don't stop and starts again when I move to another Activity. Is it possible to do that with class or I have to use Service? I hope you can help me to that with class.
BackgroundMusic
public void startMusic() {
mediaPlayer1 = MediaPlayer.create(context, R.raw.zenenegy);
if(palya <= 5 || palya > 15){
mediaPlayer1.start();
mediaPlayer1.setVolume(0.2f, 0.2f);
mediaPlayer1.setLooping(true);
play = true;
}
}
public void stopMusic(){
if(play){
mediaPlayer1.stop();
mediaPlayer1.reset();
mediaPlayer1.release();
mediaPlayer1 = null;
play = false;
}
}
An Activity
BackgroundMusic bm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fomenu);
bm = new BackgroundMusic(mentes,this);
if(sounds){
bm.startMusic();
}
}
#Override
protected void onPause() {
if(sounds){
bm.stopMusic();
}
super.onPause();
}
If I set the mediaplayer to static in the BackgroundMusic it works perfectly.
Using the following code I can play a video on android in a new Activity. I would however like to preload the video (during a loading screen) and then show it when it is fully loaded. Is it possible to perhaps somehow trigger the activity to show later? In theory It would also be ok to not use a different activity.
public class VideoPlayer extends Activity implements OnCompletionListener,OnPreparedListener
{
private VideoView mVV;
#Override
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.videoplayer);
String url = getIntent().getStringExtra("url");
if(url == null)
finish();
mVV = (VideoView)findViewById(R.id.myvideoview);
mVV.setOnCompletionListener(this);
mVV.setOnPreparedListener(this);
mVV.setVideoURI(Uri.parse(url));
mVV.start();
}
public void stopPlaying() {
mVV.stopPlayback();
this.finish();
}
#Override
public void onCompletion(MediaPlayer mp) {
finish();
}
#Override
public void onPrepared(MediaPlayer mp) {
}
}
from my main activity:
private void playVideo(String url) {
Intent videoPlaybackActivity = new Intent(this, VideoPlayer.class);
videoPlaybackActivity.putExtra("url", url);
startActivity(videoPlaybackActivity);
}
I presume I can use the onPrepared function, but I'm not sure how to do the activity triggering to show the activity later.
http://developer.android.com/reference/android/widget/VideoView.htmlHere are the methods for the VideoView. So there is indeed a:
setOnPreparedListener(MediaPlayer.OnPreparedListener l)
Probably the best way is to use fragments in the activity and show the fragment in the activity where the mVV = (VideoView)findViewById(R.id.myvideoview); is declared when the onprepared is called.
Or hide and show the view in the activity. (using fragments is probably nicer).
Think that will work and that that is what you wanted?
There is a video activity, I need to handle:
1) when the first time enter the activity, get the position from intent and play the video
2) keep the same position after rotate
Here is the code to handle first requirement
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_full_screen);
ButterKnife.bind(this);
if (getIntent() != null) {
video_url = getIntent().getStringExtra("video_url");
pos = (int)getIntent().getLongExtra("time", 0);
}
player.setOnPreparedListener(this);
player.setVideoURI(Uri.parse(video_url));
}
#Override
public void onPrepared(MediaPlayer mp) {
player.seekTo(pos);
player.start();
}
Here is the code to handle second requirement
#Override
protected void onSaveInstanceState(Bundle outState)
{
outState.putInt("time", (int)player.getCurrentPosition());
player.pause();
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
int last_pos = savedInstanceState.getInt("time");
player.seekTo(last_pos);
player.start();
super.onRestoreInstanceState(savedInstanceState);
}
The problem is the handling is conflict to each other.
If first time enter progess is 10s , when I play at e.g. 30s and rotate , it still go to 10s instead of 30s.
It is caused by the seekTo(pos) at the onPrepared function but I can not remove that as it handle the first requirement.
How to fix that? Thanks for helping.
Rotating the screen calls onDestroy(). Are you saving the time progress in onDestroy()? For more info on android life cycle see: https://androidcookbook.com/Recipe.seam?recipeId=2636
I have 6 activities in my app. I want to play different sound throughout whole app. But the problem is that when I start second activity from first activity I want same sound continue from point where its playing in first activity. But unable to find any solution on SO. how to do this? Please help me.
I am using MediaPlayer.
use the application class, or any singleton pattern for that matter you can persist data across activities
https://developer.android.com/reference/android/app/Application.html
In your activities onPause() you have to save the current progress of the track to the shared preferences, then in your activities onResume() get the progress and resume the mediaplayer...
public void onPause() {
super.onPause();
mediaplayer.pause();
int progress = mediaplayer.getCurrentPosition();
getSharedPreferences(getPackageName(), Activity.MODE_PRIVATE).edit().putInt("track_progress",progress).commit();
}
public void onResume() {
int progress = getSharedPreferences(getPackageName(), Activity.MODE_PRIVATE).getInt("track_progress",0);
mediaplayer.seekTo(progress);
mediaplayer.start();
}
Well yeah, or as #Brian says, use a singleton ... :)
Update as a singleton e.g.
public class BackgroundPlayer {
private static final String TAG = BackgroundPlayer.class.getName();
private static BackgroundPlayer instance;
public static BackgroundPlayer instance() {
if(instance==null) instance = new BackgroundPlayer();
return instance;
}
private MediaPlayer mediaPlayer;
public void startBackgroundMusic(Context ctx, int res) {
if(mediaPlayer==null) {
mediaPlayer = MediaPlayer.create(ctx, res);
mediaPlayer.setLooping(true);
}
if(mediaPlayer!=null&&!mediaPlayer.isPlaying())
Log.i(TAG,"started");
mediaPlayer.start();
}
public void stopBackgroundMusic() {
if(mediaPlayer!=null)
Log.i(TAG,"stopped");
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
Now you can access the same instance of the BackgroundPlayer anywhere in your code with
BackgroundPlayer.instance()
and you can call
BackgroundPlayer.instance().startBackgroundMusic(Context, resource);
BackgroundPlayer.instance().stopBackgroundMusic();
anywhere. Now you have to make sure you call .startBackgroundMusic in your first activities onCreate() and call .stopBackgroundMusic in the last activity on the stack, so the sound doesn't keep going when the user leaves your app.
In my Android app, I am trying to simply go back to my main Activity once a video that I am playing ends. I have tried many workarounds, but I can't find a way to call StartActivity from the video onCompletionListener - I am getting the "cannot make a static reference to the non-static method startActivity(Intent) from the type Activity" error.
I tried getting a context from the Activity that preceded the videoView, and passing that to the intent/startActivity. That allowed the app to compile, but then I got a runtime exception.
Here is the code as it stands now, which gets the "cannot make a static reference" error - any help would be appreciated!
public class Videoscreen extends Activity{
public static VideoView myVideoView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoplay);
myVideoView = (VideoView) findViewById(R.id.main_videoview);
System.out.println("playing video oncreate");
playVideo();
}
public static void playVideo(){
// video finish listener
myVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer vmp) {
Intent intent = new Intent();
intent.setClass(Videoscreen.this, Game.class);
Videoscreen.startActivity(intent);
}
});
String low_word = SpellingView.get_low_word();
Uri bubblesUri = Uri.parse("android.resource://org.lalloinc.ilovetrucks/raw/"+ low_word + "_vid");
myVideoView.setVideoURI(bubblesUri);
myVideoView.start();
}
}
If you know the time of the video then you try:
String uri1 = "android.resource://" + getPackageName() + "/" + R.raw.race3;
vd.setVideoURI(Uri.parse(uri1));
vd.start();
new Thread() {
public void run() {
try{
sleep(50000);
} catch (Exception e) {
}
Intent intent = new Intent(Video.this, Another.class);
startActivity(intent);
finish();
}
}.start();
if you don't know the time then you get the time as:
int vtime = vd.getDuration();
And then at thread sleep you just put this integer.
If you started the Video Activity from the Activity you would like to go back to later, just calling finish() at the end of the video will do the job.
Starting the main Activity again creates a not necessarily wanted stack of activities.