Below is my code to exit my app.
Since I have more than 1 activity, where should I put exitBy2Click() so it can be use for all activities?
I tried to create a new class called "Global", and public exitBy2Click(), but Toast.makeText(this,... not work.
Thanks.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
exitBy2Click();
}
return false;
}
private static Boolean isExit = false;
private void exitBy2Click() {
Timer tExit = null;
if (!isExit) {
isExit = true;
Toast.makeText(this, "click again to quit", Toast.LENGTH_SHORT).show();
tExit = new Timer();
tExit.schedule(new TimerTask() {
#Override
public void run() {
isExit = false;
}
}, 2000);
} else {
finish();
System.exit(0);
}
}
Checking your method, I think that best option would be Inheritance..
Note on example below that you can override onBackPressed() instead of onKeyDown()
public class BaseActivity extends Activity {
private static Boolean isExit = false;
#Override
public void onBackPressed() {
exitBy2Click();
}
public void exitBy2Click() {
Timer tExit = null;
if (!isExit) {
isExit = true;
Toast.makeText(this, "click again to quit", Toast.LENGTH_SHORT).show();
tExit = new Timer();
tExit.schedule(new TimerTask() {
#Override
public void run() {
isExit = false;
}
}, 2000);
} else {
finish();
System.exit(0);
}
}
}
Then, your "real" activities can extends that BaseActivity and this way, onKeyDown and exitBy2Click will be commom to all classes.
public class MainActivity extends BaseActivity {
#override
public void onCreate(Bundle savedInstance) {
}
}
public class SecundaryActivity extends BaseActivity {
#override
public void onCreate(Bundle savedInstance) {
}
}
//ETC
The best place to put this code is literally "nowhere".
Forcibly terminating an Android app is not recommended, and calling System.exit is definitely not something you should ever do in an Android app.
Related
I want to execute a function only when returning to the Application from the background.
I have included the method in onResume, and this does it to a certain extent. Problem is since onResume is fired even on creating the Activity and when returning to the activity from another activity (Ex: From pressing the back button), and the function is executed there as well.
How to avoid this and execute the function only when returning from background?
Ps: My application already has multiple places using startActivity so changing to startActivityForResult is a tedious task.
Also all my Activities are extending from a common BaseAppCompactActivity class and it's where my method is located, so this will apply to the whole application.
Edit 2:
My BaseAppCompactActivity is as below with LifecycleObserver implemented now. This doesn't seem to work though.
public class BaseAppCompactActivity extends AppCompatActivity implements LifecycleObserver {
private String TAG = BaseAppCompactActivity.class.getSimpleName();
#Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
#Override
protected void onPause() {
super.onPause();
stopService();
}
#Override
protected void onPostResume() {
super.onPostResume();
startService();
}
// #Override
// protected void onResume() {
// super.onResume();
//// updateLastAccessedDate();
// }
private void startService() {
startService(new Intent(this, BusinessCacheService.class));
}
private void stopService() {
stopService(new Intent(this, BusinessCacheService.class));
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
private void updateLastAccessedDate() {
//Do something
}
}
Although its a duplicate . Here is a Java implementation i am sharing for sake of help ..
public class MyApplication extends MultiDexApplication implements LifecycleObserver {
private boolean previouslyInBackground;
#Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
#OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onAppBackgrounded() {
previouslyInBackground=true;
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
void onAppForegrounded() {
if(previouslyInBackground){
// Do your stuff Here
}
previouslyInBackground=false;
}
}
Add the Gradle dependency from Lifecycle-aware components Documentation
You can use startActivityForResult instead of startActivity.
Then you can catch the returning inside onActivityResult method.
first set a global boolean variable like this:-
boolean isPaused = false;
now set a methods in your activity :-
#Override
protected void onUserLeaveHint() {
isPaused = true;
super.onUserLeaveHint();
}
or in your onResume method:-
#Override
protected void onResume() {
if(isPaused){
isPaused = false;
}
super.onResume();
}
Do like this
add these variable in your main activity
public static boolean isAppWentToBg = true;
public static boolean isWindowFocused = false;
public static boolean isBackPressed = false;
and also add these methods
private void applicationWillEnterForeground() {
if (isAppWentToBg) {
isAppWentToBg = false;
// Toast.makeText(getApplicationContext(), "App is in foreground", Toast.LENGTH_SHORT).show();
}
}
public void applicationdidenterbackground() {
if (!isWindowFocused) {
isAppWentToBg = true;
// Toast.makeText(getApplicationContext(), "App is Going to Background", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
isBackPressed = true;
Log.d(TAG, "onBackPressed " + isBackPressed + "" + this.getLocalClassName());
super.onBackPressed();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
isWindowFocused = hasFocus;
if (isBackPressed && !hasFocus) {
isBackPressed = false;
isWindowFocused = true;
}
super.onWindowFocusChanged(hasFocus);
}
#Override
protected void onStart() {
Log.d(TAG, "onStart isAppWentToBg " + isAppWentToBg);
applicationWillEnterForeground();
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop ");
applicationdidenterbackground();
}
What I would suggest is create a new boolean variable which say if that is created for the first time in resume and work on it.
Boolean isForeGround = true;
#Override
public void onPause() {
super.onPause();
isForeGround = false;
}
#Override
public void onResume() {
super.onPause();
if(!isForeGround){
isForeGround = true;
// write your code here
}
}
I have an activity that runs the following:
private void loop() {
// TODO Auto-generated method stub
handler.postDelayed(new Runnable() {
public void run() {
DBListern();
handler.postDelayed(this, 5000);
}
}, 5000);
}
I would like to cancel this handle on back button:
public boolean onBackPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
handler.removeCallbacksAndMessages(null);
return true;
}
return super.onKeyDown(keyCode, event);
}
The handler is still running after back button is pressed, how can I stop it?
First of all the right name of the method you are looking for is onBackPressed(). So your code is simply not called by framework. Try
#Override
public void onBackPressed() {
handler.removeCallbacksAndMessages(null);
super.onBackPressed();
}
You need to do this way:
#Override
public void onBackPressed() {
if(mHandler!=null){
mHandler.removeCallbacks(mRunnable);
}
super.onBackPressed();
}
Reason: You need to manually remove callback of Runnable from Handler onBackPress.
Hope this would help you.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loop();
}
private void loop() {
// TODO Auto-generated method stub
handler.postDelayed(new Runnable() {
public void run() {
Log.i(TAG,"run");
handler.postDelayed(this, 5000);
}
}, 5000);
}
Handler handler = new Handler();
#Override
public void onBackPressed() {
super.onBackPressed();
handler.removeCallbacksAndMessages(null);
}
}
this works for me.
For removed handler messeges, you need set not null in method parametrs. Its Must bee lenk on object , or message type, what do yo like to remove. And why you made this chek
if (keyCode == KeyEvent.KEYCODE_BACK) {
its realy nesesary?
Android activity has overridden method onUserInteraction.But how can I check the user interaction in the dialog?I want to develop some logic based on this.Please help
This code works (onUserInteraction)fine with Activity
public class MyBaseActivity extends Activity {
public static final long DISCONNECT_TIMEOUT = 300000; // 5 min = 5 * 60 * 1000 ms
private Handler disconnectHandler = new Handler(){
public void handleMessage(Message msg) {
}
};
private Runnable disconnectCallback = new Runnable() {
#Override
public void run() {
// Perform any required operation on disconnect
}
};
public void resetDisconnectTimer(){
disconnectHandler.removeCallbacks(disconnectCallback);
disconnectHandler.postDelayed(disconnectCallback, DISCONNECT_TIMEOUT);
}
public void stopDisconnectTimer(){
disconnectHandler.removeCallbacks(disconnectCallback);
}
#Override
public void onUserInteraction(){
resetDisconnectTimer();
}
#Override
public void onResume() {
super.onResume();
resetDisconnectTimer();
}
#Override
public void onStop() {
super.onStop();
stopDisconnectTimer();
}
}
But how can I use 'onUserInteraction' method with Dialog ?
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
final Dialog dialog = new Dialog(MainActivity.this);
//setting custom layout to dialog
dialog.setContentView(R.layout.cusotm_dialog_layout);
dialog.setTitle("Custom Dialog");
//adding text dynamically
TextView txt = (TextView) dialog.findViewById(R.id.textView);
txt.setText("Put your dialog text here.");
ImageView image = (ImageView)dialog.findViewById(R.id.image);
image.setImageDrawable(getResources().getDrawable(android.R.drawable.ic_dialog_info));
//adding button click event
Button dismissButton = (Button) dialog.findViewById(R.id.button);
dismissButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
I have implemented onUserInteraction for DialogFragment. This has the same handling as Activity for onUserInteraction. The setUserInteractionEnabled method can also be implemented in an Activity subclass.
public abstract class BaseDialogFragment
extends DialogFragment
{
protected void onUserInteraction()
{
Activity activity = getActivity();
if(activity != null)
{
activity.onUserInteraction();
}
}
protected void setUserInteractionEnabled(Dialog dialog, boolean enabled)
{
if(!enabled)
{
dialog.getWindow().setCallback(dialog);
return;
}
dialog.getWindow().setCallback(new WindowCallbackWrapper(dialog)
{
#Override
public boolean dispatchKeyEvent(KeyEvent event)
{
onUserInteraction();
return super.dispatchKeyEvent(event);
}
#Override
public boolean dispatchKeyShortcutEvent(KeyEvent event)
{
onUserInteraction();
return super.dispatchKeyShortcutEvent(event);
}
#Override
public boolean dispatchTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
onUserInteraction();
}
return super.dispatchTouchEvent(event);
}
#Override
public boolean dispatchTrackballEvent(MotionEvent event)
{
onUserInteraction();
return super.dispatchTrackballEvent(event);
}
#Override
public boolean dispatchGenericMotionEvent(MotionEvent event)
{
onUserInteraction();
return super.dispatchGenericMotionEvent(event);
}
});
}
}
Call this in your onCreateDialog.
public class MyDialogFragment
extends BaseDialogFragment
{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
Dialog dialog = new Dialog(getContext());
setUserInteractionEnabled(dialog, true);
return dialog;
}
}
Note: this will not call onUserInteraction from the dialog's soft keyboard. That should be handled from a TextWatcher that calls onUserInteraction in afterTextChanged.
I want to exit the app only when double tap continously. I am using fragment class. I used the below code but doesn't work
private long lastPressedTime;
private static final int PERIOD = 2000;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
if (event.getDownTime() - lastPressedTime < PERIOD) {
finish();
} else {
Toast.makeText(getApplicationContext(), "Press again to exit.",
Toast.LENGTH_SHORT).show();
lastPressedTime = event.getEventTime();
}
return true;
}
}
return false;
}
please guide me how to implement this in an app.
#Override
public void onBackPressed() {}
in your activity, because activity responsible for back button handling
Look to this question, it has not got an accepted answer, but contain some solutions
Remove your implementation inside onKeydown and try this code
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
try this :
private boolean doubleBackToExitPressedOnce;
#Override
public void onBackPressed() {
Log.i(tag, "Start: On Back Pressed!");
if (doubleBackToExitPressedOnce) {
Log.i(tag, "Double Back Pressed!");
super.onBackPressed();
return;
}
doubleBackToExitPressedOnce = true;
Toast.makeText(this, R.string.msg_exit, Toast.LENGTH_SHORT).show();
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 2500);
}
dont forget to add this line in onResume:
#Override
protected void onResume() {
doubleBackToExitPressedOnce = false;
}
I have set ontouch listener to implement a counter for my imagebutton. But I can only detect button being touched and release. I am not sure how to implement incrementing as long as the button is pressed and how to stop it after it is released. Following is the code I have:
up.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
pressdown();
}
else if (event.getAction()==MotionEvent.ACTION_UP) {
pressrelease();
}
return true;
}
Ok. Here's a solution to my own question. It might help someone else.
use a Handler object because you have to implement a separate thread for incrementing/decrementing
public class MainActivity extends Activity{
private boolean autoIncrement = false;
private boolean autoDecrement = false;
private final long REPEAT_DELAY = 50;
private Handler repeatUpdateHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.input);
class RepetitiveUpdater implements Runnable{
#Override
public void run() {
if (autoIncrement) {
increment();
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(), REPEAT_DELAY);
}
else if(autoDecrement){
decrement();
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(), REPEAT_DELAY);
}
}
}
up.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
increment();
}
});
up.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
autoIncrement = true;
repeatUpdateHandler.post(new RepetitiveUpdater());
return false;
}
});
up.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP && autoIncrement ){
autoIncrement = false;
}
return false;
}
});
public void increment(){
if (i<100) {
i++;
TextView no = (TextView)findViewById(R.id.no);
no.setText(String.valueOf(i));
}
}
}
Do the same for decrement.
Courtesy: Github, author: Jeffrey F. Cole