Making a temporary Activity .. Like a hello screen - java

I want to make a temporary Activity that allowed me to show it , For Example it is appear only for 5 seconds so how can I make it >> Like a hello screen in the beginning in my app .
By the way I am using Android Studio

The splash screen displays for 2 seconds and then the main activity of the application appears. For this, we add a java class that displays the splash screen. It uses a thread towait for 2 seconds and then it uses an intent to start the next activity.
public class SplashScreen extends Activity {
private long ms=0;
private long splashTime=2000;
private boolean splashActive = true;
private boolean paused=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread mythread = new Thread() {
public void run() {
try {
while (splashActive && ms < splashTime) {
if(!paused)
ms=ms+100;
sleep(100);
}
} catch(Exception e) {}
finally {
Intent intent = new Intent(SplashScreen.this, Splash.class);
startActivity(intent);
}
}
};
mythread.start();
}
}

Related

Android Studio Splash Screen Test - java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

I've created a splash screen in my app that displays for 3 seconds before moving to LogInActivity. It looks like this:
public class SplashScreenActivity extends AppCompatActivity {
// Splash screen displays for 3 seconds.
private static int SplashTimer = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
finishTiming();
}
public void finishTiming() {
Handler h = new Handler(Looper.getMainLooper());
h.postDelayed(new Runnable() {
#Override
public void run() {
// App then transitions to login activity.
Intent intent = new Intent(SplashScreenActivity.this, LogInActivity.class);
startActivity(intent);
finish();
}
}, SplashTimer);
}
}
Now I'm trying to test it and I have two tests. testTimer() checks that the timer works as it should and SplashScreenToLogin() checks that the activity moves to the LogInActivity next:
#RunWith(AndroidJUnit4.class)
public class SplashScreenActivityInstrumentationTest {
SplashScreenActivity splashScreenActivity;
private Instrumentation.ActivityMonitor activityMonitor;
#Before
public void createSplashScreenActivity() {
splashScreenActivity = new SplashScreenActivity();
activityMonitor = InstrumentationRegistry.getInstrumentation().addMonitor(LogInActivity.class.getName(), null, false);
}
#Test
public void testTimer() {
assertFalse(splashScreenActivity.isFinishing());
splashScreenActivity.finishTiming();
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
assertTrue(splashScreenActivity.isFinishing());
}
#Test
public void SplashScreenToLogin() {
splashScreenActivity.finishTiming();
splashScreenActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
LogInActivity logInActivity = (LogInActivity) InstrumentationRegistry.getInstrumentation().waitForMonitorWithTimeout(activityMonitor, 10000);
assertNotNull(logInActivity);
logInActivity.finish();
}
}
My issues is that when I run this I get the following error: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
This error displays at the first line of each test function and I'm not sure why. Can someone explain why it's happening and a potential solution?

Android: Media Player not pausing in second activity using ImageView

