我正在编写一个可以通过接收带有 ACTION_VIEW 或 ACTION_EDIT 的意图从另一个应用程序启动的应用程序。例如,可以通过查看电子邮件附件来打开它。麻烦的是,当您单击主页按钮并再次单击您正在使用的电子邮件应用程序的启动图标时,我的活动被终止,并且已进行的任何用户编辑都将丢失。我想要发生的是,当用户单击主页按钮时,我的活动被重新设置为父项,以便当用户单击我的应用程序的启动图标时它会恢复。我尝试在 manifest.xml 中设置 android:allowTaskReparenting="true" 但这不起作用。有时它根本没有任何效果,有时活动被移动到我的启动图标,但当您再次单击电子邮件应用程序图标时仍然会被杀死。allowTaskReparenting 的文档真的很模糊。它说该属性意味着:
“Activity 是否可以从启动它的任务转移到与其有关联的任务。”</p>
这个词在这里是什么意思?我想要的是保证活动确实移动(并保持在那里)。有什么办法可以做到这一点?
提前感谢任何可以提供帮助的人。
编辑
为了回应下面的评论,我整理了一个婴儿版本来展示我遇到的问题。当您通过单击另一个应用程序中的文件(例如,电子邮件的附件)启动 EditFileActivity 时,您可以编辑该文件。但是单击主页图标,然后再次单击电子邮件应用程序图标会导致您对文件所做的更改丢失。我希望 android 系统仅在用户明确单击返回然后说“是”或“否”时才忘记 EditFileActivity 的实例。理想情况下,我希望 EditFileActivity 的所有实例都堆积在我的应用程序的启动图标上。我可以通过使用 singleTask 或 singleInstance 并编写某种活动来显示选项卡中所有打开的文件来实现类似的东西,但如果我能让 android 系统本身帮助我,那就容易多了。
这是一个演示问题的完整项目。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.Example"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="11"/>
<application
android:label="Example"
android:icon="@drawable/ic_launcher">
<activity
android:name=".LaunchActivity"
android:label="LaunchActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".EditFileActivity"
android:label="EditFileActivity"
android:screenOrientation="portrait">
<!-- This is just an example. I wouldn't use this intent filter in a real app! -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.intent.action.EDIT"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="file"/>
<data android:scheme="content"/>
<data android:mimeType="*/*"/>
<data android:host="*"/>
</intent-filter>
</activity>
</application>
</manifest>`
启动活动:
public class LaunchActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setText("This is the activity you see when you click on the application's launch icon. It does absolutely nothing.");
textView.setTextSize(18);
setContentView(textView);
}
}
编辑文件活动:
public class EditFileActivity extends Activity {
// This String represents the contents of the file.
// In a "real" app the String would be initialised by reading the data from the Intent that started the activity.
// However, for the purposes of this example, the initial value is "Default".
private String fileContents = "Default";
private boolean editsMade = false;
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setText(fileContents);
textView.setTextSize(18);
textView.setPadding(10, 10, 10, 10);
setContentView(textView);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
makeEdits();
}
});
}
@Override
public void onBackPressed() {
if (editsMade) {
savePrompt();
} else {
finish();
}
}
private void savePrompt() {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == Dialog.BUTTON_POSITIVE) {
// Here is where I would save the edited file.
Toast.makeText(EditFileActivity.this, "File saved", Toast.LENGTH_LONG).show();
}
finish();
}
};
new AlertDialog.Builder(this)
.setTitle("Close File")
.setMessage("Do you want to save the changes you made?")
.setPositiveButton("Yes", listener)
.setNegativeButton("No", listener)
.show();
}
private void makeEdits() {
final EditText editText = new EditText(this);
editText.setText(fileContents);
new AlertDialog.Builder(this)
.setTitle("Edit File")
.setView(editText)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
Editable editable = editText.getText();
assert editable != null;
String newContents = editable.toString();
if (!fileContents.equals(newContents)) {
editsMade = true;
fileContents = newContents;
textView.setText(fileContents);
}
}
})
.setNegativeButton("Cancel", null)
.show();
}
}
2014 年 10 月 12 日更新
遇到的问题是由于使用了 Intent 标志 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET。幸运的是,从 API 级别 21 开始,Google 已弃用此标志。