Android onActivityResult NEVER called
Asked Answered
B

7

3

my onActivityResult method is never called. am using android 2.2

I am using a Tabhost, where TabHosts contain TabGroups which contain individual Activities.

One of my individual activity runs the following intent

 Intent intent = new Intent(); 
 intent.setType("image/*");
 intent.setAction(Intent.ACTION_GET_CONTENT);
 startActivityForResult(Intent.createChooser(intent,
                    "Select Picture"), 0);

this loads my gallery apps, I use the default android gallery to select one image and when I return my onActivityResult is not called my activity.

It looks like this - and I put a breakpoint at if(resultCode == 0) , so right now, the logic of my onActivityResult should not matter

 public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == 0) {
        if (requestCode == 0) {
            Uri selectedImageUri = data.getData();

            //OI FILE Manager
            filemanagerstring = selectedImageUri.getPath();

            //MEDIA GALLERY
            selectedImagePath = getPath(selectedImageUri);

            //DEBUG PURPOSE - you can delete this if you want
            if(selectedImagePath!=null)
                System.out.println(selectedImagePath);
            else System.out.println("selectedImagePath is null");
            if(filemanagerstring!=null)
                System.out.println(filemanagerstring);
            else System.out.println("filemanagerstring is null");

            //NOW WE HAVE OUR WANTED STRING
            if(selectedImagePath!=null)
                System.out.println("selectedImagePath is the right one for you!");
            else
                System.out.println("filemanagerstring is the right one for you!");
        }
    }
}

Lifecycle functions are often called out of order and intermittently for Activities within a tabhost/tabgroup, so I checked to see what lifecycle functions ARE being called after the gallery closes (this happens as soon as I select an image from the android gallery)

The only one being called is the onResume() in my TabHost activity. So I tried putting the exact same onActivityResult() method in my TabHost class AS WELL AS the TabActivity class. With a breakpoint in the same location at the beginning of method.

Neither of these classes are called.

I'm drawing a blank now, how can I get the result from the gallery app in my app if none of the built in receiving methods will respond to it.

Since I know that my main TabHost gets the onResume() called, I tried added Intent graphics = getIntent(); to see if it would receive data from the gallery selection, it does not, so I don't see how I can do the logic in the onResume() method either.

Solutions welcome! :)

Bracken answered 18/10, 2011 at 18:47 Comment(3)
Are you sure you have onActivityResult in the same activity that is calling startActivityForResult(..) ?Acantho
It is, I also added it in the tabgroup and tabactivity pages with breakpoints to see if any of them get called at all. Ironically it says that it will throw an ActivityNotFoundException if it isn't called correctly, and this doesn't work either :( its simply not being calledBracken
Just for fun have you tried creating a test project and just copying your intent along with the onActivityResult that you have in the above code to make sure it works then. If it doesn't work then. Something is funky with your phone/emulator. If it does work, something is being overlooked in your code or the activity that you are calling isn't calling setResult(..) properlyAcantho
B
4

The solution is to call a transparent activity over top of the main activity. This transparent activity is in front of the tabhost and will have normal lifecycle functions.

This transparent activity calls the gallery intent onCreate(), it gets everything returned like normal in its onActivityResult and you will be able to pass the information returned back to the rest of the app like normal. finish() is inside of the onActivityResult method, so the user never even notices that a transparent activity was called.

Update copied from from comments:

Activity A calls Activity B via normal intent. Activity B has no xml and runs onCreate like this

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //setContentView(R.layout.dialogpopper); 

    Intent intent = new Intent(Intent.ACTION_PICK); 
    intent.setType("image/*"); startActivityForResult(intent, 0);

}//end onCreate 

and when Activity C is finished it calls the onActivityResult of Activity B

