3

i have a question if there is decent way to handle this situation:

i would like my app to launch passcode activity as soon as application is launched for very first time or then user resumes it from background (for example user clicks home button and moves application into background and then launches it again).

I know i can do this using special permissions and granting access to system tasks, but i don't want to do this way. Also some of you will suggest to use onPause, onResume and onStop - making a boolean variable and change it state from true to false. But this only work when you have one activity - as soon as you move from activity to activity you have to add onActivityResult or something to handle boolean variable.

so maybe you can suggest something more?

UPDATED:

this is sample code from my app main activity:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
        requestPinCode();
        }
/* .. */
}

private void requestPinCode() {
    boolean pinStart = false;
    SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    pinStart = appPrefs.getBoolean("switch_pincode", false);
    if (pinStart) {
        Intent intent = new Intent(this, PinCodeActivity.class);
        startActivity(intent);
    }
}

if pinStart is true - it means lock is activated and user must enter passcode on app start. But if you just click home button and start app again no passcode is asked. How to handle this? i want to launch passcode activity as soon as user enters app, but as he navigates inside app - no passcode. Also i want to have this in every activity, not only in main.

tereru
  • 268
  • 3
  • 9
  • Are you trying to make another screenlock that is just for your app instead of whole phone? – VM4 Jan 07 '14 at 11:01
  • you can store boolean value in preference – Hardik Jan 07 '14 at 11:02
  • nope, i am trying to have screenlock only for my app. it is a part of application, just for some data protection. – tereru Jan 07 '14 at 12:12
  • It is unclear from who you are trying to protect this info, because another screenlock just specifically for your app will most likely just annoy the user and provide no added security. What are you trying to protect it from, someone stealing the phone? – VM4 Jan 07 '14 at 12:22
  • i am trying to protect application inner data from for example family member who accidentaly took phone to browse and wants to check what data this app contains. It is finance manager so it has to have a passcode. Also i have made this through checkbox, so if user doesn't want to protect app - easily unchecks a passcode. – tereru Jan 07 '14 at 12:33
  • This is a functionality I have never seen before. You usually have to do some login or smthn to the app, but adding extra protection in one app is new to me. Android 4.2 added multiple user accounts for Tablets, but phones are not considered devices you should share. The lockscreen protects your phone from eavesdroppers, thats it. – VM4 Jan 07 '14 at 13:47

2 Answers2

2

You can store your boolean value in shared preferences, that way it stays persistent in memory even if you switch Activities. For example: when you want to unlock your app (for example in onStop()) you can just set it to false with this method:

public void setLockStatus(boolean lock) {
   getSharedPreferences("SOMETAG", 0).edit().putBoolean("LOCK", lock)
        .commit();
}

Later when you want to check if your app is locked (maybe in onStart of next activity):

public boolean getLockStatus() {
    return getSharedPreferences("SOMETAG", 0).getBoolean("LOCK", true);
}

Also note that this method will return true if no "LOCK" value has been set (as indicated by the second param to getBoolean).

So every Activity that you have when it starts checks our flag if the App is locked.

@Override
public void onStart() {
    super.onStart();
    if (getLockStatus() == true) {
        // show lockscreen
    } else {
       // we are not locked.
    }
}

Now we need one more flag to check if we are still in the App and never left:

public void setAppStatus(boolean status) {
   getSharedPreferences("SOMETAG", 0).edit().putBoolean("IN_APP", status)
        .commit();
}
public boolean getAppStatus() {
    return getSharedPreferences("SOMETAG", 0).getBoolean("IN_APP", false);
}

So now every time we launch a new activity before we start it we have to set a flag that we are still in the App, so that onStop will know that we shouldn't lock the app. For example if your button onClick start a new Activity in the onClick we can do this:

    @Override
    public void onClick(View v) {
         setAppStatus(true); // we are not leaving the app.
         // startActivity(blabla);    
    }

Now onStop checks if we need to lock:

    @Override
    public void onStop() {
       super.onStop();
       if(getAppStatus() == false) setLockStatus(true); // locking the app
       else setLockStatus(false); 
    }

EDIT: also you need to setAppStatus(false); if you are actually leaving the application.

Hope this gives you an idea of how to solve it, you need to implement the back press logic yourself (when to lock the app and when not to).

Community
  • 1
  • 1
VM4
  • 6,321
  • 5
  • 37
  • 51
  • ok then how to handle this situation: app has a lock, user launches first activity which shows passcode activity. user enters passcode and returns back to first activity. but first activity was onStop because passcode activity was on top. this is a loop :) – tereru Jan 07 '14 at 12:44
  • Then you also need a flag that gets set when you startActivity() or press back (and stay in the app) that signals that you never left the app. So for example if your activity cycle is A -> B -> C, pressing back when you are in B will set a flag that you are still in App and you don't need to lock in onStop(). – VM4 Jan 07 '14 at 13:09
  • that is what i am looking for - how to set those flags and where :))) – tereru Jan 07 '14 at 13:11
  • Done. You also need to implement the same logic with pressing back, for example on the first activity you need to lock on back press, and in the others you don't. – VM4 Jan 07 '14 at 13:26
  • Thanks, i will try to adopt this into my app :)! – tereru Jan 07 '14 at 17:37
0

You can maintain some common state across activities by implementing your own application object.

Create a class that extends Application like so:

public class MyApplication extends Application {
    boolean userIsLoggedIn;

    public boolean isUserLoggedIn() {
        return userIsLoggedIn;
    }

    public void setUserIsLoggedIn(boolean loggedIn) {
        userIsLoggedIn = loggedIn;
    }
}

Then use that as your application in the manifest file:

<application ... ... android:name="MyApplication">

Then in your activities you get the application object like this:

@Override
public void onStart() {
    MyApplication myApp = (MyApplication)getApplication();
    boolean isLoggedIn = myApp.isUserLoggedIn();
    if (!isLoggedIn) {
        // .. open login activity
    }
}
doorstuck
  • 2,299
  • 1
  • 22
  • 29
  • please describe a little more how can check if user comes from another activity inside app, or he is relaunching app from background? this is a concern for me, not how to reuse another class for checking logged state.. – tereru Jan 07 '14 at 12:40
  • i have adopted your suggestion, but combined with V M's :) Thanks – tereru Jan 08 '14 at 11:46