Android: calling AccountManager.getAuthToken from within the service - android

I'm making a simple REST client in Android: I created a service that is responsible for the REST calls, but it needs the username and password to operate.
The username and password is stored in a regular account registry, so what I want to do is to retrieve the usernama and auth token in the service.
The problem is that getAuthToken wants to have the Activity as the parameter, but while I'm in the service I don't have any kind of Activity to pass. Is there a known way to deal with this issue? Or I'm doing is all wrong and I shouldn't even try to access this data from within a service?

Not necessarily: I've used http://developer.android.com/reference/android/accounts/AccountManager.html#getAuthToken%28android.accounts.Account,%20java.lang.String,%20boolean,%20android.accounts.AccountManagerCallback%3Candroid.os.Bundle%3E,%20android.os.Handler%29 before from within a Service.
EDIT: The world changed. It is now recommended to use this. You just have to have your app register an IntentReceiver for the LOGIN_ACCOUNTS_CHANGED_ACTION and then you will receive that intent whenever the user enters a password. You very explicitly don't wait for the result: you either get it immediately if they're already logged in or you get told you need to wait for the intent.

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!

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 - sending data to a web service

I'm about to write an application that sends data to a server with a post request. These requests can fail and if they do I want them to be sent when the connection is back online.
What is the best way to implement this behavior?
EDIT
I've read some articles and come up with the following idea. I register a BroadcastReceiver in the manifest and tell it to listen for android.net.conn.CONNECTIVITY_CHANGE and android.net.wifi.WIFI_STATE_CHANGED. When the request can't be send I store the request. If the connection becomes alive then I will send the cached requests.
What is the best way to implement this behavior?
Make Volley requests from a bound Service, and send the result back to the Activity if it is still in the foreground.
EDIT:
won't this be a problem if the user decides to close the application?
That's exactly why you need to use a Service. If you do it from an Activity, the request continues even when the Activity is dismissed. If your Volley request is expressed as an anonymous class instance, it continues to hold an implicit reference to the outer Activity class, which leads to a memory leak / exception.
Check your Internet Connection continuously by using Handler or service ,if it is sends the data to the server otherwise dont send it.

How to inform back Your order is ready? how to check data in server updated?

I am developing an application with login functionality. Users can login and make request for a thing through the server. When the order gets ready I need to inform him/her back (if he/she is not logged Out) that order is ready.
I am using server and an online database. How can I reply back to the person?? the device using may change.
You can use Google Cloud Messaging service to do that.
You can use a service to run in the background and in the service you can keep checking for the response from the server.
When you get a response, you can easily notify to the user.
Another way to this is with the use of AsyncTask. this is a kind of thread that keeps running in the background and updates accordingly on its postExecute method.
You can make this possible from a background service!
All you need to do is :
Start a background service that will check again and again after a specific time that the data is updated or not!
If the data is ready, send the data back to the user's device and check in the service that received data is not null and show a notification that your order is received.
A good example of Android Service

Android - activity lifecycle and HTTP session

I'm reading article "Managing the Activity Lifecycle" (http://developer.android.com/training/basics/activity-lifecycle/index.html) and I'm little confused. Maybe first I'll try to say what my application do. So, this is some kind of http client. User login to the server and client store authorization (session id). After login, TimerTask is executing, which for every 10 seconds get some small json from server and by the way server know that authorization key is still alive (normally it is valid for ~30 minutes). In this json could be some events which should be shown to the user (I'm using notification manager for this) or questions for which user should answer (I'm showing custom dialog with "Yes", "No", "Don't know" and then POST answer to the server).
This works fine when my application is in foreground, but I don't really know what should I do if the application is stopped/paused.
My doubts:
I want that TimerTask should works even if user click home button or another application appear. There are two reasons: One - user need to be notified about events, two - I need to keep alive session id. But this article say that when activity is in foreground, it should release resources. What this mean? What are restrictions? Must I stop my timer?
Documentation say that system can kill application when it is no longer needed. What does it mean no longer needed? When user don't use it or when application code do nothing for a while? Can my TimerTask keep alive application?
Storing authorization key. I need remember session id in situations where activity is recreated by system like orientation change, etc. I'm using for this SharedPreferences object. Problem is that using this object, key is saved in database and I can't recognize when my application is closed permanently (which mean "logout") or just recreated because orientation is changed. This occur situations when user run application again after couple hours and my activity restore dead session id (my application look like "logged in" because authorization variable is not empty and I use this state as a flag). I need some temporary version of SharedPreferences object. What about bundle object passed in onSaveInstanceState? Is it temporary?
Regards
It looks like you are on the right track. I think that you should continue reading documentation. Some suggestions:
Activity life cycle
Context.bindService()
ServiceConnection

Categories

Resources