I have implemented login using finger print authentication and it works well.
Below is the Activity that calls the authenticate method:
FingerPrintActivity
onCreate(){
… //Code to initialize the fingerprint manager
FingerprintHandler fingerprintHandler = new FingerprintHandler(this);
fingerprintHandler.startAuthentication(fingerprintManagerCompat, null);
}
FingerPrintHandler
#Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
updateLoginUi("Successfully verified!", true);
}
private void updateLoginUi(String authenticationMessage, boolean result){
if(result){
context.startActivity(…)
}
}
After successfully verifying the fingerprint, I launch the MainActivity,
however, on pressing the back button to go back to the fingerprint activity, I am unable to use the service. What do I need to activate or trigger in order to validate the fingerprint again?
You could move
FingerprintHandler fingerprintHandler = new FingerprintHandler(this);
fingerprintHandler.startAuthentication(fingerprintManagerCompat, null);
from onCreate() to onResume().
In this case it would start authentication everytime you go into the activity, if that is what you want.
Related
I am able to log in and do export/import from my Android app using the v2 Dropbox API. The only problem is on first run when a token is requested and the Dropbox app/website is launched - I have to run Auth.startOAuth2Authentication at least twice with a pause in between to be able to read the token with Auth.getOAuth2Token.
Is there anyway to wait() and get notified when startOAuth2Authentication returns after acquiring a token?
Auth.startOAuth2Authentication(this, getString(R.string.app_key));
//wait for response, retry, or time out and finish
String accessToken = Auth.getOAuth2Token();
prefs.edit().putString(ACCESS_TOKEN, accessToken).commit();
You shouldn't call startOAuth2Authentication twice, and you shouldn't call getOAuth2Token immediately after calling startOAuth2Authentication.
You should start the flow by calling startOAuth2Authentication as shown in the example here:
https://github.com/dropbox/dropbox-sdk-java/blob/master/examples/android/src/main/java/com/dropbox/core/examples/android/UserActivity.java#L36
And then you should complete the flow by calling getOAuth2Token later in onResume as shown in the example here:
https://github.com/dropbox/dropbox-sdk-java/blob/master/examples/android/src/main/java/com/dropbox/core/examples/android/DropboxActivity.java#L22
Here is a simple example for implementing the Dropbox Android API:
https://www.sitepoint.com/adding-the-dropbox-api-to-an-android-app/
Now, to get to the point of your question, you will not be able to get a toke immediately after Auth.startOAuth2Authentication(this, getString(R.string.app_key)); is called. After you call this method, the Dropbox login activity is shown, and you can get the token only after the user logs in (which is in no way immediate, and you have no way of telling how long it will take).
After the user logs in successfully your activity will be resumed, and you can see in the example from the tutorial that the Activity's onResume method is overridden a check is performed in there.
I will copy below the LoginActivity from this tutorial. It should be easy enough to start from here:
public class LoginActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button SignInButton = (Button) findViewById(R.id.sign_in_button);
SignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Auth.startOAuth2Authentication(getApplicationContext(), getString(R.string.APP_KEY));
}
});
}
#Override
protected void onResume() {
super.onResume();
getAccessToken();
}
public void getAccessToken() {
String accessToken = Auth.getOAuth2Token(); //generate Access Token
if (accessToken != null) {
//Store accessToken in SharedPreferences
SharedPreferences prefs = getSharedPreferences("com.example.valdio.dropboxintegration", Context.MODE_PRIVATE);
prefs.edit().putString("access-token", accessToken).apply();
//Proceed to MainActivity
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}
}
}
i was try to create login session with session key, the session key always generate new key either we do Login/registration, i can retrieve the data from my gson
LoginService loginService = retrofit.create(LoginService.class);
Observable<LoginResponse> obs = loginService.logins(emai,pass,"1", Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID), Build.MODEL, Build.VERSION.RELEASE);
obs.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer<LoginResponse>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
public void onNext(LoginResponse loginResponse) {
int responses = loginResponse.getCODE();
String texts="";
if(responses == 1)
{
User user = loginResponse.getDATALIST().get(0);
setPrefIsLogin(true);
setPrefSessionUid(user.getSESSIONKEY(),user.getUSERID());
nextActivity();
}
else{
}
}
});
the question is, how to make handler to handle the save session check if there is another login activity with the same account?
You should never assign two accessToken/Session for one user. You will send the same accessToken to the other instance of the new user. Plus side, user won't be able to duplicate his/her work by two accessToken.
If you want to force the other/first one AUTO-LOGOUT, you can use Firebase notification feature to send a notification to that particular deviceID and force it to stop. You can check firebase's tutorial to see how they work.
Another slow procedure is to check before login & everyother server side work to check if there are instance of same user. You will send an error and user end will receive it and show the error accompanying by logging out the user.
I am creating an app on Android that uses Firebase as database and Batch for pushing notifications. Usually, when my app starts, it goes to the main page, a login activity. The activity verifies if a user is still logged in using:
Firebase dbRef = new Firebase(Constants.URL_DB);
AuthData auth = dbRef.getAuth();
if (auth != null) // Proceed with a logged in user
else // Show authentication layout
My problem is that when I get a notification from Batch, I click on the notification to go to the app but then I am not logged in as I should be... auth == null. I don't want my users to need to log in every time they get a push from Batch. Can I detect that the app started from a notification? How is that I lose authentication from Firebase?
Here is the onCreate and onResume of the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initiating Batch
Batch.onStart(this);
// Initiating layout
setContentView(R.layout.login);
// Setting database
Firebase.setAndroidContext(this);
// Unrelated stuff done here (Setting Views, etc)
}
#Override
protected void onResume() {
super.onResume();
// Getting login information from previous authentication.
Firebase dbRef = new Firebase(Constants.URL_DB);
AuthData auth = dbRef.getAuth();
// I added the addAuthStateListener here
if (auth != null) {
goToHomePage();
}
}
All right I found the problem. When I click on the notification, my MainActivity is called obviously. The thing is that when the user is logged in successfully, I start another Activity using:
startActivityForResult(intent, Constants.SUCCESS);
Now, onActivityResult is normally called to log out the user when the back button has been pressed on the home page. Otherwise, onResume is called and since the user is logged in, I would go straight back to the home page. BUT: when I click on a notification, somehow onActivityResult is called (probably because the activity stack gets trashed) and the user is logged out before resuming the activity.
So the solution is to log out the user in the onBackPressed of the home page activity. Then I don't need to startActivityForResult anymore.
// In the home page activity
#Override
public void onBackPressed() {
super.onBackPressed();
Firebase dbRef = new Firebase(Constants.URL_DB);
dbRef.unauth();
finish();
}
I am trying to achieve the following when a user starts my app:
1- if the user is not logged in then show a login screen.
2- If the user as already created an account and there is a valid token then show start screen.
To this end I have implemented a custom Authenticator based on the tutorial found here http://www.udinic.com/.
The code works, my issue is that it shows the current activity UI briefly then switches to the add Account UI provided by my AccountAuthenticator. How can I fixed this?
This is the code:
#Override
public void onStart(){
super.onStart();
getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAccountManager = AccountManager.get(this);
}
/**
* Get an auth token for the account.
* If not exist - add it and then return its auth token.
* If one exist - return its auth token.
* If more than one exists - show a picker and return the select account's auth token.
* #param accountType
* #param authTokenType
*/
private void getTokenForAccountCreateIfNeeded(String accountType, String authTokenType) {
final AccountManagerFuture<Bundle> future = mAccountManager.getAuthTokenByFeatures(accountType, authTokenType, null, this, null, null,
new AccountManagerCallback<Bundle>() {
#Override
public void run(AccountManagerFuture<Bundle> future) {
Bundle bnd = null;
try {
bnd = future.getResult();
final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN);
showMessage(((authtoken != null) ? "SUCCESS!\ntoken: " + authtoken : "FAIL"));
} catch (Exception e) {
e.printStackTrace();
showMessage(e.getMessage());
}
}
}
, null);
}
force my users to login at the start of the app. I have implemented a custom Authenticator based on the tutorial found here http://www.udinic.com/.
Since your authentication method is asynchronous, you can't prevent the UI from showing. I would implement a Router/Splashscreen Activity that checks the authentication status and then starts either the Login Activity or actual Activity the user sees if he's logged in. Make sure you set your Router Activity to nohistory in your manifest.
If you want to keep it in a single Activity, you should have a full-screen loading indicator in your layout that lays on top of the UI and fades out once you have figured out which layout to show.
I'm struggling to understand the Android AccountManager API. As far as I got thinks working I can use the blockingGetAuthToken method and specify whether Android should provide a notification for user to allow or deny the request. Another possibility is to use getAuthToken and check if KEY_INTENT is returned. If that's the case I could start a new Activity where the user can confirm my request.
My problem is that I would like to call one of these two methods from within a Service. Is there any chance to get a callback once the user has made a decision?
Thanks for your help
If you want a callback after the user has made a decision it's probably better to use the asynchronous version:
AccountManager mgr = AccountManager.get(getApplicationContext());
Account[] accounts = mgr.getAccountsByType("com.mydomain");
// assert that accounts is not empty
You'll want to use an AccountManagerFuture<Bundle> to hold results of the authentication token. This has to be async since the Android device may ask the user to login in the meantime:
private AccountManagerFuture<Bundle> myFuture = null;
private AccountManagerCallback<Bundle> myCallback = new AccountManagerCallback<Bundle>() {
#Override public void run(final AccountManagerFuture<Bundle> arg0) {
try {
myFuture.getResult().get(AccountManager.KEY_AUTHTOKEN); // this is your auth token
} catch (Exception e) {
// handle error
}
}
}
Now you can ask for the auth token asynchronously:
myFuture = mgr.getAuthToken(accounts[0], AUTH_TOKEN_TYPE, true, myCallback, null);