我可以启动Activity,但也需要能够获取结果。我该怎么做?
我尝试在PreferencesActivity中重写onActivityResult,但没有成功。
我是否在preferences.xml中漏掉了一些额外的属性?
我所知道的最干净的解决方案是监听preferences上的点击事件并显式地启动intent。这样,onActivityResult
将像往常一样被调用。
假设您的intent-preference在XML中定义,您可以像这样附加一个监听器(其中1234
是onActivityResult
的请求代码):
Preference pref = (Preference) findPreference("prefKey");
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivityForResult(preference.getIntent(), 1234);
return true;
}
});
startActivity()
方法,并在检查意图是我们感兴趣的之后,改为调用 startActivityForResult()
,类似于以下示例(使用 1234 作为请求代码):public class PreferencesActivity {
// ...
@Override
public void startActivity(Intent intent) {
if (thisIsTheExpected(intent)) {
super.startActivityForResult(intent, 1234);
} else {
super.startActivity(intent);
}
}
@Override
protected void onActivityResult(int reqCode, int resCode, Intent data) {
if (reqCode == 1234) {
// should be getting called now
}
}
// ...
}
根据您的需求,这可能比在代码中添加多个OnPreferenceClickListener
更简单 :)
startActivity(Intent)
总是在单击首选项项时调用。此外,thisIsTheExpected(intent)
似乎不太直观,因此更容易出错,而与首选项键匹配则更为简单明了。因此,目前我将采用自己的解决方案。 - KaarelstartActivityForResult(new Intent(main.this, preferences.class), 0);
Intent i;
i.putStringExtra("name", "tom");
setResult(RESULT_OK, i);
finish();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (resultCode == RESULT_OK){
Log.d("test", data.getExtraString("name");
}
}
}
String foo = "hello";
Intent i = new Intent();
i.putExtra("testString", foo);//You can also add other types of variables here, see [1] for reference
i.setClass(main.this, preferences.class);
startActivity(i);
Bundle b = this.getIntent().getExtras();//[2]
if (b!=null){
String recievedString = b.getString("testString");
//The recievedString variable contains the String "hello" now, see [3]
}
[1] https://developer.android.com/reference/android/content/Intent.html意图是一个抽象的描述,用于请求操作或传递消息到另一个组件(如活动、服务、广播接收器等)。
[2] https://developer.android.com/reference/android/content/Intent.html#getExtras%28%29getExtras()方法返回与此意图关联的额外数据包。
[3] https://developer.android.com/reference/android/os/Bundle.htmlBundle类是一种存储映射,其中所有键和值都是字符串类型。它们通常用于在不同组件之间传递数据。
onActivityResult
应该在PreferencesActivity
中。 - Kaarel如果您查看平台源代码中的PreferenceActivity.java此处的第1000行,您可以看到您的意图通过startActivity startActivity(header.intent);
而不是通过startActivityForResult调用,因此我认为这是不可能的。
但是,您可以尝试覆盖PreferenceActivity的 onHeaderClick
函数以及 onActivityResult
,然后查看会发生什么。我自己没有尝试过,所以我不知道,并且很有可能这种方法在未来的版本中会失效。
但是也许还有另一种适合您的方法。从您的参考问题中,我可以看出您正在通过意图启动一个活动。如果此活动用于设置编辑,则这不是正确的方法,因为Android仅使用此意图来启动活动而已。我认为最好通过扩展任何可用的类来创建特定的首选项活动以进行自定义。这是我自定义的ListPreference,我用它来让用户选择应用程序:
public class CustomSelectAppPreference extends ListPreference {
//----- Constructor -----
public CustomSelectAppPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
//----- Constructor END -----
//----- Public Code -----
public void SetResult(String packageName) {
if(this.callChangeListener(packageName)) {
Editor edit = this.getSharedPreferences().edit();
edit.putString(this.getKey(), packageName);
edit.commit();
}
this.getDialog().dismiss();
}
//----- Public Code END -----
//----- ListPreference Overrides -----
@Override
protected void onPrepareDialogBuilder(Builder builder) {
Log.d("CustomSelectAppPreference", "onPrepareDialogBuilder");
super.onPrepareDialogBuilder(builder);
String selectedPackage = this.getSharedPreferences().getString(this.getKey(), "");
ListAdapter listAdapter = (ListAdapter) new ApplicationsArrayAdapter(this.getContext(), Utilities.getInstalledApplications(this.getContext(), selectedPackage), this);
builder.setAdapter(listAdapter, this);
}
//----- ListPreference Overrides END -----
}
而且我现在是这样在我的preferences.xml中使用它的:
<PreferenceScreen android:key="connection_screen"
android:title="@string/wpref_Connection_Screen_title"
android:summary="@string/wpref_Connection_Screen_summary"
android:shouldDisableView="true">
<com.test.app.CustomSelectAppPreference android:key="userSelectedApplication"
android:title="@string/wpref_userSelectedApplication_title"
android:summary="@string/wpref_userSelectedApplication_summary"
android:dialogTitle="@string/userselectedApplication_dialogTitle"
android:entries="@array/selectedapps_dummy_actions"
android:entryValues="@array/selectedapps_dummy_actionsvalues"
android:defaultValue=""
android:shouldDisableView="true"/>
</PreferenceScreen>
通过使用这种方法,我可以在不违反Android有关首选项的规则的情况下控制用户在此活动中所做的一切。
希望这可以帮到您。