6

In my android application I coded to read shared data of another Android application and then to delete that data from shared preferences. My code as follows :

try {

     con = createPackageContext("com.testapp.ws", 0);
     SharedPreferences pref = con.getSharedPreferences("demopref", Context.MODE_PRIVATE);
     ipAdr = pref.getString("demostring", "No Value");
     pref.edit().remove("demopref").commit();
   }

This shows following error:

06-12 11:52:07.400: E/ApplicationContext(3587): Couldn't rename file /data/data/com.testapp.ws/shared_prefs/demopref.xml to backup file /data/data/com.testapp.ws/shared_prefs/demopref.xml.bak

I used this method in my other application to make shared data

 public void shareData(){
    String strShareValue = ip;
    SharedPreferences prefs = getSharedPreferences("demopref",Context.MODE_WORLD_READABLE);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString("demostring", strShareValue);
    editor.commit();
}

How can I do that ? Is there anything to add Manifest file ?

Thanks!

Grant
  • 4,413
  • 18
  • 56
  • 82

4 Answers4

4

If you use android:sharedUserId in your manifest files it should work. This is a permissions issue I've been running into myself.

To do this, you simply need to add a tag such as android:sharedUserId="com.example.you" to your <manifest> tag in your AndroidManifest.xml file for both of your applications (and the com.example.you has to be the same in both apps, of course).

Example start of the manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="package.name"
    android:versionCode="1"
    android:versionName="1.0"
    android:sharedUserId="com.example.you" >
...

For an indepth description of the way to get this working see my answer on How can I share a SharedPreferences file across two different android apps?

Community
  • 1
  • 1
matt5784
  • 3,065
  • 2
  • 24
  • 42
  • Can you please explain how can I use that here. I have no idea. I'm just a learner :) – Grant Jun 13 '12 at 18:27
  • edited the above :) Also check the link in the original paragraph to see the documentation. – matt5784 Jun 13 '12 at 18:34
  • Thanks for the explanation. I tested it but still have the same problem. Same error "Couldn't rename file"... Why is that ? Do you have any idea ? – Grant Jun 13 '12 at 18:51
  • 1
    I have had trouble with it myself. I _believe_ it is a problem where the shared preferences file is retrieved properly and the permissions are granted to the second app to use it and everything with that file works fine - _however_, when you try to do a `SharedPreferences.Editor.commit()` it automatically tries to save a backup file, which your second app is never given permission to write to. Therefore the commit fails. However I am not positive this is the problem, it is just a possible explanation. – matt5784 Jun 13 '12 at 18:54
  • Is there any way to delete that XML ? – Grant Jun 13 '12 at 18:59
  • Just $0.02: If your application is already deployed and this is an update, you can forget this method outright. Updating an application while changing it's uid breaks all existing file access in nasty ways. If this app is still prior to first release, though, this is still viable. – devunwired Jun 13 '12 at 19:10
  • Got it to work! See http://stackoverflow.com/questions/11025234/how-can-i-share-a-sharedpreferences-file-across-two-different-android-apps – matt5784 Jun 14 '12 at 00:27
1

You need to use MODE_WORLD_READABLE instead of MODE_PRIVATE. Read the docs for further information.

Here's a tutorial to check further if you have any more mistakes.

Kazekage Gaara
  • 14,972
  • 14
  • 61
  • 108
  • Even with `Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE` it likely won't work. I am having this problem myself. Additionally, the context matters when the shared prefs are created, not the context of the package used to retrieve them from the outside app. – matt5784 Jun 13 '12 at 18:17
  • Additionally, that tutorial will give you the same result - I've tried following it myself. It only works for reading the prefs, which he can already do. – matt5784 Jun 13 '12 at 18:21
  • Well mate, you seem to have a better experience at it. :-) My knowledge is based on what I've read, haven't had a chance to implement it all. – Kazekage Gaara Jun 13 '12 at 18:22
  • Yes matt5784 is correct. I also tried Context.MODE_WORLD_READABLE|MODE_WORLD_WRITEABLE...but the same error happened! – Grant Jun 13 '12 at 18:23
  • Someone on the android team made a comment on a google groups thread to the effect of "you shouldn't try to implement sharedprefs between apps, that functionality isn't intended to work - use a contentprovider instead." So it isn't officially supported & may be buggy even if you can get it to work. See my above answer for a way that _should_ work, however. – matt5784 Jun 13 '12 at 18:24
1

While the other solutions here will technically work in most circumstances, the framework that Android has provided to you for sharing data between processes/applications is the ContentProvider. It may seem like a lot of extra abstraction, but it's the one that is guaranteed to work.

While the interface for this component mirrors the calls into a database, the underlying data structure can be anything you like. In specific, you can return a MatrixCursor in response to queries that provides the contents of your SharedPreferences object, and you can implement a URI scheme for delete/update calls that can be used to modify the preferences from other applications.

Here is a link to a blog post from another developer who used MatrixCursor to share preferences.

HTH

Community
  • 1
  • 1
devunwired
  • 62,780
  • 12
  • 127
  • 139
1

I've been struggling with SharedPreferences the last three days, but I think I finally solved it for myself. Here's a few tips and gotchas you should try out that might help you (and loads of other stackoverflow users).

Please note that all my observations are for ICS (4.0.2 and 4.0.4).

  1. If you change the android:sharedUserId, delete the app as file/folder permissions will be incorrect. So you shouldn't change that value if you have already relased the app.
  2. If you change the Context.MODE_* values, delete the app's data (or the whole app) to ensure file permissions aren't incorrect.
  3. If you use android:sharedUserId, be sure to sign the apps with the same certificate.
  4. Use a different filename for the preferences in the two apps. I had problems with the app just reading the local shared preferences even though I used createPackageContex().

This is what worked for me in the end:

  1. I used the same android:sharedUserId for the two apps. (Not the same android:process.)
  2. I used Context.MODE_WORLD_READABLE for both reading and writing local prefs, and for reading the other app's prefs.
  3. I used Context.CONTEXT_IGNORE_SECURITY when calling createPackageContext().
Roy Solberg
  • 18,133
  • 12
  • 49
  • 76