我将一些值存储在共享的首选项文件中,并且在代码的某个点上,我拆分了此文件并将共享上传到几个云中,以便可以进行安全备份。
因此,现在我的应用程序在启动时会查看共享的首选项文件夹,如果该文件不存在,它会要求用户登录云以恢复该文件(考虑用户丢失手机的情况)。
因此,尝试性能时,我模拟我没有这样的文件并下载零件并将它们组合起来以得到整体。该文件已完美恢复(我手动将其打开,并且具有所有字段)。
但是,当我尝试在此文件中写入新值时,系统无法识别它,请删除它并创建一个新值。总而言之,该文件将被覆盖。即使我尝试从旧文件(我下载的文件)中读取一个值,它也不起作用并返回默认值。
您是否知道可能是问题所在,并且除了不使用“共享首选项”之外,是否还有其他解决方案?
KeyManagement.combineFile(split);
SharedPreferences prefs = mContext.getSharedPreferences("CACSPrefs", 0);
String key = prefs.getString("KEY", null);
Editor editor = prefs.edit();
editor.putString("IS_STORED", "TRUE");
editor.commit();
split是文件数组(我从Internet下载的部分)。我检查了重新组合的文件名为“ CACSPrefs.xml”
编辑
当我分割原始文件时,我一步一步地向每个共享发送一个字节,每个共享都以相同的名称调用,但是添加了“ _1”,“ _ 2”,...,因此合并文件的行为是另一种方式回合。
protected static void combineFile(File[] fileShares) throws FileNotFoundException, IOException{
// create file
String parentPath = fileShares[0].getParent();
String fileName = fileShares[0].getName().substring(0,
fileShares[0].getName().indexOf("_"));
File file = new File(parentPath + "/" + fileName);
if (!file.exists()) file.createNewFile();
FileInputStream[] in = new FileInputStream[fileShares.length];
// create input streams
int length = 0;
for (int i = 0; i < fileShares.length; i++){
length += (int) fileShares[i].length();
in[i] = new FileInputStream(fileShares[i].getAbsolutePath());
}
// read byte by byte and write
FileOutputStream out = new FileOutputStream(file);
for (int i = 0; i < length; i++){
int b;
if((b = in[i % fileShares.length].read()) == -1) break;
out.write((byte) b);
}
out.flush();
out.close();
for (int i = 0; i < fileShares.length; i++){
in[i].close();
}
}
最佳答案
我建议另一种解决方案。编写一种方法,使用标准SharedPreferences.get*()
方法仅将要上传到云的值转换为JSON并上传JSON。然后,当需要它返回时,您将获取JSON,读取值并使用标准的SharedPreferences.Editor.put*(...)
方法再次将其存储。
您可以避免原始代码可能引入的任何错误,这些错误导致SharedPreferences
无法识别文件(或不使用它加载值),因为您使用的是访问共享首选项的官方方法。
编辑:或者不使用JSON,您可以使用任何喜欢的传输协议,甚至您自己的,只要您按照上述方式编写首选项即可。
编辑2:应OP的要求,这里有一个示例,说明如何获取选定的共享首选项作为JSON,反之亦然。
要将某些共享首选项添加到JSON对象中,请执行以下操作:
SharedPreferences prefs = getApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
JSONObject json = new JSONObject();
try {
json.put("my_long", prefs.getLong("my_long", 0));
json.put("my_string", prefs.getString("my_string", null));
// only upload this one if it's set
if (prefs.contains("my_boolean")) json.put("my_boolean", prefs.getBoolean("my_boolean", false));
} catch (JSONException e) {
e.printStackTrace();
}
String toUpload = json.toString();
现在上传
String toUpload
例如作为POST请求正文。要保存从服务器获得的共享首选项,请执行以下操作:
String fromDownload =...; // obtained from http response body
try {
SharedPreferences prefs = getApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
JSONObject json = new JSONObject(fromDownload);
SharedPreferences.Editor editor = prefs.edit();
// this will throw JSONException if no value came from server
editor.putLong("my_long", json.getInt("my_long"));
// this will set a default value if no value came from server
editor.putString("my_string", json.optString("my_string", "default"));
// this will only store the value if it came from server otherwise no-op
if (json.has("my_boolean")) editor.putBoolean("my_boolean", json.getBoolean("my_boolean"));
editor.apply();
} catch (JSONException e) {
e.printStackTrace();
}