web-dev-qa-db-fra.com

Comment utiliser la méthode onActivityResult à partir d'une classe autre que Activity

Je crée une application où j'ai besoin de trouver l'emplacement actuel de l'utilisateur.

Donc, ici, je voudrais faire une tâche comme lorsque l'utilisateur revient de cette intention du système, ma tâche devrait être effectuée après cela. (Affichage de l'emplacement actuel des utilisateurs)

Je prévois donc d'utiliser OnActivityResult().

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

}

Mais le problème est que je ne sais pas comment utiliser cette méthode dans une classe qui n'étend pas Activity.

S'il vous plaît, quelqu'un me donne une idée comment puis-je y parvenir?

20
Jay Vyas

Vous avez besoin d'une activité sur commande pour recevoir le résultat.

Si c'est juste pour l'organisation du code, appelez une autre classe de la classe Activty.

public class Result {
    public static void activityResult(int requestCode, int resultCode, Intent data){
          ...
   }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       Result.activityResult(requestCode,resultCode,data);
        ...
    }
12
Yogesh Lakhotia

Créez une classe interne dans la classe non Activity et définissez-y votre gestionnaire de résultats d'activité:

class singletonActivity extends Activity{
  protected void onActivityResult(...){
    // do whatever ..
  }
}

le lancer pour appeler startActivityForResult

Activity actv = new singletonActivity(..)
actv.startActivityForResult(intent ..)

votre gestionnaire sera appelé. :)

ps: vous devrez peut-être inclure des remplacements. laissez-les simplement vides.

pps: c'est de la vieille école Java style mouseListenerAdapter ~ Oo>

6
user1135300

Vous ne pouvez pas appeler cette méthode hors de sa portée.

protected void onActivityResult (int requestCode, int resultCode, Intent data)

Si la méthode est protégée comme dans ce cas, vous pouvez voir le tableau Niveaux d'accès pour savoir comment procéder.

|-----------------------------------------------------------|
|                     ACCESS LEVELS                         |
|------------------|---------|---------|----------|---------|
|      Modifier    |  Class  | Package | Subclass |  World  |
|------------------|---------|---------|----------|---------|
|      public      |    Y    |    Y    |    Y     |    Y    |
|------------------|---------|---------|----------|---------|
|      protected   |    Y    |    Y    |    Y     |    N    |
|------------------|---------|---------|----------|---------|
|      no modifier |    Y    |    Y    |    N     |    N    |
|------------------|---------|---------|----------|---------|
|      private     |    Y    |    N    |    N     |    N    |
|------------------|---------|---------|----------|---------|

Comme vous pouvez le voir, cette méthode ne peut être appelée que depuis le package Android.app.*, Activity et leurs sous-classes.


SOLUTION:

Vous devez faire quelque chose comme ceci:

