I have my main Activity, it starts with a custom SurfaceView called DrawView being set by setContentView. The Main Activity (Draw) has the following method within it
public void launchCutScene(int scene) {
Intent intent = new Intent(Draw.this, CutScene.class);
startActivityForResult(intent, 0);
}
if I call this method directly after setContentView the new Activity CutScene loads properly. CutScene is as follows
public class CutScene extends Activity implements OnCompletionListener, OnPreparedListener{
String pathToFile = "";
VideoView videoPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pathToFile = "EM Math/" + "st.mp4";
setContentView(R.layout.main);
File root = Environment.getExternalStorageDirectory();
videoPlayer = (VideoView) findViewById(R.id.myvideoview);
videoPlayer.setOnPreparedListener(this);
videoPlayer.setOnCompletionListener(this);
videoPlayer.setKeepScreenOn(true);
videoPlayer.setVideoPath(root + "/" + pathToFile);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onStop() {
super.onStop();
}
#Override
public void onPrepared(MediaPlayer vp) {
videoPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
finish();
}
#Override
public boolean onTouchEvent (MotionEvent ev){
if(ev.getAction() == MotionEvent.ACTION_DOWN){
if(videoPlayer.isPlaying()){
videoPlayer.pause();
} else {
videoPlayer.start();
}
return true;
} else {
return false;
}
}
}
However, if within DrawView I call draw.launchCutScene(0) then the activity still comes up, but the video glitches, it either stays as a black screen and you have to press back to make the activity crash, in which case it will bring up the first activity. Or it will play the sound only but multiple times and un-synced. Either way after it crashes if a launchCutScene call is done again within the DrawView class the video now works fine.
Why is this happening? does anybody understand what I need to do?
Okay, Finely fixed the error!
All I had to do was set my threads runnable boolean to false, then call the activity. Once activity closes my program reinitiates the thread, and everything work hunkydorry now!!!!... So if your getting this Video Bug with your Video Views it's probably because you are running a thread in the background!
Related
I have an Fragment which opens up a new activity in landscape mode which has a videoview to play a video. The problem s when the video is completed the activity with the video should finish and the control should automatically go back to the previous Fragment . Similar should be when the back button is pressed.
Currently, When the video gets completed it restarts and only when the second time it completes the control goes back to the previous Fragment . Same is with the back button press ie. I have o press the back button twice to finish the activity with the video.
Here is some code im doing:-
MainFragment
Intent mIntent = new Intent();
mIntent.AddFlags(ActivityFlags.ReorderToFront);
mIntent.AddFlags(ActivityFlags.NewTask);
mIntent.SetClass(this.Activity, typeof(VideoActivity));
Activity.StartActivity(mIntent);
VideoActivity
public class VideoActivity : Activity, Android.Media.MediaPlayer.IOnCompletionListener
{
private VideoView mVV;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
RequestWindowFeature(WindowFeatures.NoTitle);
SetContentView(Resource.Layout.VideoLayout);
// Create your application here
int fileRes = 0;
fileRes = Resource.Raw.trailer;
mVV = FindViewById<VideoView>(Resource.Id.myvideoview);
mVV.SetOnCompletionListener(this);
if(!mVV.IsPlaying)
{
if (!playFileRes(fileRes)) return;
MediaController mc = new MediaController(this);
mc.SetAnchorView(mVV);
mVV.SetMediaController(mc);
}
else
{
mVV.Suspend();
Finish();
}
}
private bool playFileRes(int fileRes)
{
if (fileRes == 0)
{
stopPlaying();
return false;
}
else
{
mVV.SetVideoURI(Android.Net.Uri.Parse("android.resource://" + PackageName + "/" + fileRes.ToString()));
return true;
}
}
public void stopPlaying()
{
mVV.StopPlayback();
this.Finish();
}
public void OnCompletion(Android.Media.MediaPlayer mp)
{
stopPlaying();
}
protected override void OnResume()
{
mVV.Resume();
}
protected override void OnPause()
{
stopPlaying();
}
public override void OnBackPressed()
{
stopPlaying();
}
}
How do I solve this? Any help would be appreciated.
this is my Splash Screen, If I press home or multitasking/appswitch button when Intent is started app crash, in logcat is FATAL EXEPTION: Thread-1277. Can I kill/delete this Intent when player press home button?
public class SplashScreen extends Activity {
private static int loadingTime = 1000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
setContentView(R.layout.loading_screen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, loadingTime);
}
}
The following code tracks whether the SplashActivity is at least partially showing. If yes, it will continue to MainActivity. If not (activity is finished by pressing Back button, activity is stopped by pressing Home button) nothing happens.
This solution uses Fragments so the timing is preserved across e.g. screen orientation changes (it will always take specified time no matter how many times you rotate your device - the timer will not reset).
public class SplashActivity extends Activity {
// tracks when the activity is at least partially visible (e.g. under a dialog)
private boolean mStarted = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// your current code
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
setContentView(R.layout.activity_startup);
if (savedInstanceState == null) {
// first time onCreate, create fragment which starts countdown
getFragmentManager()
.beginTransaction()
.add(SplashFinishFragment.newInstance(), SplashFinishFragment.TAG)
.commit();
} else {
// fragment already set up from first onCreate after screen rotation
}
}
#Override
protected void onStart() {
// the activity becomes at least partially visible
mStarted = true;
super.onStart();
}
#Override
protected void onStop() {
// the activity is no longer visible
mStarted = false;
super.onStop();
}
public boolean isStarted2() {
// there is already hidden method isStarted() in the framework
// you can't use it and are not allowed to override it
return mStarted;
}
public static class SplashFinishFragment extends Fragment {
private static final String TAG = SplashFinishFragment.class.getSimpleName();
private static final int DELAY = 1000; // one second delay
private static final Handler mHandler = new Handler(); // one main thread anyway
private final Runnable mRunnable = new Runnable() {
#Override
public void run() {
if (getActivity() == null) {
// this should never happen, there is no activity, so no fragment
Log.e(TAG, "No activity!");
return;
}
SplashActivity a = (SplashActivity) getActivity();
if (a.isStarted2() || a.isChangingConfigurations()) {
// if activity is even partially visible or is rotating screen right now, continue
Intent i = new Intent(a, SettingsActivity.class);
a.startActivity(i);
}
// in any case close splash
a.finish();
}
};
public static SplashFinishFragment newInstance() {
return new SplashFinishFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// the countdown will continue (not reset) across screen rotations
setRetainInstance(true);
// try running the main activity after specified time
mHandler.postDelayed(mRunnable, DELAY);
}
#Override
public void onDestroy() {
// if the fragment gets destroyed (e.g. activity closes) do not launch main activity
mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
}
}
This was tested on a virtual Galaxy S2. It works when Home or Back button is pressed. It doesn't work when Recent Apps button is pressed. I don't know your use case but personally I would expect the app to continue launching while I browse recent apps.
I am trying to use a MediaController and alter it so that it does not disappear after 3 seconds. I have found this code in a related question and I am using it:
mediaController = new MediaController(this) {
#Override
public void hide()
{
mediaController.show();
}
};
This code works, but when the activity stops (from using back button), I get log errors about a leaked window from a view added in the code below at the show(0) statement:
public void onPrepared(MediaPlayer mediaPlayer) {
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(findViewById(R.id.audio_control));
handler.post(new Runnable() {
public void run() {
mediaController.setEnabled(true);
mediaController.show(0);
}
});
}
It seems to me that overriding the hide method by simply calling the show method means the hide method is not doing what is needed when finishing the activity. I must be overriding other necessary functionality, like actually hiding the controller!
I want to hide the controller when necessary (such as when finishing with it), but not in the case of when it is simply being hidden after 3 seconds (and the activity is not being finished).
Or maybe I should let the controller disappear after 3 seconds all the time but I am not sure I understand why it is implemented this way. It seems better to just keep it there all the time to me.
It's a bug in the MediaController:
private View.OnClickListener mPauseListener = new View.OnClickListener() {
public void More ...onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
}
};
There are two ways to solve this.
A) Override the hide() method:
class MyMediaController extends MediaController {
#Override
public void hide() {
// Nope, do not hide. Call hideActually() to actually hide.
}
public void hideActually() {
super.hide();
}
}
B) Override the show() methods:
class MyMediaController extends MediaController {
public int mTimeout = 0;
#Override
public void show() {
show(mTimeout);
}
#Override
public void show(int timeout) {
super.show(mTimeout);
}
}
Overriding the hide() method gives you the full control over hiding the MediaController, but you have to ensure calling hideActually() before the Activity is destroyed, else you'll get these log errors about a leaked window.
Overriding the show() methods gives you the chance to set a timeout after all. In this case there are some events on which the MediaController will hide without calling the hide() method explicitly, i.e. when the user presses the back button.
Personally I'd prefer using a mix of both implementations:
class MyMediaController extends MediaController {
public int mTimeout = 0;
#Override
public void show() {
show(mTimeout);
}
#Override
public void show(int timeout) {
super.show(mTimeout);
}
#Override
public void hide() {
// Do not hide until a timeout is set
if (mTimeout > 0) super.hide();
}
public void hideActually() {
super.hide();
}
}
In this case you have full control over showing and hiding the MediaController when mTimeout = 0, but you get the "normal" behaviour of the MediaController when you actually set a timeout.
I am playing videos in my app, video should play portrait and landscape mode withought restarting actvity, please any can give examples are links.
using video view for playing video.
public class PlayVideoActivity extends Activity {
private VideoView video;
private ImageButton back;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
back = (ImageButton)findViewById(R.id.backbutton);
back.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
video=(VideoView)findViewById(R.id.videoView);
video.setDrawingCacheEnabled(true);
video.setDrawingCacheQuality(VideoView.DRAWING_CACHE_QUALITY_HIGH);
video.setVideoURI(Uri.parse("android.resource://"+ getPackageName() +"/" + R.raw.fillings_class_1));
video.requestFocus();
video.setMediaController(new MediaController(this));
video.start();
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//restore the relevant information
}
}
If you really need to prevent the activity from being restarted on an orientation change, you need to set the configChanges attribute for the Activity in the manifest to include orientation.
I have an activity that contains many UI views. In its onCreate method, I found single line of setContentView takes 8-12 seconds to be complete. So I want to show my logo image while it's loading. I tried many things but without any success. I suspect main reason might be that before finishing setContentView, nothing can be shown.
Any help would be appreciated.
UPDATE:
I think many people do not know that you cannot show any dialog before finishing setContentView. So using another splash activity does not help me at all.
UPDATE2
I forgot to update this question after I found cause of the problem. Please refer to following question: setContentView taking long time (10-15 seconds) to execute
use AsyncTask
put splash in onPreExecute()
and do your work in doInBackground()
and close splash in onPostExecute()
Below is the simple code for creating splash screen using CountDownTimer class
public class SplashDialogActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Be sure to call the super class.
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.layout);
counter.start();
}
MyCount counter = new MyCount(5000, 1000);
public class MyCount extends CountDownTimer{
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
go_back();
}
#Override
public void onTick(long millisUntilFinished) {
}
}
public void go_back()
{
counter.cancel();
Intent i=new Intent(this,account.class);
i.putExtra("first_time", true);
startActivity(i);
this.finish();
}
}
try this code for splash page
private Thread mSplashThread;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splesh);
final Splash sPlashScreen = this;
mSplashThread = new Thread(){
#Override
public void run(){
try {
synchronized(this){
wait(5000);
}
}
catch(InterruptedException ex){
}
finish();
Intent intent = new Intent();
intent.setClass(sPlashScreen,Login.class);
startActivity(intent);
stop();
}
};
mSplashThread.start();
}
// Processes splash screen touch events
#Override
public boolean onTouchEvent(MotionEvent evt) {
if(evt.getAction() == MotionEvent.ACTION_DOWN)
{
synchronized(mSplashThread){
mSplashThread.notifyAll();
}
}
return true;
}