11

I'm trying to create an android project that contains shared code which will be used by others. In this project I only have POJO and no android specific classes.

Some of the functionality requires calling some activities and is depended on the result. My POJO classes get reference to the calling activity when used, but that's happening at run time and I have no control over the implementation of those activities.

My problem is that with the reference of the calling activity I can startActivityForResult but I have no way of adding the onActivityResult, which might exists in the calling activity but is not aware of the requestCode I used.

My question then is how do I know, from within a regular java object when the activity has returned? since, as far as I understand I can only implement onActivityResult on Activity classes.

thanks!

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299

5 Answers5

1

i have the same problem while i play with UNITY3D,the unity have it's own Activity(the unity player),i don't wanna edit it for some reason. but the player activity do nothing inside the "onActivityResult" function. And i have something to do when access image picker,i can call "unityPlayer.startActivityForResult" to open image picker,but NO WAY TO CODE MY OWN "onActivityResult".

i think what we hope is something like this:

OtherActivityClass.onActivityResultListener=function(){My Own CODE}..........OR OtherActivityClass.onActivityResultListener.add(myResultListener)..................

1

You will have quite a few problems with this setup, but this is how you might want to get started:

You will have to include an activity in your project which does nothing else than starting the activity you want to get the result from and stores it in a globally accessible storage (e.g. a singleton or a static field).

class Pojo {
    static final ConditionVariable gate = new ConditionVariable();
    static int result;

    int m(Context context) {
        context.startActivity(new Intent(context, ForwarderActivity.class));
        gate.block();
        return result;
    }
}

class ForwarderActivity extends Activity {
    private boolean started = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (!started) {
            started = true;
            startActivityForResult(new Intent("ContactsProvider"), 1);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Pojo.result = resultCode;
        Pojo.gate.open();
    }
}

There are a couple of problems, though. Like your POJO's method can't be called from the main (UI) thread, because you need to convert an asynchronous call (startActivityForResult()) to a synchronous one (Pojo.m()) and the activity you want to receive info from will be started on the main thread, so you can't block it in Pojo.m()...

Anyway, the code does not work, but you can see which way to go if you really have to stick with this setup. But you should really try to come up with some other means of fetching the data, like a content provider.

Szabolcs Berecz
  • 4,081
  • 1
  • 22
  • 21
0

Maybe PendingIntent http://developer.android.com/reference/android/app/PendingIntent.html can help you with that. I'm still looking around for a solution to my problem and for me, this class looks quite promising.

Another way might be to make your own class abstract and have a method onActivityResult that is required to be overridden. Of course, you would have to rely on JavaDoc and "please call super.onActivityResult" to be able to process the result in your code. But if the users of your class want to have some success with your code they should follow your JavaDoc instructions.

Risadinha
  • 16,058
  • 2
  • 88
  • 91
0

Similar to what Szabolcs Berecz suggests, it is possible. There is no beautiful solution, but following is possible:

  • create a simple no view activity that starts the intent for you
  • distribute the result through a global listener manager where interested classes can register and unregister theirself (the POJO e.g.)
  • this is non blocking but startActivityForResult and waiting for its result is non blocking in general

I've set this up in a library for app settings and some settings do start a system intent (e.g. select an image) and need to wait for their result and this works even after screen rotation without the need of any code adjustments by the libraries user.

prom85
  • 16,896
  • 17
  • 122
  • 242
0

My question then is how do I know, from within a regular java object when the activity has returned?

Have the activity call the POJO, supplying the result.

My POJO classes get reference to the calling activity when used, but that's happening at run time and I have no control over the implementation of those activities.

Then whoever is in "control over the implementation of those activities" will need to have the activity call the POJO, supplying the result. This is no different than any other callback/listener mechanism.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Well, I have some nasty constraints I need to deal with.. what ever uses my POJO is like a black box for me, all I know that it invokes methods on my POJOs and in return expect a result. As for the activities I want to call from within my POJO, those are activities existing in the android device, which also are out of my control.. I just need to call them (let's say get a contact) and get the result. thanks. – Nitzan Tomer Oct 04 '11 at 15:11
  • @Nitzan Tomer: "I have some nasty constraints I need to deal with" -- those constraints will need to be lifted. You cannot use `startActivityForResult()` except from some activity of yours where you implement `onActivityResult()`. – CommonsWare Oct 04 '11 at 15:29