Android 如何使用 Activity 类以外的 onActivityResult 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21780252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:04:02  来源:igfitidea点击:

How to use onActivityResult method from other than Activity class

androidandroid-activityonactivityresult

提问by Jay Vyas

I?am?creating?an?app?where?i?need?to find?current?location of user .

我?正在?创建?应用程序?在哪里?我?需要?找到?当前?用户的位置。

So?here?I?would?like?to?do?a?task?like?when user?returns?from?that?System intent,?my?task?should?be?done after that.(Displaying?users?current?location)

所以?在这里?我?会?喜欢?要做?做?任务?喜欢?什么时候用户?返回?从?那个?系统意图,?我的?任务?应该?在那之后完成。(显示?用户?当前位置)

So i am planning to use OnActivityResult().

所以我打算使用OnActivityResult().

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

}

But the problem is that I don't know how can I use that method in a class which is not extending Activity.

但问题是我不知道如何在不扩展 Activity 的类中使用该方法。

Please some one give me idea how can i achieve this?

请有人告诉我如何实现这一目标?

采纳答案by Jay Vyas

Finally i got what i need and also the solution for this question.

最后我得到了我需要的东西以及这个问题的解决方案。

 Activity con;
Intent intent_= new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            con.startActivityForResult(intent_, 0);

Now i can create a method here,

现在我可以在这里创建一个方法,

public void startActivityForResult(Intent i, int code)
{
    Log.e("", "insede method startActivityForResult()");
}

By using this System is not creating a sub-activity for my intent so,this method gets called only after user return from intent.

使用此系统不会为我的意图创建子活动,因此只有在用户从意图返回后才会调用此方法。

回答by Yogesh Lakhotia

You need an Activity on order to receive the result.

您需要一个 Activity 才能接收结果。

If its just for organisation of code then call other class from Activty class.

如果它只是为了组织代码,那么从 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);
        ...
    }

回答by Yogesh Lakhotia

Create an inner class in the non Activity class and define your activity results handler therein:

在非 Activity 类中创建一个内部类并在其中定义您的活动结果处理程序:

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

intantiate it to call startActivityForResult

初始化它以调用 startActivityForResult

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

your handler will be called. :)

您的处理程序将被调用。:)

ps: you may have to include some overrides. just leave them empty.

ps:您可能必须包含一些覆盖。只是让它们空着。

pps: this is old school java mouseListenerAdapter style ~Oo>

pps:这是老派的 java mouseListenerAdapter 风格~Oo>

回答by IgniteCoders

You can't call this method out of his scope.

你不能在他的范围之外调用这个方法。

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

If the method is protectedlike this case, you can see the table of Access Levelsto know how to proceed.

如果方法像这种情况一样受到保护,您可以查看访问级别表以了解如何继续。

|-----------------------------------------------------------|
|                     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    |
|------------------|---------|---------|----------|---------|

As you can see, this method only can be called from android.app.*package, Activityand their subclasses.

如您所见,此方法只能从android.app.*Activity及其子类中调用。



SOLUTION:

解决方案:

You need to do something like this:

你需要做这样的事情:

We have a class ImagePickerfor selecting a image from Galleryor Cameraor Deleteit. This class need to call onActivityResultif user wants to delete image (We don't need to start an Activityfor a result that we already know).

我们有一个ImagePicker用于从图库相机中选择图像或删除它的类。onActivityResult如果用户想要删除图像,这个类需要调用(我们不需要为Activity我们已经知道的结果启动一个)。

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

For using this class in our Activity, we need to implement the delegate methods and pass our activity as the delegate of ImagePicker:

为了在我们的 中使用这个类Activity,我们需要实现委托方法并将我们的活动作为 的委托传递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);
    }
}

Finally, we need to make thous delegate methods to be called, and that happen in show()and handleResponse(Intent data):

最后,我们需要调用数千个委托方法,这发生在show()and 中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
    }
}

At the end, what we have, is a classthat can call a method in your Activityinstead of onActivityResult, but when you get a result in onActivityResult, you need to handle it in that class

最后,我们拥有的是一个class可以在你的Activity而不是调用方法的方法onActivityResult,但是当你在 中得到结果时onActivityResult,你需要在那个中处理它class

回答by Ameer Moaaviah

You need to register an Activityto this class and then use OnActivityResult()for that activity.

您需要向Activity此类注册,然后OnActivityResult()用于该活动。

回答by Manuel Spigolon

When you start an activity with startActivityForResult method from an activity, only the caller will recive the result.

当您从活动中使用 startActivityForResult 方法启动活动时,只有调用方会收到结果。

So you could handle the result and pass it to the task or update the ui of that activity:

因此,您可以处理结果并将其传递给任务或更新该活动的 ui:

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

回答by DragonFire

I am using it like this this may be helpful to others

我像这样使用它这可能对其他人有帮助

In my fragment I have

在我的片段中,我有

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

    }
});

Then Calling The Result Like This In The Fragment

然后在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());
}

The public class / functions supporting these are

支持这些的公共类/函数是

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