Handle onActivityResult on a Service

不问归期 提交于 2020-01-01 04:36:29

问题


So i have a simple Question , it is Possible to Handle the Method onActivityResult() in a Service if this Activity was Started from the Same Service (Using Intent) ?

In My Case , i want to start SpeechRegnition , Speak , and Get the Result on the Service , Everything on Background (Main Service Start from a Widget) ,

Thanks .


回答1:


Thanks for a recent downvoting, whoever it was. The previous answer I gave back in 2012 is a total nonsesnse so I decided to write a proper one.

You can not handle Activity result in a Service, but you can pass any data retrieved from onActivityResult() to a Service.

If your Service is already running, you can call startService() with a new Intent handling the event, like so

@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);
}

And handle action in a Service. If it is already running it will not be restarted, otherwise it will be started

@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;
}



回答2:


I recently stumbled upon the same issue, how to wire onActivityResult() outcome to a Service for an Activity started from the aforementioned Service. I did not want to store the Activity in a static variable given that Activity leak is a bad practice. So I added a static listener in the Activity handling onActivityResult() that implements an appropriate Interface and instantiated this listener as a private member of the Service class.

The code in a simplified form looks like this:

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);
    } 
}

As you can see I could not avoid static references due to device rotation issues, but I think this solution is more appropriate; albeit verbose.




回答3:


Open Transparent activity from service and use BroadcastReceiver in service. Follow the steps in detail.

1. Open transparent activity from Service

Intent i = new Intent(mContext, FloatingServiceSupportActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("action", "SpeechRegnition");
mContext.startActivity(i);

// For transparent activity use this code in AndroidManifest.xml

<activity
android:name=".FloatingServiceSupportActivity"
android:theme="@style/Theme.Transparent" />

2. Create BroadcastReceiver in Service

BroadcastReceiver brOnActivityResult = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO:
    }
};

3. Register this broadcast in onCreate of Service

IntentFilter brintent = new IntentFilter();
brintent.addAction("brActionFloatingServiceOnActivityResult");
mContext.registerReceiver(brOnActivityResult, brintent);

4. Unregister this broadcast in onDestroy of Service

mContext.unregisterReceiver(brOnActivityResult);

5. Do work in Activity by using startActivityForResult and Send broadcast from Activity's (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();
}


来源:https://stackoverflow.com/questions/13608236/handle-onactivityresult-on-a-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!