Bracken answered 19/10, 2011 at 0:42 Comment(4)
This should definitely be considered a hack btw.Educative
Agreed with @Educative that this is quite "hacky". However, glad to hear you figured out a way to get this to workAcantho
Is a code example of this hack possible? Would really like to know how this is achieved!Sesquicarbonate
Activity A calls Activity B via normal intent. Activity B has no xml and runs onCreate like this public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.dialogpopper); Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, 0); }//end onCreate and when Activity C is finished it calls the onActivityResult of Activity BBracken
E
18

Try to call the startActivityForResult using the context of the tabgroup activity containing your current activity and then listen in the tabgroup activity.

Use this to get the tabGroupActivity:

TabGroupActivity parentActivity = (TabGroupActivity)getParent();

And then call startActivityForResult from it:

parentActivity.startActivityForResult(...);

Finally , put an onActivityResult listener in the tabGroupActivity:

protected void onActivityResult(int requestCode, int resultCode,Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
    }
Earthwork answered 9/2, 2012 at 9:1 Comment(1)
+1 I was calling startActivityForResult() from a fragment so I had to preface it with the parent Activity context.Wescott
H
16

Judging from the many questions like this one, there are many reasons why a called activity may not trigger the caller's onActivityResult() method.

One reason I found, was when I called startActivityForResult(intent, requestCode), with a requestCode value of less than 0. My application did not need a requestCode and the Android documentation said using < 0 would not send a requestCode.

But the Android docs did not mention the consequence of a requestCode < 0. The consequence is that it prevents the caller's onActivityResult() method from ever being invoked! Ouch!

Therefore, even if your app does not need a requestCode, you many still want to use one with a value >= 0.

That's what I learned today:-)

Happenstance answered 11/11, 2011 at 14:27 Comment(1)
yes, I think I saw a similar answer regarding that and tried it myself in a different application recentlyBracken
B
4

The solution is to call a transparent activity over top of the main activity. This transparent activity is in front of the tabhost and will have normal lifecycle functions.

This transparent activity calls the gallery intent onCreate(), it gets everything returned like normal in its onActivityResult and you will be able to pass the information returned back to the rest of the app like normal. finish() is inside of the onActivityResult method, so the user never even notices that a transparent activity was called.

Update copied from from comments:

Activity A calls Activity B via normal intent. Activity B has no xml and runs onCreate like this

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //setContentView(R.layout.dialogpopper); 

    Intent intent = new Intent(Intent.ACTION_PICK); 
    intent.setType("image/*"); startActivityForResult(intent, 0);

}//end onCreate 

and when Activity C is finished it calls the onActivityResult of Activity B

Bracken answered 19/10, 2011 at 0:42 Comment(4)
This should definitely be considered a hack btw.Educative
Agreed with @Educative that this is quite "hacky". However, glad to hear you figured out a way to get this to workAcantho
Is a code example of this hack possible? Would really like to know how this is achieved!Sesquicarbonate
Activity A calls Activity B via normal intent. Activity B has no xml and runs onCreate like this public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.dialogpopper); Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, 0); }//end onCreate and when Activity C is finished it calls the onActivityResult of Activity BBracken
P
2

You just have to remove android:noHistory="true" this form your manifest file.

Pfeiffer answered 30/1, 2017 at 11:59 Comment(0)
A
1

Use the constant values for the Result codes:

Activity.RESULT_OK and Activity.RESULT_CANCELED

You'll see that the value for cancelled is actually 0. So in your code you are checking to see if the activity was cancelled.

change your code to

if (resultCode == Activity.RESULT_OK) {
...
}

Additionally change your Intent action to be:

intent.setAction(Intent.ACTION_PICK);

If you do this, you can just call

    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    startActivityForResult(intent, 0); 

instead of creating the chooser. It will automatically pick the activities associated with that intent and mimetype and display them to you

Acantho answered 18/10, 2011 at 19:1 Comment(1)
I placed the above code in a test activity and tried it out on my phone and it worked perfectly. I'm not sure what's preventing onActivityResult(..) from being called. Are you sure you have onActivityResult in the same activity that is calling startActivityForResult(..) ?Acantho
M
0

