I start studying this: Android SplashScreen
and my app works perfectly with this method.
Unfortunately, I've developed a custom splash screen (not a progress dialog like in the other post) and I'm not able to use the same approach. My splashscreen is a different activity that I starts calling it from the onCreate as a different thread.
Instead of this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false); in the onCreate I do:
Thread splashThread = new Thread() {
#Override
public void run() {
// start the splash screen activity
}
};
splashThread.start();
}
The splashscreeen activity correctly starts.
So I call the AsyncTask as in the default method (doInBackground, onPostExecute) and I'm not able to end the activity that is running the splashscreen and come back to the main one, after all the variables are loaded in the doInBackground.
Any suggestion?
Well, I finally thank JPM for the suggestion to use handlers and I solved with that:
public class SplashScreen extends Activity {
private static Handler mHandler ;
private static Handler mainHandler ;
protected static final int CLOSE_SPLASH = 0 ;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
mHandler = new Handler(){
#Override
public void handleMessage(Message msg){
switch(msg.what){
case CLOSE_SPLASH:
finish();
break;
}
}
};
}
#Override
public void onStart(){
super.onStart();
if(mainHandler != null){
mainHandler.sendEmptyMessage(MainActivity.START_LOAD);
}
}
#Override
public boolean onKeyDown (int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK){
mainHandler.sendEmptyMessage(MainActivity.ABORT_LOAD);
}
return super.onKeyDown(keyCode, event) ;
}
public static void setMainHandler(Handler h){
mainHandler = h ;
}
public static void sendMessage(Message msg){
mHandler.sendMessage(msg);
}
public static void sendMessage(int w){
mHandler.sendEmptyMessage(w);
}
}
In the MainActivity I manage handlers back and forth:
public class MainActivity extends Activity {
private MainActivity _this;
private Handler mHandler;
protected static final int FINISH_LOAD = 0 ;
protected static final int START_LOAD = 1 ;
protected static final int ABORT_LOAD = 2 ;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_this = this;
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case FINISH_LOAD:
SplashScreen.sendMessage(SplashScreen.CLOSE_SPLASH);
break;
case START_LOAD:
initializing();
break;
case ABORT_LOAD:
finish();
}
}
};
startSplash();
}
private void startSplash() {
Intent intent = new Intent(this, SplashScreen.class);
SplashScreen.setMainHandler(mHandler);
startActivity(intent);
}
private void initializing() {
new Thread() {
#Override
public void run() {
long start_time = android.os.SystemClock.uptimeMillis();
doTheHeavyJob();
long duration = android.os.SystemClock.uptimeMillis() - start_time;
if (duration <=3000) {
try {
wait(3000-duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mHandler.sendEmptyMessage(FINISH_LOAD);
}
}.start();
}
}
In this manner I can manage the doTheHeavyJob() function and finish the SplashScreen in both cases: after the job finish and at least after 3000 millis, the minimum duration of my splashscreen to be shown.
I also want to tank Teskio on the anddev italian website for the most of the job done here.
I don't know if that is the way I would have done it since Android has some nice Handler methods that can do some of what you are looking for then you can block on the thread until your items download. Here is how I make a standard Splash screen. This Splash activity is the main activity in the Manifest, and when its done calls the next activities.
import java.io.File;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
/**
* Splash screen to start the app and maybe check if some things enabled
* If not enabled popup and if user enables then continue else close app.
*/
public class Splash extends Activity {
private static final String TAG = "Splash";
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.splash);
// load some stuff
(new Handler()).postDelayed(new splashHandler(), 2000);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "OnActivity result code = " + resultCode);
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == -1) {
// class of the next activity you want to display after the Splash screen
Class<?> className = MainApp.class;
startActivity(new Intent(getApplication(), className ));
Splash.this.finish();
} else {
Toast.makeText(Splash.this, getResources().getText(R.string.stringSplashonActivity), Toast.LENGTH_LONG).show();
finish();
// the program...
return;
}
}
/**
* Runnable class to check if user is logged in already
* and then start the correct activity.
*
*/
class splashHandler implements Runnable{
#Override
public void run() {
.....Do something.....
}
}
}
Then don't forget to define the activity between the applicaton tags in the Android Manifest.xml (for those new to Android)
<activity android:name="Splash" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Hope this helps....
Related
Am trying to include a progessbar in my app before launching my activity.
If any one knows the perfect implementaion let me know.Am tried but not getting the desired solution.
Because of this issue m not able to work further.Plz i need help.
I know the Process how to include the progress Dialog but i want to include ProgessBar.What i really need to do.
M sharing my code that i hv tried:
package com.example.demo1;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private static final int PROGRESS = 0x1;
private ProgressBar mProgress;
private int mProgressStatus = 0;
private Handler mHandler = new Handler();
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
mProgress = (ProgressBar) findViewById(R.id.progress_bar);
// Start lengthy operation in a background thread
new Thread(new Runnable() {
public void run() {
while (mProgressStatus < 100) {
mProgressStatus = doWork();
// Update the progress bar
mHandler.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
}
}
private int doWork() {
// TODO Auto-generated method stub
return 0;
}
}).start();
}
}
https://dzone.com/articles/android-example-progress-bar see if this helps... They have shown buffering progress bar example also...I dont know which one you need but this can help you chose any of them as per requirements...
You can include splash activity like this:->
public class SplashActivity extends AppCompatActivity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
context = this;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashActivity.this, HomeActivity.class);
finish();
}
}, 1000);
}
}
I would like to implement a SplashScreen in my app. I found the best and easiest way is to launch an activity that shows a layout with an image view at the launch of the app and then adding android:noHistory="true" attribute to the manifest.
Now, how do I set the splashscreen activity to launch the MainActivity class after a certain amount of time? Lets say 2 seconds?
This is my splashscreen activity
public class SplashActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splashscreen);
}
}
use
handler.postDelayed(runnable, delayinmilliseconds(2000 in your case));
final Runnable runnable = new Runnable()
{
public void run()
{
//start the new activity here.
}
};
Here is a complete sample.
package com.test.splash;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ImageView;
public class splash extends Activity {
private static final int STOPSPLASH = 0;
//time in milliseconds
private static final long SPLASHTIME = 3000;a
private ImageView splash;
//handler for splash screen
private Handler splashHandler = new Handler() {
/* (non-Javadoc)
* #see android.os.Handler#handleMessage(android.os.Message)
*/
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case STOPSPLASH:
//remove SplashScreen from view
splash.setVisibility(View.GONE);
break;
}
super.handleMessage(msg);
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
splash = (ImageView) findViewById(R.id.splashscreen);
Message msg = new Message();
msg.what = STOPSPLASH;
splashHandler.sendMessageDelayed(msg, SPLASHTIME);
}
}
public class TrackMyMoneyActivity extends Activity {
//member fields
private ProgressBar pbar = null;
private TextView counter_txt = null;
Thread splash_thread = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pbar = (ProgressBar) findViewById(R.id.splashpbar);
counter_txt = (TextView) findViewById(R.id.countertxt);
//define thread
splash_thread = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
int i = 0;
for( i=0;i<100;i++){
pbar.setProgress(i);
// counter_txt.setText(i+" %");
try {
splash_thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(i==100){
Intent intent = new Intent(getBaseContext(), LoginApp.class);
startActivity(intent);
}
}
});
splash_thread.start();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
I hope it will be solved your solution.
You can also use java.util.Timer in this way:
new Timer().schedule(new TimerTask(){
public void run() {
startActivity(new Intent(SplashActivity.this, MainActivity.class));
}
}, 2000 /*amount of time in milliseconds before execution*/ );
public class Splashscreen extends Activity
{
private static final int SPLASH_TIME = 10 * 1000;// 3 seconds
Button logo;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.splashscreen);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
try {
new Handler().postDelayed(new Runnable() {
public void run() {
Intent intent = new Intent(Splashscreen.this,MainActivity.class);
startActivity(intent);
Splashscreen.this.finish();
//overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
}, SPLASH_TIME);
new Handler().postDelayed(new Runnable() {
public void run() {
}
}, SPLASH_TIME);
} catch(Exception e){}
// METHOD 1
/****** Create Thread that will sleep for 5 seconds *************/
Thread background = new Thread() {
public void run() {
try {
// Thread will sleep for 5 seconds
sleep(50*1000);
// After 5 seconds redirect to another intent
Intent i=new Intent(getBaseContext(),MainActivity.class);
startActivity(i);
//Remove activity
finish();
} catch (Exception e) {
}
}
};
background.start();
}
I have a start screen with a short delay, after the delay it moves onto the splashscreen however I cant seem to override the transition and I cant see why...Although the transition does work in debug mode which is very strange
package com.example.android.bubblestrouble;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class Team extends Activity{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final int delay = 3000;
setContentView(R.layout.team);
Thread welcomeThread = new Thread()
{
int wait = 0;
#Override
public void run()
{
try {
super.run();
/**
* use while to get the splash time. Use sleep() to increase
* the wait variable for every 100L.
*/
while (wait < delay)
{
sleep(100);
wait += 100;
}
}
catch (Exception e)
{
System.out.println("EXc=" + e);
}
finally
{
/**
* Called after splash times up. Do some action after splash
* times up. Here we moved to another main activity class
*/
startActivity(new Intent(Team.this, SplashScreen.class));
Team.this.finish();
Team.this.overridePendingTransition(R.anim.fade, R.anim.hold);
}
}
};
welcomeThread.start();
}
}
Straight solution. Show your splash image immediately on activity start and replace in with the needed layout by timer. Something like this(onCreate event of Team activity):
ImageView splashImage = new ImageView(this);
splashImage.setImageBitmap(splashBitmap); // or drawable/resource - as you like
setContentView(splashImage);
Thread timerThread = new Thread() {
#Override
public void run() {
sleep(3000);
Team.runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.team);
}
});
}
}
timerThread.start();
I'm trying to make an activity that is asked for some result. This result is normally returned instantly (in the onCreate), however, sometimes it is nesesary to wait for some internet-content to download which causes the "loader"-activity to show. What I want is that the loader-activity don't display anything more than a progressdialog (and that you can still se the old activity calling the loader-activity in the background) and I'm wondering wheather or not this is possible.
The code I'm using as of now is:
//ListComicsActivity.java
public class ListComicsActivity extends Activity
{
private static final int REQUEST_COMICS = 1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_comics);
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intents.ACTION_GET_COMICS);
startActivityForResult(intent, REQUEST_COMICS);
}
});
}
/** Called when an activity called by using startActivityForResult finishes. */
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
Toast toast = Toast.makeText(this, "The activity finnished", Toast.LENGTH_SHORT);
toast.show();
}
}
//LoaderActivity.java (answers to Intents.ACTION_GET_COMICS action-filter)
public class LoaderActivity extends Activity
{
private Intent result = null;
private ProgressDialog pg = null;
private Runnable returner = new Runnable()
{
public void run()
{
if(pg != null)
pg.dismiss();
LoaderActivity.this.setResult(Activity.RESULT_OK, result);
LoaderActivity.this.finish();
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
String action = getIntent().getAction();
if(action.equals(Intents.ACTION_GET_COMICS))
{
Runnable loader = new Runnable()
{
public void run()
{
WebProvider.DownloadComicList();
Intent intent = new Intent();
intent.setDataAndType(ComicContentProvider.COMIC_URI, "vnd.android.cursor.dir/vnd.mymir.comic");
returnResult(intent);
}
};
pg = ProgressDialog.show(this, "Downloading", "Please wait, retrieving data....");
Thread thread = new Thread(null, loader, "LoadComicList");
thread.start();
}
else
{
setResult(Activity.RESULT_CANCELED);
finish();
}
}
private void returnResult(Intent intent)
{
result = intent;
runOnUiThread(returner);
}
}
It turns out you can do this by setting the activitys theme-attribute to #android:style/Theme.Dialog and calling this.setVisible(false); in the onCreate-method of the activity.
My app have a splash activity
It must display at least 5 seconds
But in this activity I have another thread to sync data from internet
Sync process may take more than 5 seconds or less than 5 second.
If less than 5 seconds, the Handler should wait until fifth second
If more then 5 seconds, the Handler should wait until process complete
How to make the Handler wait another thread?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
syncFromInternet(); // another thread may over 5 seconds
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent;
intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent);
}
}, 5000);
}
You have to make just simple logic Like
When handler completes then check for completion of syncFromInternet method, if it completed open main Activity
When syncFromInternet completes then check for completion of handler, if it completed open main Activity.
Above explanation in code:
boolean isHandlerCompleted = false, isAsyncCompleted = false;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
isHandlerCompleted = true;
if (isHandlerCompleted && isAsyncCompleted) {
openMainActivity();// both thread completed
}
}
}, 5000);
// in your async task add this condition when it completes its task
isAsyncCompleted = true;
if (isHandlerCompleted && isAsyncCompleted) {
openMainActivity();// both thread completed
} // till this line
// make this function to open main activity
openMainActivity() {
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent);
}
You can use an AsyncTask instance and measure the time for syncing with the remote server. If the time is greater than 5 minutes, start the new activity, otherwise - wait till the 5th second:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
private static final long FIVE_SECONDS = 5 * 1000;
private volatile Date mStartTime;
#Override
protected void onPreExecute() {
mStartTime = new Date();
}
#Override
protected Void doInBackground(Void... params) {
// Do the syncing here
syncFromInternet();
Date now = new Date();
long execTime = now.getTime() - mStartTime.getTime();
if(execTime < FIVE_SECONDS) {
Thread.sleep(FIVE_SECONDS - execTime);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
Intent intent = new Intent(...);
startActivity(intent);
finish();
}
};
asyncTask.execute(null, null);
}
You can use this code :
package com.example.untitled;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.File;
import java.io.IOException;
public class MyActivity extends Activity {
private volatile boolean isAvailable = false;
private volatile boolean isOver = false;
private Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
if (isOver) {
Log.e("messageHandler","isOver");
transitToNewActivity();
}else {
Log.e("messageHandler","isOver false");
}
break;
}
}
};
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
syncFromInternet(); // another thread may over 5 seconds
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
isOver = true;
Log.e("mainHandler", "Main handler expired");
if (isAvailable) {
transitToNewActivity();
Log.e("mainHandler", "isAvailable");
}else {
Log.e("mainHandler","isAvailable false");
}
}
}, 50000);
public void transitToNewActivity() {
Log.e("transitToNewActivity","Activity transited");
Intent intent;
intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent);
}
public void syncFromInternet() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(80000);
isAvailable = true;
messageHandler.sendEmptyMessage(0);
Log.e("syncFromInternet", "internet data synced");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
}
}
and please modify it according to your requirement.
you should implement AsyncTask so that this will wait untill your syncFromInternet() is completed.
private class BackgroundSplashTask extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
// show progressbar
}
#Override
protected Object doInBackground(Object[] params) {
try {
syncFromInternet(); // sync in background
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
// dismiss progressbar
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent); // go to SecondActivity after syncFromInternet is completed
finish();
}
}
Call your handler inside syncFromInternet() after execution of thread.