编辑
请滚动到该线程的底部,以进行更新。我已经解决了这个问题,但是仍然需要帮助来解决。
背景
在我的Android应用上,我使用以下代码启动文件对话框并加载以前保存的共享首选项集:
public void load (){
Intent intent = new Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select a file"), 123);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==123 && resultCode==RESULT_OK) {
Uri selectedfile = data.getData(); //The uri with the location of the file
File file = new File(selectedfile.getPath());
loadSharedPreferencesFromFile(file);
}
}
@SuppressWarnings({ "unchecked" })
private boolean loadSharedPreferencesFromFile(File src) {
SharedPreferences shared = getActivity().getSharedPreferences("mypref", getActivity().MODE_PRIVATE);
SharedPreferences.Editor editor = shared.edit();
//
boolean res = false;
ObjectInputStream input = null;
try {
input = new ObjectInputStream(new FileInputStream(src));
editor.clear();
Map<String, ?> entries = (Map<String, ?>) input.readObject();
for (Map.Entry<String, ?> entry : entries.entrySet()) {
Object v = entry.getValue();
String key = entry.getKey();
if (v instanceof Boolean)
editor.putBoolean(key, ((Boolean) v).booleanValue());
else if (v instanceof Float)
editor.putFloat(key, ((Float) v).floatValue());
else if (v instanceof Integer)
editor.putInt(key, ((Integer) v).intValue());
else if (v instanceof Long)
editor.putLong(key, ((Long) v).longValue());
else if (v instanceof String)
editor.putString(key, ((String) v));
}
editor.commit();
res = true;
Toast toast = Toast.makeText(getActivity().getApplicationContext(), "Load successful", Toast.LENGTH_LONG);
toast.show();
restartActivity();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
try {
if (input != null) {
input.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return res;
}
代码按旧版API的预期工作(我已经在Kitkat和Lollipop中尝试过):打开文件对话框,由用户选择文件,并且(如果是共享首选项文件)设置成功加载到应用中。
问题
上面的代码不适用于Oreo(API 26)!
文件对话框成功启动,但是一旦我选择了先前保存的共享首选项文件,该对话框就会消失,而首选项不会加载到应用程序中。显然,此过程中有问题(也许在loadSharedPreferencesFromFile
中?),但我不知道是什么。
我的问题
关于我使用的代码,我应该知道Oreo是否有所更改-例如共享首选项ObjectInputStream
或其他任何种类的东西?我查看了Oreo的官方文档,但没有发现任何相关信息。
两个注释:
1)我做通过在外部存储设备上编写的代码明确地要求用户许可,清单中也提到了该信息
2)如果有什么不同,我尝试加载的已保存的首选项文件 是由该应用程序的同一实例(即Oreo版本)成功创建的,则不是外部保存的文件。
编辑:
我试图绕过文件对话框加载文件-即只是将特定的文件对象(路径和文件名)传递到loadSharedPreferencesFromFile
-并且有效。这意味着问题出在文件对话框中。有什么想法吗?
编辑2
据我所知,问题似乎在于线条
Uri selectedfile = data.getData(); //The uri with the location of the file
File file = new File(selectedfile.getPath());
loadSharedPreferencesFromFile(file);
奥利奥(或实际上是棉花糖及以上)似乎不喜欢Uri
。我一直在搜索解决方案,包括此答案,以实现FileProvider
:
Intent.ACTION_SEND not working on Oreo
我一直无法理解如何更改代码。我知道我需要像这样实现if-statement
:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Uri selectedfile = data.getData(); //The uri with the location of the file
}
else {
// code for higher versions
}
但我不确定如何进行。
但是要更换
Uri uri = Uri.fromFile(fileImagePath);
使用
Uri uri = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".provider",fileImagePath);
我迷路了,因为在我自己的代码中我使用过Uri selectedfile = data.getData();
,那么如何使这一部分适应该解决方案?