Nous avons une classe ImagePicker pour sélectionner une image parmi Gallery ou Camera ou Delete it. Cette classe doit appeler onActivityResult si l'utilisateur veut supprimer l'image (nous n'avons pas besoin de démarrer un Activity pour un résultat que nous connaissons déjà).

public class ImagePicker {
    private ImagePickerDelegate delegate;

    public ImagePicker (ImagePickerDelegate delegate) {
        this.delegate = delegate;
    }

    //Will explain this two methods later
    public void show() {
        //Some code to show AlertDialog
    }

    public void handleResponse(Intent data) {
        //Some code to handle onActivityResult
    }

    //Our interface to delegate some behavior 
    public interface ImagePickerDelegate {
        void onImageHandled(Bitmap image);
        void onImageError();
        void onImageDeleted();
    }
}

Pour utiliser cette classe dans notre Activity, nous devons implémenter les méthodes déléguées et passer notre activité en tant que délégué de ImagePicker:

public class MyActivity extends Activity implements ImagePicker.ImagePickerDelegate {
    ImagePicker imagePicker;    

    @OnClick(R.id.image_edit)
    public void selectImage () {
        imagePicker = new ImagePicker(this);
        imagePicker.show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == ImagePicker.REQUEST_IMAGE_PICKER && resultCode == RESULT_OK) {
            imagePicker.handleResponse(data);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onImageHandled(Bitmap image) {
        //handle image resized
        imageView.setImageBitmap(image);
    }

    @Override
    public void onImageError() {
        //handle image error
        Toast.makeText(this, "Whoops - unexpected error!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onImageDeleted() {
        //handle image deleted
        groupImageView.setImageBitmap(null);
        groupImageView.setImageResource(R.drawable.ic_pick_picture);
    }
}

Enfin, nous devons créer des milliers de méthodes déléguées à appeler, et cela se produit dans show() et handleResponse(Intent data):

//The show method create and dialog with 3 options,
//the important thing here, is when an option is selected
public void show() {
    //Inflating some views and creating dialog...

    NavigationView navView = (NavigationView)viewInflated.findViewById(R.id.navigation_menu);
    navView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) {
            switch (menuItem.getItemId()) {
                case R.id.action_select_image:
                    Intent pickPhoto = new Intent(Intent.ACTION_PICK, Android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    activity.startActivityForResult(pickPhoto , REQUEST_IMAGE_PICKER);
                    break;
                case R.id.action_take_picture:
                    Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    activity.startActivityForResult(takePicture, REQUEST_IMAGE_PICKER);
                    break;
                case R.id.action_delete_image:
                    delegate.onImageDeleted(); //send response to activity
                    break;
            }
            alertDialog.dismiss();
            return true;
        }
    });

    //Show dialog...
}


//this method is called from onActivityResult
public void handleResponse(Intent data) {
    try {
        //Retrieve and resize image...
        delegate.onImageHandled(image); //send the image to activity
    } catch (Exception e) {
        e.printStackTrace();
        delegate.onImageError(); //send error to activity
    }
}

À la fin, ce que nous avons, c'est un class qui peut appeler une méthode dans votre Activity au lieu de onActivityResult, mais quand vous obtenez un résultat dans onActivityResult, vous devez le gérer dans ce class

3
IgniteCoders

Vous devez enregistrer un Activity dans cette classe, puis utiliser OnActivityResult() pour cette activité.

1
Ameer Moaaviah

Lorsque vous démarrez une activité avec la méthode startActivityForResult à partir d'une activité, seul l'appelant recevra le résultat.

Vous pouvez donc gérer le résultat et le transmettre à la tâche ou mettre à jour l'interface utilisateur de cette activité:

int MY_REQUEST_ID = 1;

public void onClick(){
    //Select a contact.
    startActivityForResult(
             new Intent(Intent.ACTION_PICK,
             new Uri("content://contacts")),
             MY_REQUEST_ID);
}    

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if(requestCose == MY_REQUEST_ID && resultCode == SUCCESS) {
         MyAsyncTask task = new AsyncTask(requestCode, resultCode, data);
         task.execute();
         // or update the UI
         textView.setText("Hi, activity result: "+ resultCode);
     }
}
1
Manuel Spigolon

Je l'utilise comme ceci, cela peut être utile aux autres

Dans mon fragment, j'ai

// Upload Cover Photo On Button Click
btn.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {

        // Start The Image Cropper And Go To onActivityResult
        Intent intent = ImageManager.startImageCropper(getContext());
        startActivityForResult(intent, CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE);

    }
});

Puis appeler le résultat comme ça dans le fragment

// On Activity Result for Start Activity For Result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    // Get The Image From Image Cropper
    Uri resultUri = ImageManager.activityResult(requestCode, resultCode, data, getContext());
}

La classe/les fonctions publiques qui les prennent en charge sont

public class ImageManager {

    // Start Image Cropper
    public static Intent startImageCropper(Context context) {

        // Crop Image
        Intent intent = CropImage.activity()
                .setGuidelines(CropImageView.Guidelines.ON)
                .setActivityTitle("Title")
                .setCropMenuCropButtonTitle("Save")
                .setAutoZoomEnabled(true)
                .setAspectRatio(1, 1)
                .getIntent(context);

        return intent;

    }

    public static Uri activityResult(int requestCode, int resultCode, Intent data, Context context) {

        // Handle Cropped Image

        Uri resultUri = null;

        if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
            CropImage.ActivityResult result = CropImage.getActivityResult(data);
            if (resultCode == Activity.RESULT_OK) {
                resultUri = result.getUri();

            } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
                Exception error = result.getError();
                Toast.makeText(context, (CharSequence) error, Toast.LENGTH_SHORT).show();
            }

        }
        return resultUri;
    }
}
0
DragonFire