Dealing with re-authentication with AccountManager in a large Android app - android

I'm using AccountManager in a fairly large Android app and am using Retrofit and Otto to handle REST Requests. When a user's token no longer works a 401 error gets returned to my REST Handler.
What I would like is for the REST handler to be able to show the login activity, but since it's not an activity it can't start the getAuthToken process. My next thought is to send a message back to the calling activity using Otto to let it know that the auth token no longer works, then have that activity start the auth process, which seems like it would work, but I have several activities and it doesn't seem like the right away to go about it, handling something that is application wide on an activity level.
How do other people handle this? Do you just put the re-authentication code everywhere that a user might need to re-authenticate?

Related

calling AccountManager#getAuthTokenByFeatures from multiple WorkerThreads at the same time

Background
I am using AccountManager with a custom account type. In the beginning the App starts the user LogInActivity and a token recieved by the server is stored within the account. The tokens are used by some Worker organized by WorkManager to sync data in the background. Each worker is requesting the token with AccountManager#getAuthTokenByFeatures(). When the user is changing the password on the website connected with the server, the token is expired and the AccountManager is starting (due to password change) the related LogInActivtiy.
Issue If during the user input of the new login data other (parallel running) Worker are requesting an AuthToken, the LogInActivity is started multiple times.
Solution Approach
Setting android:launchmode="singleInstance"of LogInActivity -> only one Activity is started, but second, third, ... calling Worker results in deadlock due to no return of AccountManagerFuture<Bundle>.
Creating Workaround: AccountAthenticator checks if an Instance of LogInActivity is allready running in Foreground and starts all further Activities invisible in the background. If LogIn was successfull all in the background running LogInActivities recieving necessary Information via LocalBroadcastManager -> LocalBroadcastManager is deprecated, power consuming and unnecessary overhead
Is the use of AccountManager in combination with WorkManager correct in this case?
Might there any configuration issue with AccountManager causing this behavior?
Any other solution approaches?
Help is really appreciated. Thank you!

Getting a result back from a service which is not part of the same application

Overview of my use-case :
I have an application, which contains a service SignInService. This service accepts login credentials, initiates authentication (by
hitting a 3rd party API) and gets the result (success/failure). I
have some applications say, App1 (having Activity1) and App2
(Activity2), both of which have a UI and basically start
SignInService with the login credentials and wait for the result of
authentication. Both of these activities will then dynamically change
the UI based on the result.
I have done some research and found some solutions none of which seem to apply to my situation :
Solution : Sending a broadcast from SignInService and receiving it in my applications using BroadcastReceivers.
Problem : This won't be giving the result back to the activity that initiated the service and is waiting to change it's UI based on the result.
Solution : Using ResultReceiver callbacks.
Problem : Works with activities and services in same application.
Is there another way to implement this functionality ? I have explored both Services and BroadcastReceivers and didn't seem to find a solution (maybe I missed something) .
p.s : I have not included any code because I don't think this problem is code specific. Also, I'm not really bent on using Service to perform the sign-in and want to my options open to all kinds of solutions.

Keep Twilio clientDevice in memory on Android so call can be placed immediately

I am developing an app that is designed to allow emergency calls using Twilio - my code is derived from https://github.com/twilio/twilio-client-quickstart-android.
All I've done which is different to the GitHub code is create a separate AlertManager class that does the Twilio initialisation outside of an Activity.
At any moment a user must be able to open the app and tap a button which will (as quickly as possible) make an emergency call using Twilio.
My issue is that Twilio requires the creation of a clientDevice by requesting a "capabilityToken" from my server. That is fine, but the token expires after an hour.
Assuming there is always an external internet connection, how can I make it so my application always has a clientDevice (with a valid token) object available in memory somewhere, such that when the user enters the Activity to make an emergency call, they are able to do it immediately without the app having to request a new token nor create a new clientDevice?
From a quick test using Airplane mode and hard coding a valid token it appears the Twilio SDK can create a clientDevice as long as it has a token, i.e. only one network request is required to retrieve the token, rather than two if another is required to create the clientDevice.
I know I could use some kind of Service to fetch tokens, but I'm not entirely sure where I can store my clientDevice. It can't reside inside an Activity since the app will not always be running. I did wonder about creating my own Application class but as I understand it Android can and will create new instances of that class when it needs to which would then result in my clientDevice being removed from memory. Or is it possible to store it in the Service and then send some kind of broadcast to the Service to make the call?
I hope that makes some kind of sense and if anyone has any ideas it would be much appreciated.
Twilio developer evangelist here.
I have a couple of ideas about the token expiry.
First up, you can set the token expiry time up to 24 hours.
Second, you could use Twilio's AccessManager library that takes an access token and lets you listen to events for when a token is close to expiry or when it expires.
I don't know about keeping live objects while your application is in the background though I'm afraid. Hopefully someone else can help you here.

Android - API Request Callback after onDestroy

I hope I can explain this well ...
I am trying to understand better how to handle HTTP callbacks in Android, so I have created a simple app that uses Volley for HTTP requests. It only has a button that triggers an HTTP request to a service that, basically, just updates a number in a database and sends it in the JSON response after 5 seconds. The Activity gets the response and displays the response in a TextView. I am testing it in a real device that has enabled the "Don't keep activities" option in Settings - Developer Options.
This is the scenario I am testing:
Start App.
Tap the button that triggers the HTTP request.
Inmediately after tapping the button, tap the device's home button to send the app to background. onDestroy method is called because of the "Don't keep activities" option.
Wait a few seconds for the HTTP response. I can see the device gets it because it is printed in the logcat monitor and the database is updated.
Before running the callback, I check that the activity is still alive. Since the activity has been destroyed, the callback is ignored. If the app is restored from background, there is no crash but the Network Response is missed. Also, if I tap the button again, it sends a new HTTP request and increases the number again ...
So, the questions are:
Which are the best practices to deliver network responses to the UI? I mean, if instead of a simple operation let's say it was a register form and I get a phone call or something that forces me to send the app to background, where anything can happens, how can I make sure to not miss the network callback? Is there something that could delay the callback execution until the app is again in foreground?
Is there a way to save a Bundle like the one in onSaveInstanceState after onDestroy has been called and restore it when app is again in foreground?
Let's say the information that the HTTP response contains is sensitive. Is there a recommended way to handle this case? I was thinking to save the response in the internal storage and check for it when the app is again in foreground, but I don't know if it is possible to do that after onDestroy has been called, or if it not a good idea with sensitive data.
Thanks in advance!
1)YOu can never miss the network callback. You'll be called even if you're in the background, unless your entire app (not just the activity is killed). You'll just get the callback while backgrounded.
2)No. If you need the result of a network call the next time the activity starts like that, I suggest you use a Loader to load the data. That way you can query for the Loader results next time, and start the request only if needed.
3)Do what I suggested in 2 and there's no need for this question, its all in app memory.

Notification of Activity from AsyncTask

Within an AsyncTask, I am making a REST call to retrieve data. Within that AsyncTask, I may encounter an exception which I would like to package up (the HTTP code) and inform the Activity, which based on the HTTP response code (Timeout, Unauthorized, etc), would display different messages to the user.
What would be the best way to bubble that information up to the Activity for processing?
I have looked at a number of different Android mechanisms such as Notification, Handler, etc but I can't seem to determine a good architectural pattern for this situation.
If the error causes a halt in the users workflow, then you need to obtrusively interrupt using a dialog alert and then direct the user to the fix. If the error does not stop the user, then interrupt unobtrusively using a toast or notification.

Categories

Resources