Android: Cannot access other app's SharedPreference - android

I've been searching for days to solve this, but with no success.
I want to get the shared preference settings from my old app and put it on to my new app.
but I've encounter some security issue (suspect).
my code:
Context c = createPackageContext("my.app.pkg", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sp = c.getSharedPreferences("my.app.pkg", Context.CONTEXT_IGNORE_SECURITY);
Running the code above giving me this:
Attempt to read preferences file /data/data/my.app.pkg/shared_prefs/my.app.pkg_preferences.xml without permission
even thought the object sp is not null, but it does not retrieve anything from my old app.
I tried googling around and seems like most people can run the code above with no errors.
Is there anything I've missed out?

We've done exactly this for our Android book Android in Practice. The key is to use the same process and user ID for both apps. The sample code and sample apps are on Google Code (SharedProcessApp1 and SharedProcessApp2). You can go from there.

You can indeed share preferences across applications. That's why it's called SharedPreferences.
What you need to do is make sure both application are signed with the same certificate and they both share the same SharedUserId in the AndroidManifest.xml file: read here.
This is because the SharedPreferences you get from
PreferenceManager.getDefaultSharedPreferences(context)
has always MODE_PRIVATE.
However in an application you can also get a SharedPreferences object within a Context with the following:
SharedPreferences prefs = getSharedPreferences("my_public_shared_prefs", MODE_WORLD_READABLE);
which you can freely retreive from another app with the following:
Context context = createPackageContext("my_target_app_package", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences prefs = context.getSharedPreferences("my_public_shared_prefs", MODE_WORLD_READABLE);
Make sure you don't store any private information there because it's WORLD readable, which means you and anyone else can read that data.
To finish, if you want to retrieve the SharedPreferences of your old app you will need to update the old application with a SharedUserId in the Manifest file.

Android APplications runs in their own sandbox, so one application can not access data of other activity. BUt If an application want to share some of its data, this can be achieved by ContentProvider.
See Content Provider: http://developer.android.com/guide/topics/providers/content-providers.html

Related

Access data from other application saved in preference

If an application has saved data using SharedPreference like this:
SharedPreferences.Editor preferencesEditor = getDefaultSharedPreferences.edit();
preferencesEditor.putInt("count", mValue);
preferencesEditor.apply();
can an other application have access to these data after reboot like this for example:
SharedPreferences sharedPref = getDefaultSharedPreferences();
int value = sharedPref.getInt("count",0);
And if it is not posssible, how is possible from an application to store variable so that other application have access to it?
Yes it is possible, but both apps need to be signed by the same certificates among other things, check this answer for details.
An application can also share and access data from a public content provider and this is usually the recommended way of sharing data among different applications.
You can also have a shared file in storage that both apps can read and write.

Does SharedPreferences name need to be unique?

Probably a dumb question, but I"m using a SharedPreference with a few different names "MyPrefs1", "MyPrefs2" etc.
I'm assuming this is restricted to my app. i.e. if some other app tries to use the same name, it won't overwrite my values
I pretty much believe my understanding is correct, but the name "SharedPreferences" seem to indicate that it can be shared between apps? (is it for Sharing between activities?)
That's correct, the SharedPreferences are stored in your app's private folder (to be exact, in /data/data/your package name/shared_prefs).
You can give them whatever name you want.
SharedPreferences represent the preferences which can be shared between different components of your application. The SharedPreferences you create in your application is never exposed with other applications.
Whether you use PreferenceManager.getDefaultSharedPreferences() or Context.getSharedPreferences("file_name", Context.MODE_PRIVATE); both are particular to your application only.
Note - SharedPreferences or Preferences is not exposed to other applications.
Although you assumption is right that the SharedPreferences are not shared between apps and thus names cannot clash, it's a good practice (besides of put a specific name to your shared preferences file) to add the package of your application as a prefix. This is useful if you have different flavours and you don't want to overwrite your preferences among them, especially when you're testing an app and don't want to screw up the original values of the shared preferences files.

ContentProvider to expose app preferences

I want to write a content provider for an app that exposes some data sored in the app's shared preferences. Is it possible to do that?
Why do you want to to do that ? Normally Preferences are secret data which should be only available to source app.
Incase you want to do that, you can read other's app preferences by obtaining the context of source application
Context otherAppsContext = createPackageContext("other.application.package", mode);
Also you should understand that you can’t get all preferences. When you will receive results you will see that PRIVATE and WORLD_WRITABLE aren’t available.

Android: one time only variable storing

I have an appliaction which will show a welcome window only the first time the user starts the app. What would be the best way to store this boolean variable (i.e. "isFirstTime") to phone storage? Should I use Shared Preferences or Internal Storage?
The docs say that if I use Internal Storage my "preference" file will automatically get removed upon uninstallation which is quite handy.
I want a clean, simple and fast solution.
Yes, I'd recommend using Shared Preferences. Basically you could put a shared preference with a key of "isFirstTime" and a type of boolean set to false. Then in your main activity do something like:
getBoolean (isFirstTime, true);
This, if it can't find isFirstTime will give you true, allowing you to do an if-statement based on the result.
I agree that SharedPreferences would probably be the most "clean, simple, and fast solution" that you are looking for. SharedPreferences are also deleted when the application is uninstalled.
Are the shared preferences associated with the App deleted when the app is removed?
SharedPreferences are your best option for this.

SharedPreferences : Why are they called so?

As per my understanding the values stored using the SharedPreferences in android can be used only by the app which created it.(correct me if wrong).
Then what is the significance of the name SharedPreferences.
Is something really shared here?
well it can be shared accross applications if you set the mode to WORLD READABLE or WORLD_WRITEABLE. (think ringtone settings, notification message etc...)
see this link
public static final int MODE_WORLD_READABLE
Since: API Level 1
File creation mode: allow all other applications to have read access to
the created file.
The SharedPreferences use a secure /data directory for preferences that are shared within your app's activities and services.
http://developer.android.com/reference/android/content/SharedPreferences.html

Categories

Resources