Copying shared XML settings file from / data to Samsung device failed

My application has an export function. This is just a copy operation, since all my settings are stored in general preferences.

I just copy the xml file from /data/data/package.name/shared_prefs/settings.xml to the SD card. It works great on my HTC Desire. However, it may not work on Samsung devices, and I get the following error while I try to copy the file.

  I / System.out (3166): /data/data/package.name/shared_prefs/settings.xml (No such file or directory) 
 in the directory.

Does anyone know how to fix it, or is there another easy way to maintain shared preferences?

Thanks.

+7
source share
6 answers

CommonsWare's suggestion would be a smart hack, but unfortunately this will not work.

Samsung does not always put the shared_prefs directory in the same parent directory as getFilesDir() .

I would recommend checking for availability (hardcode it, except for the package name): /dbdata/databases/<package_name>/shared_prefs/package.name_preferences.xml , and if it exists, use it, otherwise refer to the CommonsWare new File(getFilesDir(), "../shared_prefs") or simply /data/data/<package_name>/shared_prefs/package.name_preferences.xml .

Warning, although this method may have problems if the user switched from a Samsung drive to a custom rum without cleaning, since the /dbdata/databases file may not be used, but still exists.

More details

On some Samsung devices, such as the Galaxy S series running on froyo, the setting is as follows:

/data/data/<package_name>/(lib|files|databases)

Sometimes there are shared_prefs, but Samsung is just trying to embarrass you! Do not believe it! (I think this can happen if you switch from version 2.1 to 2.2, but it can be a disconnection from users switching roms. I really don’t know, I just included an application error report in my interface, and sometimes I see both files )

and

/dbdata/databases/<package_name>/shared_prefs

This is the real shared_prefs directory.

However, on the Galaxy Tab on Froyo, this is weird. Usually you have: /data/data/<package_name>/(lib|shared_prefs|files|databases)

Without the /dbdata/databases/<package_name> , but it seems that system applications have: /dbdata/databases/<package_name>/yourdatabase.db

And the added bonus is that /dbdata/databases/<package_name> not deleted when your application is deleted. Good luck using SharedPreferences if a user ever reinstalls your application!

+8
source

Never, never, never, never, never, never, ever pave the way.

Unfortunately, there is no getSharedPreferenceDir() anywhere that I can think of. The best solution I can think of would be:

 new File(getFilesDir(), "../shared_prefs") 

Thus, if the device manufacturer chooses to change the partition names, you are closed.

Try it and see if it helps.

+7
source

The best way to get a valid path on all devices is to run the Context.getSharedPrefsFile method, defined as:

 /** * {@hide} * Return the full path to the shared prefs file for the given prefs group name. * * <p>Note: this is not generally useful for applications, since they should * not be directly accessing the file system. */ public abstract File getSharedPrefsFile(String name); 

Because of this, the latent needs to use reflection and use the reserve in case of failure:

 private File getSharedPrefsFile(String name) { Context context = ...; File file = null; try { Method m = context.getClass().getMethod("getSharedPrefsFile", new Class[] {String.class}); file = (File)m.invoke(context, new Object[]{name}); } catch (Throwable e) { Log.w("App TAG", "Failed call getSharedPrefsFile", e); file = new File(context.getFilesDir(), "../shared_prefs"); } return file; } 

Some Samsung have the following:

 public File getSharedPrefsFile(String paramString) { return makeFilename(getPreferencesDir(), paramString + ".xml"); } private File getPreferencesDir() { synchronized (this.mSync) { if (this.mPreferencesDir == null) { this.mPreferencesDir = new File("/dbdata/databases/" + getPackageName() + "/", "shared_prefs"); } File localFile = this.mPreferencesDir; return localFile; } } 

On other Android like this:

 public File getSharedPrefsFile(String name) { return makeFilename(getPreferencesDir(), name + ".xml"); } private File getPreferencesDir() { synchronized (mSync) { if (mPreferencesDir == null) { mPreferencesDir = new File(getDataDirFile(), "shared_prefs"); } return mPreferencesDir; } } private File getDataDirFile() { if (mPackageInfo != null) { return mPackageInfo.getDataDirFile(); } throw new RuntimeException("Not supported in system context"); } 
+1
source

I tested on Samsung P1010 with:

//I'm in a IntentService class

File file = this.getDir("shared_prefs", MODE_PRIVATE);

I got: "/data/data/package.name/app_shared_prefs"

This works great for me. I can run ffmpeg in this folder.

Appearance:

Context.getDir

0
source

Try using

 context.getFilesDir().getParentFile().getAbsolutePath() 
0
source

You need to create the shared_prefs directory:

 try{ String dir="/data/data/package.name/shared_prefs"; // Create one directory boolean success = (new File(dir)).mkdirs(); if (success) { // now copy the file } }catch (Exception e){//Catch exception if any System.err.println("Error: " + e.getMessage()); } 

Also ... package of your application package.name ? Make sure you mean the right package.

-one
source

All Articles