首先,我应该注意,这不是官方支持的,尽管将来可能会在 Android 中添加一种受支持的方法(即不会是这种方法)(这两种说法的来源:请参阅此链接的第二段) .
同样,这是不受支持的,而且很可能不稳定。我主要是作为一个实验来做的,看看它是否可能。如果您打算将此方法实际合并到应用程序中,请格外小心。
但是,如果满足一些要求,似乎可以在应用程序之间共享首选项。首先,如果您希望 App B 能够访问 App A 的首选项,则 App B 的包名必须是 App A 的包名的子项(例如 App A: com.example.pkg
App B: com.example.pkg.stuff
)。此外,他们不能同时访问文件(我假设在活动之间访问它们的规则相同,如果您想确保原子访问,则必须使用额外的保护措施,例如 .wait( ) 和 .notify(),但我不会在这里讨论)。
注意:所有这些都适用于 2.2 和 2.3.3 的模拟器——我没有在设备或安卓版本上进行广泛的测试。
在将拥有偏好的应用程序中要做的事情(上面的应用程序 A):
1.) 声明 SharedPreferences 文件
这相当简单。只需为您的 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 文件以从中加载首选项。这就是为什么它在文档中说它不能跨多个进程工作;为了最大限度地减少 I/O,它会在您抓取首选项时加载它们一次,并且仅在您关闭应用程序/活动时备份它们。但是,如果您从外部应用程序调用它,您将收到有关该文件夹(这是第一个应用程序的数据文件夹)没有正确文件权限的警告。为了解决这个问题,我们将自己创建 .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") 方法并检索它。
在访问文件中要做的事情(上面的 App B)
1.) 写入文件
这更简单。我在这个活动上做了一个按钮,并在它的 onClick 方法中设置了代码,这会将一些东西保存到共享首选项文件中。请记住,应用 B 的包必须是应用 A 的包的子级。我们将基于 App 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,它将检索包含此应用程序更改的文件。