I have spent almost the day trying to figure it out and yet could not manage to achieve it. I basically have two activities, MainActivity.java and GameActivity.java. The music stops but after going back to MainActivity.java and coming back to GameActivity.java using ImageView several times.
MainActivity.java
public class MainActivity extends AppCompatActivity {
ImageView iv;
public static final String BG_SOUND_CHECK = "background playing!";
// public static MediaPlayer backgroundSound;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
final MediaPlayer backgroundSound = MediaPlayer.create(this, R.raw.background_music);
handler.postDelayed(new Runnable() {
#Override
public void run() {
backgroundSound.setLooping(true);
backgroundSound.start();
Log.v(BG_SOUND_CHECK, "After loop Started!");
}
}, 3000);
getSupportActionBar().hide();
iv = (ImageView)findViewById(R.id.playImage);
iv.setOnClickListener(new View.OnClickListener(){
public void onClick(View view1){
// backgroundSound.setLooping(false);
backgroundSound.pause();
// Log.v(BG_SOUND_CHECK, "Playing After Play Button Click");
Intent myIntent = new Intent(MainActivity.this, GameActivity.class);
// myIntent.putExtra("backgroundSoundObj",backgroundSound);
startActivity(myIntent);
// Log.v(BG_SOUND_CHECK, "After Game Scene");
}
});
}
}
GameActivity.java
public class GameActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// MainActivity.backgroundSound.pause();
// Rest of the code
}
}
I tried putting the music onPause(); in
1) ImageView onClick();
2) As soon as the GameActivity.java is loaded
but both ways end up pausing it only after I try coming back to MainActivity.java and going to GameActivity.java several times.
Do you see how you put your backgroundSound.start() inside the postDelayed-3000 ?
backgroundSound.pause() anytime before that 3000ms is not going to do anything.
It has nothing to do with going back and forth between your two activities, it just so happens that doing that takes up more than 3000ms, so when you do click for pause(), 3000ms has passed.
What you can do, to fit your current code, is to separate that into a Runnable.
Runnable bgSound = new Runnable() {
#Override
public void run() {
backgroundSound.setLooping(true);
backgroundSound.start();
Log.v(BG_SOUND_CHECK, "After loop Started!");
}
}
Use it with handler.postDelayed(bgSound, 3000)
In your onClick, if you want to stop it from playing before it starts, can use handler.removeCallbacks(bgSound), to stop it after it plays, your pause(). If you don't care to know if it has or hasn't started, you can do both alongside each other, should work fine too.
(if you don't want the music to play after you've left your main activity, you should also do the same actions in your onDestroy and/or onPause)

Activity starts where it shouldn't start

my class MainActivity starts the Activity "GameActivity" by user interaction (button). My class GameView is the view for my class GameActivity and has an implementation of the Runnable interface. Inside I've implemented a Handler as timer, that runs the trigger() method continuously. When gameIsOver == true the game stops and starts the GameOverActivity. Inside the GameOverActivity I've added a Button to commit the score. If you press the Button you get back to the MainView and you can start a new game.
Now to the problem: After I've played the game the GameOverActivity gets started, I commit the score and start a new Game or I end the Game and exit (not kill) the app.
In both ways, sometimes the GameOverActivity starts again and shows me that the Game is over. How could that be? Where is it called from? I guess the timer or the Runnable wasn't stopped correctly, but I really don't know what to do to prevent that problem...
PS: If the GameOverActivity gets started during the game, the game doesn't really end. If I press the back button on my phone, I'm just back in game.
GameView.java
private Handler timerHandler;
private boolean gameIsOver;
private long triggerTime, counter;
public void init() {
gameIsOver = false;
triggerTime = 1000;
counter = 0;
timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
if (gameIsOver) {
return;
}
long millis = System.currentTimeMillis() - startTime;
invalidate();
if (millis > (triggerTime * counter)) {
counter++;
GameView.this.trigger();
}
timerHandler.postDelayed(this, 250);
}
};
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 250);
}
inside the trigger() method:
if (gameIsOver) {
timerHandler.removeCallbacks(timerRunnable);
invalidate();
Intent intent = new Intent(this.context, GameOverActivity.class);
intent.putExtra("EXTRA_SCORE", score);
// some more extras...
((Activity) this.context).startActivity(intent);
((Activity) this.context).finish();
}
EDIT:
GameActivity.java
public class GameActivity extends Activity {
private GameView game;
private int level;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_game);
Intent intent = getIntent();
level = intent.getExtras().getInt("EXTRA_LEVEL");
game = (GameView) findViewById(R.id.game);
game.setLevel(level);
}
}

How to restore to exact activity after coming from Paused or Resumed state in android

