所以我有一个简单的问题,如果此活动是从同一服务启动的(使用 Intent),是否可以在服务中处理方法 onActivityResult()?
在我的情况下,我想启动 SpeechRegnition 、 Speak 并在服务上获取结果,一切都在后台(主要服务从小部件开始),
谢谢 。
感谢最近的投票,无论是谁。我在 2012 年给出的上一个答案完全是胡说八道,所以我决定写一个正确的答案。
您不能在服务中处理活动结果,但您可以将从 onActivityResult() 检索到的任何数据传递给服务。
如果您的 Service 已经在运行,您可以使用新的 Intent 调用 startService() 来处理事件,如下所示
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CODE && resultCode == RESULT_OK) {
notifyService(data);
}
}
private void notifyService(final Intent data) {
final Intent intent = new Intent(this, MyService.class);
intent.setAction(MyService.ACTION_HANDLE_DATA);
intent.putExtra(MyService.EXTRA_DATA, data);
startService(intent);
}
并在服务中处理操作。如果已经在运行,则不会重新启动,否则将启动
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
final String action = intent.getAction();
if (action != null) {
switch (action) {
case ACTION_HANDLE_DATA:
handleData(intent.getParcelableExtra(EXTRA_DATA));
// Implement your handleData method. Remember not to confuse Intents, or even better make your own Parcelable
break;
}
}
}
return START_NOT_STICKY;
}
从服务中打开透明活动并在服务中使用 BroadcastReceiver。详细按照步骤操作。
1.从Service开启透明Activity
Intent i = new Intent(mContext, FloatingServiceSupportActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("action", "SpeechRegnition");
mContext.startActivity(i);
// 对于透明活动,请在 AndroidManifest.xml 中使用此代码
<activity
android:name=".FloatingServiceSupportActivity"
android:theme="@style/Theme.Transparent" />
2.在Service中创建BroadcastReceiver
BroadcastReceiver brOnActivityResult = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO:
}
};
3.在服务的onCreate中注册这个广播
IntentFilter brintent = new IntentFilter();
brintent.addAction("brActionFloatingServiceOnActivityResult");
mContext.registerReceiver(brOnActivityResult, brintent);
4. 在 onDestroy of Service 中取消注册这个广播
mContext.unregisterReceiver(brOnActivityResult);
5. 使用 startActivityForResult 在 Activity 中工作,并从 Activity 的 (FloatingServiceSupportActivity) onActivityResult 发送广播
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Intent i = new Intent();
i.setAction("brActionFloatingServiceOnActivityResult");
i.putExtra("action", "initTextToSpeech");
mActivity.sendBroadcast(i);
mActivity.finish();
}
我最近偶然发现了同样的问题,如何将 onActivityResult() 结果连接到从上述服务启动的活动的服务。鉴于 Activity 泄漏是一种不好的做法,我不想将 Activity 存储在静态变量中。所以我在 Activity 处理 onActivityResult() 中添加了一个静态监听器,它实现了一个适当的接口,并将这个监听器实例化为 Service 类的私有成员。
简化形式的代码如下所示:
public class MyActivity extends FragmentActivity {
public Interface ResultListener {
onPositiveResult();
onNegativeResult();
}
private static ResultListener mResultListener;
public static setListener(ResultListener resultListener) {
mResultListener = resultListener;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && mResultListener != null) {
mResultListener.onPositiveResult();
} else if (resultCode == Activity.RESULT_CANCELED && mResultListener != null) {
mResultListener.onNegativeResult();
}
mResultListener = null;
}
}
public class MyService {
private MyActivity.ResultListener mListener = new MyActivity.ResultListener() {
onPositiveResult() {
// do something on RESULT_OK
}
onNegativeResult() {
// do something on RESULT_CANCELED
}
}
private void startActivityForResultFromHere() {
MyActivity.setListener(mListener);
Intent intent = new Intent();
intent.setClass(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
如您所见,由于设备旋转问题,我无法避免静态引用,但我认为这种解决方案更合适;尽管很冗长。