I have multiple apps that have some sort of in-app currency (i.e gold).
The gold (Integer value) should be accessable through all of my apps. All of my own apps should be able to read/write the value.
It is important that only my apps are able to write the value, it doesn't matter if anyone else can read it.
It's also important that I do not know which of my apps is installed. There is no 'main'-app at all. It should be irrelevant which of my apps is installed and in which order.
The value does not have to be shared between the apps during runtime, I rather thought of something like sharedPreferences or an SQL database.
Where/How should I store this value?
Which is the preferred solution to this problem (if there is any)?
If you need to share data between two (or more) apps, you can set to them the same android:sharedUserId (in AndroidManifest.xml) so the other app can read/write in the private data of the other app.
android:sharedUserId
The name of a Linux user ID that will be shared
with other applications. By default, Android assigns each application
its own unique user ID. However, if this attribute is set to the same
value for two or more applications, they will all share the same ID —
provided that they are also signed by the same certificate.
Application with the same user ID can access each other's data and, if
desired, run in the same process.
Doc here.
Related
I´m currently trying to share information between different applications in Android, the goal I´d like to achieve is having the same behavior the KeyChain data share have in iOS but in Android.
I´ve already given a try using SharedPreferences and using "shareUserId" attribute inside Manifest, (by default Android applications behave as sandBoxes and they are not allowed to share data, they also haven´t a common context, so a "fake" one must be built) issues here come by the fact that is mandatory to know every app´s packageName so the data share happens between those apps with the same shareUserID value. I mean, I would like to access this resources without having to ask for the application that stored them.
Context appOne = createPackageContext("com.xxx.zzz.appOne", CONTEXT_INCLUDE_CODE);
mSharedPref = appOne.getSharedPreferences("Test", Context.MODE_PRIVATE);
Other way I tried was using the AccountManager in order to store that information so other applications could reach it. Bad news were that this account will be shared among all applications installed in the system and i will like this behavior to be more restrictive in terms that I would like to be able to choose which apps will have access to this information and those who won´t.
Reference to related post
(Should you use AccountManager for storing Usernames and Passwords for an Android app?)
Is there anyway to achieve this goal? Any help or hint will be appreciated, been stuck in here for a couple of days... If extra information is needed feel free to ask for it. Thanks in advance.
I am planning on storing a unique identifier after a user logs in for the first time on an Android and Apple app. This will make sure that the user can only access data from one device if they try to login through another device as I will flag then as having access. I will save this unique identifier in the devices preferences and use it for requests to get this private data.
With that being said I know the preferences can be deleted or removed. This piece of data isnt needed long term and in emergencies we can reset the users account back as if they never got access yet like for a factory reset or deleted app.
My question is, are there any issues with this? These arent developers so somehow getting access to the user preferences to find that unique identifier and using it elsewhere shouldnt be an issue.
for IOS:
You shouldn't concern your self with that cause there is no need to store the identifiers to user prefs (and it is not a good practice).
You just use:
[[[UIDevice currentDevice] identifierForVendor] UUIDString];
It will return the same value as long as it is called from the same device and same vendor. This is explained in:
http://www.doubleencore.com/2013/04/unique-identifiers/
I have inherited an app which comes as a free version, and Pro monthly subscription is bought via in-app items. The Pro status (a simple string "pro_status") is saved inside the AccountManager (package android.accounts).
//AccountManager initiated
AccountManager mAccountManager = AccountManager.get(this);
//fetch accounts which correspond to our package name
Account[] accounts = mAccountManager.getAccountsByType(getString(R.string.account_type));
//save Pro status inside the AccountManager
mAccountManager.setUserData(mAccount, "is_pro", "" + info.isPro());
The app suffers from a strange bug that it forgets the Pro state randomly, either when you close the app or during the work.
Is this a good way to store Pro status? Could AccountManager be the reason why the app loses the idea of a Pro status?
I usually use either a database or SharedPreferences to store such data (besides storing it on the remote API), so I need a help from someone who used his app in the same way.
Usually the people playing with the setting "pro" status will be the one with rooted devices. Anyways the data stored in the account manager is visible to such users.
So, for such a use case, even account manager is not safe. Though other apps (with different UID) cannot access this data.
Also keep in mind that the user can delete the account from the settings which might be the reason for your settings going away.
My advice would be save this info in shared pref in encrypted form??
In all phones,there is a specific User Database which stores information regarding your accounts.
Is this a good way to store Pro status?
I cannot answer that however I can give you answer to related questions
Is it modifiable?
There are 2 ways of accessing this data, viz
The user explicitly gives permission to an application to read
account details for that particular account. This list of apps
which can access the details for this account are stored based on
PIDs,which cannot be same for different apps. check setUserData
and AUTHENTICATE_ACCOUNTS permission
This database can be accessed(and modified ) on a rooted device.
Can a user manually delete this data?
-Yes,He can delete the account from the device itself.It is his device and he can modify any account details on it too.
In my experiece,the Acccount Manager API is very temperamental, and prone to change which can break your code if it is not used in the way that it was intended to be i.e. store User Account details in centralised database.
You should look into the approach and comments(but not the answer) of this question
.
I agree with the shared preferences approach too.
I'm writing an App for Android which gets a list of all installed Apps and their details. I get most of what I need with:
context.getPackageManager().getInstalledPackages(0);
What I can't seem to figure out is where I can get the name or id of the vendor who created the package/App.
Any suggestions?
I don't think there is any way to programmatically access that information. In fact I don't think the name of the vendor is stored within the apk file anywhere. The name that shows up as "Developer" in the Market is the name associated with the google account that uploaded the application. I think this value is stored by the Market infrastructure, rather than the application itself. Unfortunately there are currently no public APIs that grant access to the Market data.
If you are not necessarily concerned with the actual human readable name and you just aim to be able to programmatically tell whether the device has multiple applications from the same developer you might be able to glean this from the signature field inside the PackageInfo object that you can get from pm.getPackageInfo(String packageName, int flags); I have very little experience with this though, I could be incorrect.
I would like to make a slight change to my application's name. I read that it can work if both applications are signed with the same signature and is given the same userId then they can share information and I can migrate the original application's information to the new one. It is very important that the user gets the notification to upgrade. Will the user receive the update to upgrade if its done this way?
Your users will still get the upgrade, as long as you don't change the top level java package name.
Do you mean the actual name (human readable) or the application package? You can change the name, description, etc. at any time (though it might be confusing for existing users). On the other hand, you cannot change the package name, you need to publish a new app. Unless the current app already has the sharedUserId, set you cannot really use that option: setting it will change the UID and the application won't be able to see its own files. Two solutions to this:
export the data in some shared format (XML, CSV, JSON, etc.)
write a content provider and use a signature permission to make sure only your apps can read from it.