The first splashscreen hidden after 5 secondes.
I want to add a second splashscreen like the first before enter in MainActivity.
in #drawable/background_1 <= This is the first image splashscreen I added.
in #drawable/background_2 <= I need to add this image in second splashscreen.
splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background_1" >
</RelativeLayout>
SplashScreen.java
package org.sbynight.app;
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
public class SplashScreen extends Activity {
private static String TAG = SplashScreen.class.getName();
private static long SLEEP_TIME = 5; // Sleep for some time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); // Removes title bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Removes notification bar
setContentView(R.layout.splash);
// Start timer and launch main activity
IntentLauncher launcher = new IntentLauncher();
launcher.start();
}
private class IntentLauncher extends Thread {
#Override
/**
* Sleep for some time and than start new activity.
*/
public void run() {
try {
// Sleeping
Thread.sleep(SLEEP_TIME*1000);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
// Start main activity
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
SplashScreen.this.startActivity(intent);
SplashScreen.this.finish();
}
}
}
Problem Solved - UPDATE OF POST -
1.I create a "SplashScreen2.java" + "Splash2.xml"
2.I added #drawable>background_2 (the second image of splashscreen)
3.I added to In Manifest splash2.....
In my SplashScreen.java, I deleted this code:
// Start main activity
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
SplashScreen.this.startActivity(intent);
SplashScreen.this.finish();
In my SplashScreen.java, Replace by this code :
/**** Create Thread that will sleep for 5 seconds ****/
Thread background = new Thread() {
public void run() {
try {
// Thread will sleep for 1 seconds
sleep(1*1000);
// After 1 seconds redirect to another intent
Intent i=new Intent(getBaseContext(),SplashScreen2.class);
startActivity(i);
//Remove activity
finish();
} catch (Exception e) {
}
}
};
// start thread
background.start();
In my Splashscreen2.java, I added the same code like SplashScreen.java,
Surely with this code now to start the MainActivity.class
// Start main activity
Intent intent = new Intent(SplashScreen2.this, MainActivity.class);
SplashScreen2.this.startActivity(intent);
SplashScreen2.this.finish();
Problems Solved! I have now 2 SplashScreen!
This use-case goes against the Android design guidelines.
Please think about how your users would get a good user experience using your app and get access to your content fast.
Designing Help into Your App
Don't show unsolicited help, except in very limited cases
Naturally, you want everyone to quickly learn the ropes, discover the
cool features, and get the most out of your app. So you might be
tempted to present a one-time introductory slideshow, video, or splash
screen to all new users when they first open the app. Or you might be
drawn to the idea of displaying helpful text bubbles or dialogs when
users interact with certain features for the first time.
In almost all cases, we advise against approaches like these because:
They're interruptions. People will be eager to start using your app,
and anything you put in front of them will feel like an obstacle or
possibly an annoyance, despite your good intentions. And because they
didn't ask for it, they probably won't pay close attention to it.
They're usually not necessary. If you have usability concerns about an
aspect of your app, don't just throw help at the problem. Try to solve
it in the UI. Apply Android design patterns, styles, and building
blocks, and you'll go a long way in reducing the need to educate your
users.
Source: http://developer.android.com/design/patterns/help.html
I don't really understand why you would want to add a second "splash screen". If you really did want to do it, why not make the MainActivity your SplashScreenActivity and then move onto a new activity from there.
I have an activity that is using the Theme.Dialog style. It's a popup for my quiz game, for the wrong answer. But I have a problem. User can click outside the popup dialog themed activity and click on the next question. How to prevent that? I blocked back button and that works fine.
Also, when a user clicks on the popup or outside of it, it starts counting the ON time again. My popup stays ON for 2500 ms. How to prevent that also?
So, basically I don't want to allow any click outside my popup and don't want to reset my delay time when someone clicks on the screen.
Here's the code of the popup window:
public class WrongAnswer extends Activity{
MediaPlayer sound;
TextView wrong;
String correctAnswer, correct;
public final int delayTime = 2500;
private Handler myHandler = new Handler();
public void onUserInteraction(){
myHandler.removeCallbacks(closePopup);
myHandler.postDelayed(closePopup, delayTime);
}
private Runnable zatvoriPopup = new Runnable(){
public void run(){
finish();
}
};
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.wrong);
Bundle extras = getIntent().getExtras();
if(extras !=null) {
tacno = extras.getString("correctAnswer");
}
inicijalizujVarijable();
myHandler.postDelayed(closePopup, delayTime);
}
private void inicijalizujVarijable() {
wrong = (TextView) findViewById(R.id.tvWrong);
wrong.setText("Wrong answer!\nCorrect answer is:\n\n" + correct);
}
}
My activity in manifest:
<activity
android:name="com.myquiz.myquizgame.WrongAnswer"
android:label="#string/app_name"
android:theme="#android:style/Theme.Dialog"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="com.myquiz.myquizgame.WRONGANSWER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
If I got you correctly, this question had been already asked. Here is the answer, and according to it you need to call a setter method on activity, that will close your activity dialog:
this.setFinishOnTouchOutside(false);
I hope it will help you.
Second, every time when user touches WrongAnswer activity — you start new delayed task and cancel previous one here:
public void onUserInteraction() {
myHandler.removeCallbacks(zatvoriPopup);
myHandler.postDelayed(zatvoriPopup, delayTime);
}
that's why you have problems with timer
I am making an Android app with authentication. The startup activity is MainActivity, but when a user is not logged in I start a new activity called LoginActivity.
My problem is that if a user is not logged in and starts the app, he see's a default android app screen (title bar and empty content area) for a split second before the LoginActivity launches.
How can I fix this?
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!userIsLoggedIn())
{
Intent LoginActivity = new Intent(getApplicationContext(), LoginActivity.class);
LoginActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(LoginActivity);
finish();
}
}
}
You can make your MainActivity translucent by setting the activity theme android:style/Theme.Translucent. Which makes the activity transparent so you won't see any thing till other activity starts.
But this has drawbacks. The animation that accours when you click to the application icon, you won't see that anymore and If your userIsLoggedIn() takes more than it should, it will look like the phone is froze for a second to the user.
For such situations, best practice is to have a splash screen activity or welcome screen activity appear as first screen for few seconds (1 or 2 sec). This screen is generally contains your company logo/image, like Facebook app. In this activity you put the logic to decide which activity to call next.
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
if(alreadyLoggedIn)
startActivity(new Intent(SplashScreenActivity.this,MainActivity.class));
else
startActivity(new Intent(SplashScreenActivity.this,LoginActivity.class));
finish();
}
}, 1000);
I have an app start by Splash activity screen for 5 seconds Then open Login activity screen then after you put correct user and password open the Menu activity (listActivity) then each row click open MyCity activity.
UPDATE:
What I'm trying to get is: where ever you are in my app, and you go away from my app for any reason not only when you press the home button but also FOR EXAMPLES:
You press home button to check another app then want to return to my app .
You have notification show new message on whatsup or email, you open your whatsup or open email, then return to my app .
3- You left your mobile for period of time then you want to check my app again .
4- you press power button to close the phone ( lock the screen) , then open the lock and want to return back to my app .
what I mean any time you go away my app for any reason but whithout press back back back button which will exit the whole app
then want to return again to my app must open to
you the login screen to re enter your usename and password again.
I Called finish(); for both Splash activity and Login activity .
I tried:android:clearTaskOnLaunch="true" in the Login activity in the manifest but it doesn'thing.
Any advice will be appreciated,
PLEASE WRITE FULL WORKING CODE.
LOGIN ACTIVITY:
public class Login extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
Button b = (Button) findViewById(R.id.loginbutton);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
EditText username = (EditText) findViewById(R.id.login);
EditText password = (EditText) findViewById(R.id.password);
if(username.getText().toString().length() > 0 && password.getText().
toString().length() > 0 ) {
if(username.getText().toString().equals("test") && password.getText().
toString().equals("test")) {
Intent intent = new Intent(Login.this, Menu.class);
startActivity(intent);
finish(); }
} }
}); } }
Menu Activity :
public class Menu extends ListActivity {
String classes[] = { "City1", "City2", "City3", "City4", "City5"};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(Menu.this,
android.R.layout.simple_list_item_1, classes));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
String cheese = classes[position];
try {
Class ourClass = Class.forName("com.test.demo.MyCity");
Intent ourIntent = new Intent(Menu.this, ourClass);
ourIntent.putExtra("cheese", cheese);
startActivity(ourIntent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}}
MyCity Activity :
public class MyCity extends Activity {
TextView tv1;
String city;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.city);
initializeTextViews();}
private void initializeTextViews() {
tv1=(TextView)findViewById(R.id.city_tv);
city=getIntent().getStringExtra("cheese");
if(city.equalsIgnoreCase("City1")){
tv1.setText(Html.fromHtml(getString(R.string.city1)));}
else if(city.equalsIgnoreCase("City2")){
tv1.setText(Html.fromHtml(getString(R.string.city2)));}
else if(city.equalsIgnoreCase("City3")){
tv1.setText(Html.fromHtml(getString(R.string.city3)));}
else if(city.equalsIgnoreCase("City4")){
tv1.setText(Html.fromHtml(getString(R.string.city4)));}
else if(city.equalsIgnoreCase("City5")){
tv1.setText(Html.fromHtml(getString(R.string.city5)));}
}}
MY MANIFEST:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.demo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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>
<activity
android:name=".Login"
android:label="#string/app_name"
android:clearTaskOnLaunch="true">
<intent-filter>
<action android:name="com.test.demo.LOGIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Menu"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.test.demo.MENU" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MyCity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.test.demo.MYCITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
SECOND UPDATE : i reached halfway to what i want but still some steps i can't achieve it explained as below :
BY applying android:clearTaskOnLaunch="true" to Splash activity ,
and prevent back button behaviour on Menu activity :
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;
}
return super.onKeyDown(keyCode, event);
} }
SO now when press home button away my app then return to my app its:
go directly to Login activity.
but main goal now is :
if :
SCREEN LOCKED when you are away from your mobile , or press lightly the power button to lock the phone .
or
OPENED MESSAGE from notification
or
OPENED EMAIL from notification
or
you have CALL and answer it ,
THEN return to my app it does not go to login activity but you will return to the page where you was befor .
ANY ADVICE PLEASE , THANKS.
THIED UPDATE :
i used another code for override home button and control the back button rather than appling :android:clearTaskOnLaunch="true" to Splash activity in manifest , just apply the down code to Menu activity:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;}
else if (keyCode == KeyEvent.KEYCODE_HOME) {
Intent i=new Intent(Menu.this,Login.class);
startActivity(i);
finish();
return true;}
return super.onKeyDown(keyCode, event);}
If I understand you right, your goal is that users have to enter username and password again, when they come back to your App. So I think the most logical way to achieve this would be to add a check in all your Activities onResume() method to see if you have a username and password and if not, simply go to the login activity. Easiest way would be to have a BaseActivity implementing the check and let all your other activities (except for spash and login) inherit from that BaseActivity.
in pseudo java code
class BaseActivity extends Activity {
onResume() {
super.onResume();
if (!havingUsernameAndPassword()) {
startActivity(loginActivity);
finish();
}
}
}
class AnyOfYourActivitiesExceptSpashAndLogin extends BaseActivity {
onResume() {
super.onResume();
// ... further code
}
// ... further code
}
The implementation of havingUsernameAndPassword() of course depends on how you store the username and password in your login activity. A very simple way would be to store them in some static class members, so they'd survive as long as the Application runs.
Update: a more concrete example
I made a new example also showing how you can save the login data on login to be able to check it later on. Actually it would make even more sense to have just a flag 'loggedIn' and some user-id, but that depends upon your implementation, so I'll stick with username/password here.
class SimpleDataHolder {
public static String username = null;
public static String password = null;
}
class LoginActivity extends Activity {
// ...
// when user has entered valid username/password, store them in SimpleDataHolder:
SimpleDataHolder.username = username; // <-- store username entered
SimpleDataHolder.password = password; // <-- store password entered
}
class BaseActivity extends Activity {
onResume() {
super.onResume();
if (SimpleDataHolder.username == null || SimpleDataHolder.password == null) {
startActivity(loginActivity); // <-- go to login
finish(); // <-- end current activity
}
}
}
class AnyOfYourActivitiesExceptSpashAndLogin extends BaseActivity {
// ... your existing code (if any)
onResume() {
super.onResume(); // <-- this calls BaseActivity.onResume() which checks username/password
// ... your existing code (if any)
}
An application CANNOT re-route the home button without modifying the framework code. Sorry this is NOT possible...
To your second update problem I would suggest overriding the OnResume() method, but you must be careful with what you do in it. I would also suggest you study on how the android lifecycle works.
This is my suggestion :
Have a key in SharedPreferences called exit. In the onCreate() set the value of exit to false
public void onCreate(Bundle ..)
{
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor=preferences.edit();
editor.putString("exit","false");
editor.commit();
.....
}
then in onResume() check the value of exit. If it is true, take the user to the login screen else do not do anything .
public void onResume()
{
super.onResume();
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
String exit=preferences.getString("exit","");
if(exit.equals("true"))
{
Intent i=new Intent(this_activity.thi,login_activity.class);
startActivity(i);
finish()
}
}
then in onPause() set the value of exit to true.
public void onPause()
{
super.onPause();
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor=preferences.edit();
editor.putString("exit","true");
editor.commit();
}
You said that you have taken care of the backbutton. Then this should do it. Your app will always return to the login screen.
Here is the solution I came up with.
Please Download the project at the end of the blog post and test it.
Tested on:
Samsung S3 running android 4.0.4
Emulator running android 2.3.1
The basic idea: We will create a RequireLoginActivity which will be extended by all our activities except the LoginActivity.
Three cases should be captured when the onResume function is called:
Jumping from one RequireLoginActivity to another RequireLoginActivity using a flavor of startActivity.
Jumping from one RequireLoginActivity back to a previous RequireLoginActivity by finishing the current activity.
Coming back to a RequireLoginActivity after hiding it (we should here show the login!)
The basic idea of my solution is to have 2 counters: number of Started activities (startCounter) and number of Paused activities (pauseCounter). Each time an activity starts we will increment startCounter. Similarly, when an activity pauses, pauseCounter should be incremented. In our onResume function, we will decide whether to go to the Sign in by comparing the 2 counters. We will gotoLogin() if the 2 counters are equal!
Let me explain:
At any time, case 1 can be captured simply because upon starting new activities, our startCounter will always be greater that pauseCounter by 1. This is true because we will always have one extra activity started but not paused.
Also, case 3 is easily captured, because once you leave our app, say, using the HOME button, we will increment the pauseCounter and the 2 counters will become equal. Once the app is resumed, the onResume will decide to gotoLogin().
Case 2 is a bit tricky, but simple as well. The trick is by overriding the finish() function and decrementing the startCounter once and the pauseCounter twice in it. Remember that when finishing the activity, onPause is called and our counters are equal. Now by decrementing startCounter once and pauseCounter twice, we ultimately returned to the counters' values of the previous activity, and startCounter will remain greater the pauseCounter by 1 when the previous activity resumes.
Another workaround will be to create a activity(FinisherActivity) and call finish() in its onCreate() method. Then whenever you need to finish a activity on pressing the home button or back button and prevent it from staying on the stack just use an Intent to call FinisherActivity . But remember to setFlags for the intent to Intent.FLAG_ACTIVITY_CLEAR_TOP...I know its not an efficient approach, but it should work..
Actually I dont think i'm sure what exactly your asking, Do you want to press the Home Key built into your android device and start an activity?
Homekey listener
Try This:
if it works then awesome, just through an intent in there to call your login activity
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.KEYCODE_HOME) {
Toast.makeText(MainActivity.this, "Home Key is pressed
Toast.LENGTH_LONG).show();
return true;
}
Toast.makeText(MainActivity.this, "Didnt work", Toast.LENGTH_SHORT)
.show();
return super.dispatchKeyEvent(e);
};
what you are asking is against the way that android works .
when the user presses the home button , he expects that when he returns to the app , everything will stay as it was before , unless he wasn't there for a long time or if he ran a resource consuming app .
it's as if on windows , when you click ALT+TAB , you won't expect to see login on the email client (or messenger , or whatever app you use) .
in any case , you can use onWindowFocusChanged together with any of the functions of activity (onResume,onStart,onRestart,onPause,onStop,...) , and handle only the relavant cases you wish to use .
it's not possible because the home button is exclusive to call launcher application, but you can do your app a launcher application, running in kiosk mode for example, see it and it.
to turn a activity on launcher activity add this on itentfilter on manifest.xml
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
You can't override the home button default behaviour. You achieve the desired result by clicking back button, Home button's default behaviour is to goto Home Screen. My suggestion Override Back Button. Then using intent and setting flags properly you can goto login screen.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
super.onKeyDown(keyCode, event);
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
Intent i= new Intent("yourpackage.login");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);
finish();
break;
}
return super.onKeyDown(keyCode, event);
}
It is difficult to tell exactly what you are asking, however I believe this is what you are looking for: How to make splash screen not to load if app is already in memory . To summarize my post there:
This is a design problem. Your launcher activity should not be your splash screen activity. Instead, open your splash activity in your main activity's onCreate method. That way, if it is opened fresh, onCreate is called and the splash screen is shown. Otherwise, if the app is merely resumed, which calls onResume, there would be no call to open the splash screen activity.
Then you can change your manifest to this:
<activity
android:name=".ui.MainActivity"
android:noHistory="true"
android:screenOrientation="portrait"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".ui.SplashActivity"/>
Have you tried the android:noHistory activity attribute (for each of your activities) in the Android Manifest? That sounds like exactly what you are looking for.
Your code is almost correct: to clear the activity stack when launching your application, you should add android:clearTaskOnLaunch="true" to your root activity, which is Splash, not Login (it will be the first one running, see this question on determining the root activity)!
From the documentation:
This attribute is meaningful only for activities that start a new task
(the root activity); it's ignored for all other activities in the
task.
So if you move the attribute in the manifest from Login to Splash, it should work, your application will always start with the splashscreen.
UPDATE: To restart your app even on incoming calls, screen lock or notifications, you have to add android:noHistory="true" (docs here) to all your other activities, or call finish() in all their onPause() methods.
It's worth mentioning that our answers are so different and complicated because what you want to achieve is totally against core Android concepts (for example, here is a good article on exiting apps), so really, don't do anything like this outside your private app.
You should call finish() in all your activities' onPause() methods except Login activity. And you can call startActivity(new Intent (this, LoginPage.this)) in their onResume() method. So whenever the activities will come to foreground, user will be redirected to Login page again.
My little efforts may helps you, I had successfully Override the HOME button(below Android 4.0)
You can mould the code according to your requirement.
Answer on SO
Source at GITHUB
As you can now handle Home button so you can easily create your own logic to perform you Application flow.
this is you targetted event
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if ( (event.getKeyCode() == KeyEvent.KEYCODE_HOME) && isLock) {
//Logic when Home button pressed
return true;
}
else
return super.dispatchKeyEvent(event);
}
Hoping this will definitely going to meet our requirements.
Note: All this is for capturing Home Button for others you can manage
I was wondering if it's possible to somehow tap outside a popup dialog (or an Activity with a dialog theme), and dismiss it by just tapping outside of it?
I made a quick picture to illustrate it:
Normally, you have to press the back key to dismiss the dialogs, but on Honeycomb it could be great to have the option of just tapping outside the dialog, due to all the screen estate.
dialog.setCanceledOnTouchOutside(true)
Sets whether this dialog is canceled when touched outside the window's bounds.
My app is a single activity with Theme.Holo.Dialog. In my case the other answer did not work. It only made the other background apps or the launch screen to receive touch events.
I found that using dispatchTouchEvent works in my case. I think it is also a simpler solution. Here's some sample code on how to use it to detect taps outside the activity with a Dialog theme:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// Tapped outside so we finish the activity
this.finish();
}
return super.dispatchTouchEvent(ev);
}
There is a TouchInterceptor method which will called when you touch on out side of popup window
For example
mWindow.setTouchInterceptor(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mWindow.dismiss();
return true;
}
return false;
}
});
mWindow is the popup window
And if you want same functionality for Activity you have to follow below steps.
1) Add flag before setContentView() method called in onCreate();
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
2) Override onTouchEvent() event in Activity
and write below code
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Finish", 3000).show();
finish();
return true;
}
return false;
}
The complete copy is here
Activity
package net.londatiga.android;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.Toast;
public class NewQuickAction3DActivity extends Activity implements OnTouchListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make us non-modal, so that others can receive touch events.
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
setContentView(R.layout.main);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
Toast.makeText(getApplicationContext(), "Hi", 3000).show();
return true;
}
return false;
}
}
This is manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.londatiga.android"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".NewQuickAction3DActivity"
android:label="#string/app_name" android:theme="#android:style/Theme.Holo.Dialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You may use
dialog.setCancelable(true\false);
For the lastest vesrions of Android;
It will disable outSideTouching event.
You could use Activity#setFinishOnTouchOutside too, if your dialog is an Activity. That's gotta be the shortest way for Activitys ;)
(It's API 11+ though. But API <= 10 is generally screen size normal.)
dialog = new Dialog(MainActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_layout);
dialog.getWindow().setBackgroundDrawableResource(
android.R.color.transparent);
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(true);
Check if you have this line of code or not....
dialog.setCanceledOnTouchOutside(true);
Simply I write dialog.setCanceledOnTouchOutside(false); and it work for me, window will not dismiss on outside tap .
this.setFinishOnTouchOutside(false);
you can use this
Old question but yet another solution:
Make your foreground activity full-screen. Usenested layouts: The full-screen layout should have transparent background (e.g. #null or #android:color/transparent). The inner layout should have a visible background.
Add an OnClickListener to the invisible outer layout that finish()es your activity.
Use style of dialog rather than other styles.
For example, Use
public YourCustomDialog(Context context) {
super(context, android.R.style.Theme_Holo_dialog_NoActionBar);
}
When you use other styles like Theme_Translucent_NoTitleBar , the dialog will not be dismissed.
LayoutParams lp=dialogp.getWindow().getAttributes();
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;
I added this and it works flawlessly on 3.0 up, but should work on all.
Any views within the dialog can set to consume the touch event so that below won't be called.
onCreate(){
getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
dialog.dismiss();
return false;
}
});