Скопировать XML-файл общих настроек из / data на устройство Samsung не удалось - PullRequest
9 голосов
/ 03 апреля 2011

В моем приложении есть функция экспорта. Это просто операция копирования, поскольку все мои настройки хранятся в общих настройках.

Я просто копирую xml-файл из /data/data/package.name/shared_prefs/settings.xml на SD-карту. Работает нормально по моему желанию HTC. Тем не менее, он может не работать на устройствах Samsung, и при попытке скопировать файл я получил следующую ошибку.

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

Кто-нибудь знает, как это исправить, или есть еще один простой способ сохранить общие настройки?

Спасибо.

Ответы [ 6 ]

9 голосов
/ 04 апреля 2011

Предложение CommonsWare было бы хитрым взломом, но, к сожалению, оно не сработает.

Samsung не всегда помещает каталог shared_prefs в тот же родительский каталог, что и getFilesDir().

Я бы порекомендовал проверить наличие (жестко закодировать его, за исключением имени пакета): /dbdata/databases/<package_name>/shared_prefs/package.name_preferences.xml и, если оно существует, использовать его, в противном случае воспользуйтесь предложением CommonsWare new File(getFilesDir(), "../shared_prefs") или просто /data/data/<package_name>/shared_prefs/package.name_preferences.xml.

Предупреждение, однако, что этот метод потенциально может иметь проблемы, если пользователь переключился с rom Samsung на пользовательский rom без стирания, поскольку файл /dbdata/databases может быть неиспользованным, но все еще существует.

Подробнее

На некоторых устройствах Samsung, таких как серия Galaxy S, работающих под управлением froyo, настройка такова:

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

Иногда там тоже есть shared_prefs, но это всего лишь попытка Samsungсбить вас с толку!Не верь этому!(Я думаю, что это может произойти как переход от обновления 2.1 до 2.2, но это может быть перенесено пользователями, переключающими ромы. Я действительно не знаю, я просто включил оба в интерфейс отчета об ошибках моего приложения и иногда вижуоба файла).

И:

/dbdata/databases/<package_name>/shared_prefs

Это настоящий каталог shared_prefs.

Однако на вкладке Galaxy на Froyo это странно.Как правило, у вас есть: /data/data/<package_name>/(lib|shared_prefs|files|databases)

Без каталога /dbdata/databases/<package_name>, но, похоже, системные приложения имеют: /dbdata/databases/<package_name>/yourdatabase.db

И дополнительный бонус в том, что /dbdata/databases/<package_name> не удаляется, когдаВаше приложение удалено.Удачи в использовании SharedPreferences, если пользователь переустанавливает ваше приложение!

9 голосов
/ 04 апреля 2011

Никогда, никогда, никогда, никогда, никогда, никогда, никогда не проводные пути.

К сожалению, нет нигде, о чем я могу думать. Лучшее решение, которое я могу придумать, будет:

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

Таким образом, если производитель устройства решит изменить имена разделов, вы застрахованы.

Попробуйте и посмотрите, поможет ли это.

1 голос
/ 22 ноября 2015

Лучший способ получить правильный путь на всех устройствах - запустить метод Context.getSharedPrefsFile, определенный как:

/**
 * {@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);

Из-за этого скрытого нужно использовать отражение и использовать откат при сбое:

private File getSharedPrefsFile(String name) {
    Context context = ...;
    File file = null;
    try {
        if (Build.VERSION.SDK_INT >= 24) {
            try {
                Method m = context.getClass().getMethod("getSharedPreferencesPath", new Class[] {String.class});
                file = (File)m.invoke(context, new Object[]{name});
            } catch (Throwable e) {
                Log.w("App TAG", "Failed call getSharedPreferencesPath", e);
            }
        }

        if (file == null) {
            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/" + name + ".xml");
    }
    return file;
}

На некоторых инструментах Самсунгов:

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;
    }
}

На других Android, как это:

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");
}

Через некоторое время Google изменит API для уровня 24 и выше: https://android.googlesource.com/platform/frameworks/base/+/6a6cdafaec56fcd793214678c7fcc52f0b860cfc%5E%21/core/java/android/app/ContextImpl.java

1 голос
/ 15 января 2015

Попробуйте использовать

context.getFilesDir().getParentFile().getAbsolutePath()
0 голосов
/ 01 марта 2014

Я тестировал в Samsung P1010 с:

//I'm in a IntentService class

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

Я получил: "/data/data/package.name/app_shared_prefs"

Это прекрасно работает для меня.Я могу запустить ffmpeg в этой папке.

Посмотрите:

Context.getDir

0 голосов
/ 03 апреля 2011

Вы должны создать каталог shared_prefs:

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());
}

Также ... пакет вашего приложения package.name? Убедитесь, что вы имеете в виду правильный пакет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...