in my company, we have two apps that access an authentication (from our own webservice) token from the android account manager. Because this is a SSO, we decided to extract the login (activity and AbstractAccountAuthenticator) into a library, that both apps are binding to.
In order to keep the account in the android system, if one of our apps gets uninstalled (assuming the user installed both of our apps), we gave the accountType a unified name ex. my.company.auth (both apps however have the package name my.company.a and my.company.b respectively).
The problem lies when both of our apps gets uninstalled: the entry in the account settings in android is still there.
Does anyone know why or what I am doing wrong?
Does it have to do with the accountType, that has a different 'package name' then the apps?
Thank you very much in advance
You need to separate your custom account type component and provide a separate apk file.
When user tries to use any of your app, you need to check if custom account type app exsits on the device or not.
If your account type app doesn't exist, direct user to playstore for downloading your custom account type app so that user can create account for your custom account type and continue to use your app.
In this way, since user created account is not tied to one app and custom account type is separate app, uninstalling any of your app won't delete account created for your custom account type.
Related
I'm working on an app for a customer that already have a couple of apps. Request is to find a way to have an ID/string that could be generated (using a GUID) and shared between that set of apps. A sort of "CustomerDeviceID".
i.e. When user installs the first app from that publisher an ID is generated and stored in some way. Then, when user installs the second or third app, that ID could be retrieved and used. Obviously that process should NOT be driven by the user (no pickers, no permissions, no intents).
Android provides ANDROID_ID to do that but it is generated using keystore, so apps should also be signed using the same keystore (customer apps aren't!).
On iOS we are using shared keychain, but I can't find a way to do that on Android... any ideas? Thanks in advance
I have an Android SDK and I want to use Account Manager to centralise my accounts. The SDK will create an account if the device is registered the first time, if not, it will reuse the same account from the Account Manager.
Issue: If I install 2 apps from my own PC. I can see that the first account is created and is reused by the second app. However, when I install 2 apps from different PC's. The second app is not able to detect the account created by the first app and throws an error
java.lang.SecurityException: uid 10413 cannot explicitly add accounts of type: com.example
In the second scenario, I can see other accounts on the device like Google, Skype, and Whatsapp which are ofcourse not installed from my PC and have a different signature as well then how come these package names and types are visible and not mine?
Resolved: I was using read contact permission but was missing write contact permission.
At a time only one app can register for adding account of a type.
The app that add accounts and the app that need account need to be of same signature. when you are trying from same PC, same debug signature is getting applied so you are able to access.
Or set visibility for packages of other apps that want to access the account while adding the accounts or after adding the account. see method - AccountManager.addAccountExplicitly or setAccountVisibility
I am developing an SDK which multiple applications will use. This SDK should login to the user's account and will provide the application with server interaction works. My problem is that I want to share this user's account between these applications. So there should be a mechanism in which applications will first look up the account if it exists, they will use it, if not, they will create it. But I am having technical challenges.
I looked up android's custom accounts so that the account credentials could be stored there. But I am not sure if it is possible there. First, is it possible to see if an account under a certain type exists? Second, is it possible for an application to use an account which another application created? For example, google games is doing exactly this functionality. Any game can login with user's google game account. But I need to do this without installing a third-party service on user's device.
Generally, if you have anything helpful to solve this situation, it is much appreciated.
If you looking for a solution on the device you can use a content provider to share data between the two apps.
After digging deep in the explained situation, I got my answer
First, yes it is possible to see if there exist an account under an specific name. This name can be different from the application's URI.
Second, it is possible to use an account which another application has been created.
So in the SDK, I can first lookup a contracted account name which there will be an stored token. If it exists, the SDK will store it in the shared preferences. If it does not exist, the SDK will create the token using the user's credentials. This way, other applications can use this account and if the application which created the account has been uninstalled, the next application which runs, will recreate the token in accounts from its shared preferences.
Following Udinic's blog shows us how to create our own authenticator and manage our own accounts.
The problem is that if two applications try to manage the same account type, only the account authenticator of the first application will be used (and only the first application can access certain methods of the AccountManager).
However, if the first application is uninstalled, then the second application's account authenticator takes its place and the second application has full access to the account.
How can I prevent that - given my application gets uninstalled - no other malicious (already installed) app can 'take over' the accounts created by my application and thus read out my user's passwords or other private data?
I checked apps like facebook or viber, they seem to automatically remove the account if the app is uninstalled. How can they do that?
(Please don't respond with 'you should not store the password' - That is not the question here)
Following are my problems:-
Is it possible to get the list of applications that a user has installed, against their google account through Google Play, programmatically through the use of any api?. Please note that I am not asking about the list of apps currently installed in the device, but ones that have at some point been installed.
I need a solution to the above as I am thinking of a scenario in my app, which is:
I want to give my app to the user for free during the first three months, after three months if user uninstalls the app and then installs it again I want to detect through any api (from Google Play) that the user has installed the app a second time (and should not get any free usage). Please note that I don't want to use any web service to store the account id & device id of the user at my side.
For option 2, you can create a file on the SD card. This will remain there when the user uninstalls/installs. But the user can always delete your special file. Unless you do something at your side, you are never sure if the user already used your app before.
To be completely sure, store it online:
You will need to have a very simple database which holds a list of device_id that installed your app.
Further more a webpage which fills this database.
In your app you download/open this webpage which the webpage will fill the DB.
App > WebClient (or other) which opens http://www.example.com/registerDevice.php?device_id=. The php site fills the db.
You app will need to check the database if the current device already has installed this app inorder to work/not work. You can do this via the same php and check the response. You could for example return 'ok' or 'not ok' or something else.
The simplest method is to get the account of the user the first time he/she runs the app, and send that detail over to you.
How this is can be done is well-documented over here: How to get the Android device's primary e-mail address
You will have to add another line of code to check back to the database at the first start of the app.
EDIT: For a non-web solution, simply add a timer to the start of your app:
schedule(TimerTask task, Date when)
the task should be adding a token AFTER the period of time you wish to give, to the phone's memory with the user's account details for authentication (see first solution on getting the account details)
Finally, as above, add a check-back to the phone's memory for that particular file to see if the user has used the app before.
The problem with any type of authentication that is based on the phone's memory is that people can easily remove the token, if they can find it, and reuse the app again.
Try this device specific implementation:
PackageManager packageManager = getContext().getPackageManager();
List<ApplicationInfo> applications = packageManager.getInstalledApplications(
PackageManger.GET_UNINSTALLED_PACKAGES);
// retrieves some information about all applications (even uninstalled ones)
// which have data directories
Of course this method won't work if user replaces the device. But you don't need to use any web service.
You can use this by keeping a database of hashed device id and users google id on a 3rd party server.
Also see http://android-developers.blogspot.de/2011/03/identifying-app-installations.html