The way onActivityResult is called depends on the launchMode of your Activity (in the manifest). I'm not sure if that can be an issue here.

Misdemeanant answered 15/2, 2012 at 11:5 Comment(0)
T
-1

do you have @Override above your onActivityRestult?

(looking at old code that does this so not sure why its needed) call super.onactivityresult(requestcode, resultscode, data) as the first call in the method

also my intents didnt have that other stuff in them startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0); i think should just be startActivityForResult(source.class, destination.class); of course source and destination should be the name of the classes

public class ImageSwitcherView extends Activity {
    int pics[] = { R.drawable.image000, R.drawable.image001,
            R.drawable.image002};

    private int currentIndex = 0;
    SharedPreferences preferences;
    Gallery gallery;
    ImageView fullPicView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.galleryview);
        Bundle extras = getIntent().getExtras();
        currentIndex = extras.getInt("bookmark");
        gallery = (Gallery) findViewById(R.id.Gallery01);

        gallery.setAdapter(new ImageAdapter(this));
        gallery.setSelection(currentIndex);
        gallery.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView parent, View v, int position,
                    long id) {
                currentIndex = position;
                // ---display the images selected---
                fullPicView = (ImageView) findViewById(R.id.imageView1);
                fullPicView.setImageResource(pics[currentIndex]);
                fullPicView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Intent myIntent = new Intent(ImageSwitcherView.this,
                                imageView.class);
                        int resID = pics[currentIndex];
                        myIntent.putExtra("resID", resID);
                        myIntent.putExtra("index", currentIndex);
                        startActivityForResult(myIntent, 1);
                    }
                });
            }
        });
    }

    public class ImageAdapter extends BaseAdapter {
        private Context context;
        private int itemBackground;

        public ImageAdapter(Context c) {
            context = c;
            // ---setting the style---
            TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
            itemBackground = a.getResourceId(
                    R.styleable.Gallery1_android_galleryItemBackground, 0);
            a.recycle();
        }

        // ---returns the number of images---
        public int getCount() {
            return pics.length;
        }

        // ---returns the ID of an item---
        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        // ---returns an ImageView view---
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView = new ImageView(context);
            imageView.setImageResource(pics[position]);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
            imageView.setBackgroundResource(itemBackground);
            return imageView;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        currentIndex = data.getIntExtra("bookmark", 0);
        gallery.setSelection(currentIndex);
        fullPicView.setImageResource(pics[currentIndex]);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                || keyCode == KeyEvent.KEYCODE_HOME) {
            preferences = PreferenceManager.getDefaultSharedPreferences(this);

            SharedPreferences.Editor editor = preferences.edit();
            editor.putInt("bookmark", gallery.getSelectedItemPosition());
            editor.commit();
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }

}
Thyrse answered 18/10, 2011 at 19:4 Comment(6)
override is there in my activity, i'll try your other recommendationsBracken
also try what is suggested below by Dymmeh?Thyrse
regarding intents, I am opening the built-in gallery, this calls the android application that is outside of my app. I can't do source.class, destination.class if it is outside of my app. Anyway, I'm having no luck. My activities still aren't called. using both Dymmeh's result codes and your super suggestionBracken
check out my updated answer about the Intent action. I "think" this is what you need.Acantho
not sure what you mean about "android application that is outside of my app", from what it sounds like the project your trying to do is very similar to one i have done in the past. ill edit my answer with some code and see if that helps.Thyrse
i still dont understand why you are calling a gallery intent as opposed to instantiating the gallery class. if you look at the code i posted that is an implementation of the gallery class and is how it should be. (i also dont understand why someone marked this down, its a good example to work from, showing an example and implementation of the topics in question)Thyrse

© 2022 - 2024 — McMap. All rights reserved.