我的应用程序将 GNSS 位置记录为使用手机生成定向运动地图的工具。主要活动完成所有工作,当映射器需要导出完成的现场工作时,应用程序调用一个子活动 (Save_File) 负责在 Documents/Oribooklet 目录上保存一个文件,使用 gpx 格式。由于 getExternalStoragePublicDirectory 过时,SAF 是选择要走的路。我不是 IT 人员,我这样做是为了好玩,这就是为什么我这么晚才处理这件事:用户给我发消息说他们无法再保存现场工作了。
主要: Oribooklet
public class Oribooklet extends AppCompatActivity {
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Mapper clicked on a menu option in the app bar overflow menu
Intent intent;
switch (item.getItemId()) {
// Respond to a click on the "Save" menu option
case R.id.action_saveFile:
// Call the Save_File Class
// Prepare to show Save UI
// Save to Shared Preference
SharedPreferences sharedPref = getSharedPreferences("user_preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("bShowSaveUI", true);
editor.apply();
intent = new Intent(Oribooklet.this, Save_File.class);
startActivity(intent);
return true;
// Respond to a click on the "Preference" menu option
case R.id.action_settings:
// Call the Class Activity_Preference for options menu
intent = new Intent(Oribooklet.this,Activity_Preference.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
在我实现的 Save_File 活动中,它运行良好:当映射器推送保存时,触发 startActivityForResult,然后启动 Android 文件选择器,映射器选择保存位置。
void createExternalStoragePublicDocument(String fileName) {
try {
// Call SAF
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(INTENT_TYPE);
intent.putExtra(Intent.EXTRA_TITLE, fileName);
// https://stackoverflow.com/questions/6147884/onactivityresult-is-not-being-called-in-fragment
startActivityForResult(intent, CREATE_REQUEST_CODE);
} catch (Exception excep) {
excep.printStackTrace();
}
}
然后 onActivityResult 获取返回的 Uri 以通过使用字段上收集的数据填充文件来完成作业。再好不过了!
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
Uri currentUri = null;
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CREATE_REQUEST_CODE) {
if (resultData != null) {
currentUri = resultData.getData();
// Write contents
writeFileContent(currentUri, fileData);
}
} else if (requestCode == OPEN_REQUEST_CODE) {
if (resultData != null) {
currentUri = resultData.getData();
sendByMail(stringEMailAddress, stringSubject, currentUri);
// Back to Oribooklet
finish();
}
}
}
}
该应用程序有一个 Preference 片段来设置一些参数。其中之一是要使用的标准。不能把两种标准混在一起做图。当映射器更改地图的类型时,Preference 会调用 Save_File 来完成这项工作,因此不会发生数据混合。它曾经工作得很好。
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
final String key) {
// Find the one that changed and address it
Preference connectionPref = findPreference(key);
switch (key){
case "list_iof":
// IOF´s element set
SharedPreferences preferences = getActivity().getSharedPreferences("user_preferences", MODE_PRIVATE);
// Update preference Summary
ListPreference listIOFPreference = (ListPreference) findPreference("list_iof");
CharSequence iof = listIOFPreference.getEntry();
connectionPref.setSummary(getResources().getString(R.string.pref_iof_summary_1) +
iof + "\" " +
getResources().getString(R.string.pref_iof_summary_2));
// Save the field job to avoid IOF set mixing
Intent intent = new Intent(getActivity(), Save_File.class);
startActivity(intent);
break;
在 SAF 之后,Save_File 的 onActivityResult 永远不会被触发,startActivityForResult 会触发文件提供程序,但是当映射器选择保存位置时,它会返回到 Preference 而不是 Save_File 的 onActivityResult,因此文件被创建为空。
我做了很多测试,用很多断点进行调试,在很多地方设置和删除 super,检查了所有关于此事的 SO 帖子,但没有成功。
任何想法?
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_oribooklet_v0"
android:name=".MyAppContext"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--android:requestLegacyExternalStore="true" -->
<!-- android:roundIcon="@mipmap/ic_oribooklet_v2"-->
<activity android:name="com.hbcavalcanti.oribooklet.Oribooklet"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- A child of the main activity -->
<activity
android:name=".Save_File"
android:label="@string/action_saveFile"
android:parentActivityName=".Oribooklet" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".Oribooklet" />
</activity>
<activity
android:name=".Activity_Preference"
android:label="@string/action_settings"
android:parentActivityName=".Oribooklet" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".Oribooklet" />
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.hbcavalcanti.oribooklet.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>