I have two simple activities MainActivity and ThreadActivity. I call ThreadActivity from MainActivity.
The code ofMainActivity:
public class MainActivity extends Activity {
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.btn2);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ThreadActivity.class);
startActivity(intent);
}
});
}
}
And the code of ThreadActivity:
public class ThreadActivity extends Activity{
private Thread myThread=null;
Button btn;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runThread();
}
});
}
void runThread(){
myThread = new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
Log.d("Thread", "I am running " + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
};
myThread.start();
}
}
When I start ThreadActivity I run a simple thread and change button text.
My Problem
When I loose focus from application, i.e when application becomes partially visible, and I come back I am redirected to ThreadActivity and the thread is still running.
When I leave application running and open a new application, and then come back, I am again redirected to ThreadActivity.
The problem is when I press back button, I am being redirected to first activity MainActivity. But instead when back button is being pressed I want my application to exit. In a few words MainActivity should not exist in the stack.
I tried setting android:noHistory="true" for MainActivity but I could not keep the behavior explained in bullet points working. I mean when I pause the application and restore it back, it redirected me to MainActivity instead of ThreadActivity.
Just call finish() when starting the ThreadActivity:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ThreadActivity.class);
startActivity(intent);
finish();
}
});
BUT there is a problem with your app. Use a Timer to set the text of the Button! By using a Thread like you do you are creating a memory leak and that is very bad. Try this:
private int i = 0;
private Timer timer;
private final TimerTask timerTask = new TimerTask() {
#Override
public void run() {
btn.post(new Runnable() {
#Override
public void run() {
btn.setText("#" + i++);
}
});
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timer = new Timer();
timer.schedule(timerTask, 300, 300);
}
});
}
#Override
public void onPause() {
super.onPause();
if(timer != null) {
timer.cancel();
}
}
From your comments to other peoples' answers, it seems like you want the ThreadActivity to always be resumed instead of the MainActivity when your thread is running.
Do the thread in a Service - the service will mean your application's VM is likely to be kept alive longer. An app with no foreground activities can be killed off quite quickly (even if it has background threads running).
You need to persist that the thread is running, and the progress (if, in the real code that is applicable). Currently you could persist the value of i in your while loop.
Your application's default launcher activity (MainActivity) will launch when you click on it from your launcher. Check if the persisted value has been set, and act as though the user started the ThreadActivity in onCreate, if you finish() in onCreate, the user won't see any UI from the MainActivity
Depending on what you're actually trying to do, you might be able to resume the thread depending on the progress persisted - in this example, you could start from the persisted value of i (instead of 0).
What I had to is set android:noHistory="true" for MainActivity and in the ThreadActivity I had to add the solution mention by #NeTeInStEiN in this quesiotn
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;
}
return super.onKeyDown(keyCode, event);
}

Splashscreen is only showed sometimes

I defined a splashscreen the following way:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExceptionHandler.register(this);
setFullscreen();
splashScreen();
}
private void splashScreen() {
runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.splashscreen);
splash = (ImageView) findViewById(R.id.splashscreenLayer);
startSplashTime = new Date();
}
});
new LoadingThread().start();
}
private class LoadingThread extends Thread {
#Override
public void run() {
checkNetwork();
}
}
Somewhere at specific conditions in the checkNetwork() method, the stopSplash method is called:
public void stopSplash() {
Message msg = new Message();
msg.what = STOPSPLASH;
Date endSplashTime = new Date();
long time = endSplashTime.getTime() - startSplashTime.getTime();
System.out.println("Time Splashscreen was displayed: " + time);
if (time < SPLASH_MIN_TIME) {
long delay = SPLASH_MIN_TIME - time;
System.out.println("Delay Splashscreen for: " + delay);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
splashHandler.sendMessage(msg);
} else {
System.out.print("Show Splashscreen now");
splashHandler.sendMessage(msg);
}
}
private Handler splashHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case STOPSPLASH:
splash.setVisibility(View.GONE);
break;
}
super.handleMessage(msg);
}
};
The problem is, sometimes (maybe 1 of 10) if I started the app directly from Eclipse, the Splashscreen isn't showed, but instead just a black screen.
Other problem: if i restart the app, e.g. after onDestroy() was called after clicking the back button on the device, the Splashscreen is almost never shown.
Any hints why?
My assumption: could it be, that the LoadingThread starts "faster" than the Runnable, and so the network staff is done before the Splashscreen is set?
You might try using a CountdownTimer in your implementation. On your first activity, start a CountdownTimer that checks in onTick() every so often for a synchronized boolean finishedLoading with some kind of timeout in onFinish() (15 seconds or something), while your loading is done in another thread that sets finishedLoading to true when it is finished.
Maybe the splash screen isnt being terminated before the v=next activity starts.. just a thought..

Categories

Resources