Во-первых, я должен отметить, что это официально не поддерживается, хотя может быть поддерживаемый способ сделать это (то есть это НЕ будет этот метод), добавленный в Android в будущем (источник обоих утверждений: см. второй абзац эту ссылку).
Опять же, это не поддерживается и, возможно, нестабильно. В первую очередь я сделал это в качестве эксперимента, чтобы увидеть, возможно ли это; будьте предельно осторожны, если планируете использовать этот метод в приложении.
Тем не менее представляется возможным совместно использовать предпочтения между приложениями, если выполняется несколько требований. Во-первых, если вы хотите, чтобы приложение B могло получить доступ к настройкам приложения A, имя пакета приложения B должно быть дочерним по отношению к имени пакета приложения A (например, приложение A: com.example.pkg
приложение B: com.example.pkg.stuff
). Кроме того, они не могут захотеть получить доступ к файлу одновременно (я предполагаю, что применяются те же правила, что и для доступа к ним между действиями, если вы хотите обеспечить атомарный доступ, вам придется использовать дополнительные меры безопасности, такие как .wait( ) и .notify(), но я не буду вдаваться в подробности здесь).
Примечание. Все это работает на эмуляторе версий 2.2 и 2.3.3. Я не проводил тщательного тестирования на разных устройствах или версиях Android.
Что нужно сделать в приложении, которому будут принадлежать настройки (приложение A сверху):
1.) Объявите файл SharedPreferences
Это довольно просто. Просто объявите пару переменных для вашего файла общих настроек и редактора в вашем классе и создайте их экземпляры в вашем методе onCreate. Теперь вы можете поместить в настройки строку, которую вы будете использовать, чтобы убедиться, что другое приложение может правильно ее прочитать.
public class stuff extends Activity {
SharedPreferences mPrefs = null;
SharedPreferences.Editor mEd= null;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPrefs = (getApplicationContext()).getSharedPreferences("svcprefs", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
mEd = mPrefs.edit();
mEd.putString("test", "original send from prefs owner");
mEd.commit();
2.) Настройте файл резервной копии. Появляется метод getSharedPreferences для проверки наличия файла .bak для загрузки настроек. Вот почему в документации сказано, что он не будет работать в нескольких процессах; чтобы свести к минимуму ввод-вывод, он загружает префы ОДИН РАЗ, когда вы их захватываете, и создает их резервные копии только тогда, когда вы закрываете свое приложение/активность. Однако, если вы вызовете это из внешнего приложения, вы получите предупреждение об отсутствии правильных прав доступа к файлу для папки (которая является папкой данных первого приложения). Чтобы исправить это, мы собираемся сами создать файл .bak и сделать его общедоступным для чтения/записи. Я решил сделать это так, чтобы определить три переменные в моем общем классе.
final String[] copyToBackup = { "dd", "if=/data/data/com.example.pkg/shared_prefs/prefs.xml", "of=/data/data/com.example.pkg/shared_prefs/prefs.xml.bak", "bs=1024" };
final String[] mainFixPerm = {"chmod", "666", "/data/data/com.example.pkg/shared_prefs/prefs.xml"};
final String[] bakFixPerm = {"chmod", "666", "/data/data/com.example.pkg/shared_prefs/prefs.xml.bak"};
и создайте функцию в моем основном классе, которая будет принимать их в качестве аргументов и выполнять их
public void execCommand(String[] arg0){
try {
final Process pr = Runtime.getRuntime().exec(arg0);
final int retval = pr.waitFor();
if ( retval != 0 ) {
System.err.println("Error:" + retval);
}
}
catch (Exception e) {}
}
Это не очень красиво или хорошо, но это работает. Теперь в вашем методе onCreate (сразу после editor.commit()) вы будете вызывать эту функцию с каждой из трех строк.
execCommand(copyToBackup);
execCommand(mainFixPerm);
execCommand(bakFixPerm);
Это скопирует файл и сделает оба основных файла .xml и .xml.bak доступными для внешних программ. Вы также должны вызывать эти три метода в своем onDestroy(), чтобы убедиться, что база данных резервируется правильно, когда ваше приложение выходит, и дополнительно вызывать их непосредственно перед вызовом getSharedPreferences в другом месте вашего приложения (иначе он загрузит файл .bak, который вероятно, устарел, если другой процесс редактировал основной файл .xml). Это все, что вам нужно сделать в этом приложении. Вы можете вызвать getSharedPreferences в другом месте этого действия, и он соберет все данные из файла .xml, что позволит вам затем вызвать методы getdatatype("key") и получить их.
Действия при доступе к файлу(ам) (приложение B сверху)
1.) Запись в файл
Это еще проще. Я сделал кнопку для этого действия и настроил код в методе onClick, который сохранил бы что-то в файле общих настроек. Помните, что пакет приложения B должен быть дочерним по отношению к пакету приложения A. Мы будем создавать контекст на основе контекста приложения A, а затем вызывать getSharedPreferences в этом контексте.
prefsbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Context myContext = null;
try {
// App A's context
myContext = createPackageContext("com.example.pkg", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
} catch (NameNotFoundException e) {e.printStackTrace();}
testPrefs = myContext.getSharedPreferences("svcprefs", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
testEd = testPrefs.edit();
String valueFromPrefs = testPrefs.getString("test", "read failure");
TextView test1 = (TextView)findViewById(R.id.tvprefs);
test1.setText(valueFromPrefs);
testEd.putString("test2", "testback");
boolean edit_success = testEd.commit();
Это захватывает строку, которую я установил в другом приложении, и отображает ее (или сообщение об ошибке) в текстовом представлении в этом приложении. Кроме того, он устанавливает новую строку в файле настроек и фиксирует изменения. После этого, если ваше другое приложение вызовет getSharedPreferences, оно получит файл, включая изменения из этого приложения.
person
matt5784
schedule
14.06.2012