I am trying to build an app that works as an alarm clock. I implemented everything with help of the AlarmManager and it works fine. But I have one problem, when the alarm rings it starts an Activity which shows a screen with a button and plays a sound. But it shows only a black screen and vibrates + plays the sound and then after that it shows the alarm screen.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wecker);
laufen = true;
mp = MediaPlayer.create(getApplicationContext(), R.raw.ton);
verstanden =(Button)findViewById(R.id.button1);
verstanden.setOnClickListener(new View.OnClickListener() {public void onClick(View view)
{
finish();
}
});
for (int i=0; i<10;i++)
{
mp.start();
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(1000);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
What can I do to show the activity and play the sound simultaneously?
Thread.sleep(1000); Blocks your UI Thread hence, the black screen shows up.
Use this :
new Thread( new Runnable() {
public void run() {
try {
// Add loop to play music and vibrate here
} catch (InterruptedException ie) {}
}
) }.start();
You have put Thread.sleep(1000); in your onCreate() method which is on your UI Thread. Your activity's UI only shows up at onResume() which is after onCreate() so it doesn't get there until your sleep commands are finished. You need to create a new Thread and run the vibrator/sleep cycle on that Thread. Usage is shown in Shivam Verma's answer.
Related
I've a boot screen structured in this way:
public class BootActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_boot);
Thread welcomeThread = new Thread() {
#Override
public void run() {
try {
super.run();
sleep(2000);
} catch (Exception e) {
} finally {
Intent i = new Intent(BootActivity.this,
Main_activity.class);
startActivity(i);
finish();
}
}
};
welcomeThread.start();
}
}
I've added into layout R.layout.activity_boot an HD background image. I'll use this screen to load some things to use after in my main activity. I've read that activity goes in background and it's paused when another activity is opened and continue to occupy memory space. I've performed App memory monitoring and found that I've about 50Mb of memory used when BootActivity is opened. Since this activity will never be opened again, how should I clear memory to have more memory space for next Activity?
Add System.exit(0); after finish();
#Override
public void run() {
try {
super.run();
sleep(2000);
} catch (Exception e) {
} finally {
Intent i = new Intent(BootActivity.this,
Main_activity.class);
startActivity(i);
finish();
System.exit(0);
}
it may clear some memory
Also you can use intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) with intent it will remove activity from back stack
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
I have 2 layouts, and 2 activities, each one corresponding to a layout, one of them is SplashActivity, and the other is MainActivity. I want the application to open the splashActivity(splash XML shows the logo), wait for 5 seconds and open the main activity, but because of the thread, the setContentView doesn't work properly.
P.S. Also any relative documentation links would be very useful, thanks in advance
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
Thread timer = new Thread() {
public void run() {
try {
sleep(5000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
try {
Class mainMenu = Class.forName("com.carmine.project.MenuActivity");
Intent openMainMenu = new Intent(SplashActivity.this, mainMenu);
startActivity(openMainMenu);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
};
timer.run();
}
your problem is that you are calling timer.run(); instead of timer.start();
timer.run(); calls the run method on the same context of the thread that executed that line (making the UI Thread, in your case, wait for 5s, and blocking every other operation). timer.start() spawns a new thread
I have three images with me and i want them to appear on first layout xml like a splash view so that they can be viewed only once i.e that activity will be called only once when app get's installed or if app get's a new update otherwise app should always start from the Second activity, i don't know how should i begin with this :
Can any one tell me any idea how this can be done.
To show splash for only once.
Next part of this question is here
Coding will be much appreciated.
Save a flag in the Preferences when you start up the application, after you've done the welcome screen stuff. Check for this flag before you show the welcome screen. If the flag is present (in other words, if it's not the first time), don't show it.
In your activity:
SharedPreferences mPrefs;
final String welcomeScreenShownPref = "welcomeScreenShown";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
// second argument is the default to use if the preference can't be found
Boolean welcomeScreenShown = mPrefs.getBoolean(welcomeScreenShownPref, false);
if (!welcomeScreenShown) {
// here you can launch another activity if you like
// the code below will display a popup
String whatsNewTitle = getResources().getString(R.string.whatsNewTitle);
String whatsNewText = getResources().getString(R.string.whatsNewText);
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle(whatsNewTitle).setMessage(whatsNewText).setPositiveButton(
R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(welcomeScreenShownPref, true);
editor.commit(); // Very important to save the preference
}
}
Try this :
public class MainActivity extends Activity {
private Thread mSplashThread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.splash);
final MainActivity sPlashScreen = this;
mSplashThread = new Thread() {
#Override
public void run() {
try {
synchronized (this) {
wait(4000);
}
} catch (InterruptedException ex) {
}
finish();
Intent intent = new Intent();
intent.setClass(sPlashScreen, StartNewActivity.class);// <-- Activity you want to start after Splash
startActivity(intent);
}
};
mSplashThread.start();
} catch (Exception e) {
}
}
#Override
public boolean onTouchEvent(MotionEvent evt) {
try {
if (evt.getAction() == MotionEvent.ACTION_DOWN) {
synchronized (mSplashThread) {
mSplashThread.notifyAll();
}
}
} catch (Exception e) {
}
return true;
}
}
you put an Image in splash.xml to show
to do this you have to detect the first launch of your application. To do so you can store a boolean value as #Nirav suggested.
And for the splash screen, You can consider using Fragments and ViewPager to create an activity which will only be shown for the first time
I have a Splash Screen (Logo Activity) to show the company name for 3 seconds before app starts. I start Main Activity from a thread, here is the code:
public class Logo extends Activity {
Thread t;
public boolean dead = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.logo);
t = new Thread() {
public void run() {
try {
Intent i = new Intent(Logo.this, Main.class);
Thread.sleep(3000);
if (!dead) {
startActivity(i);
}
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
}
The Main Activity is called from a worked thread, is this correct? What are the differents with this code (using runOnUiThread)?
...
if (!dead) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Intent i = new Intent(Logo.this, Main.class);
startActivity(i);
}
});
}
...
I see no difference with this code in debug mode (The same threads, the same operation, etc.). Which is correct?
Starting an intent I think is not an UI operation. runOnUI thread runs UI operation on UI thread. So you can use either of thread (runOnUI or normal). May be normal thread will be good in this situation. But I would like to suggest you use timer instead.
To be honest, I don't like the Thread.sleep. PLease take a look at my solution:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// Do your work here like... startActivity...
}
}, SPLASH_DURATION); // SPLASH_DURATION IS IN MILLISECONDS LIKE 3000
Also you can block the user to prevent the back key like this:
#Override
public void onBackPressed() {
// do nothing! disable user interaction!
}
You should use AsyncTask in "doInBackground" background thread and than sleep your thread(this thread not UIThread) "PostExecute" run on UI Thread than start your new activity
private class mSplashViewer extends AsyncTask<Void,Void,Void>{
protected void doInBackground(Void params){
Thread.currentThread().sleep(3000);
return null;
}
protected void onPostExecute(){
startActivity(...);
}
}
When i click button first time. Program will random text. then when i press button again it will delay slow to show text
my code
public void onClick(View v) {
final MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.yeehaw);
showRandom = !showRandom;
t = new Thread() {
public void run() {
try {
while(showRandom) {
sleep(5);
mp.start();
handler.sendMessage(handler.obtainMessage());
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
};
t.start();
}
Your context isnt clear from your question still i can see that you are trying to delay the thread execution by 5 ms that would not be noticible to you. Increase the sleep duration to see if you overcome you issue.
PFB the detail for the sleep method here
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html
Thanks!