如何在非Activity类中使用onActivityResult方法

21

我正在创建一个应用程序,需要找到用户的当前位置。

因此,在此我想执行以下任务:当用户从该系统意图返回时,我的任务应在此之后完成(显示用户的当前位置)。

所以我打算使用OnActivityResult()

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

}

但问题是我不知道如何在一个没有继承Activity的类中使用该方法。

请有经验的人给我一个想法,我该怎么做才能实现这个?


1
请点击此链接 http://android-er.blogspot.in/2011/08/return-result-to-onactivityresult.html,它可能会对您有所帮助。 - Shailendra Madda
你不能在其他类中调用该方法。你应该在活动中创建该类的实例并在那里调用处理方法。 - Sergo Pasoevi
1
你可以创建一个空白透明的活动,并从它的onActivityResult()方法中返回结果到你的任务。 - Ganster41
你是从哪里调用这个的? - Phil
7个回答

12

您需要一个Activity来接收结果。

如果仅为了代码组织,则从Activity类中调用其他类。

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

我无法理解你的逻辑。你能演示一下吗? - Jay Vyas
我正在做类似的事情,只是为了组织Facebook登录的代码,但是在Fragment中的onActivityResult()在成功登录尝试后没有被调用。有人可以帮忙吗? - Ali_Waris

6
在非Activity类中创建一个内部类,并在其中定义您的Activity结果处理程序:
class singletonActivity extends Activity{
  protected void onActivityResult(...){
    // do whatever ..
  }
}

实例化它以调用startActivityForResult

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

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

附注:您可能需要包含一些覆盖。只需将它们留空即可。

附注2:这是老派的Java MouseListenerAdapter风格 ~Oo>


好主意,我正在处理一些第三方项目,无法访问主项目代码。你的答案可能解决我的问题。 - Swapnil
这会产生一个错误“无法找到明确的活动类{...},您是否在AndroidManifest.xml中声明了此活动?”。应该如何将其添加到AndroidManifest.xml中呢? - kamal0808

5

您不能在其作用域之外调用该方法。

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

如果该方法是像这种情况下的protected,您可以查看访问级别表格以了解如何进行操作。
|-----------------------------------------------------------|
|                     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    |
|------------------|---------|---------|----------|---------|

如您所见,此方法仅限于从android.app.*包、Activity及其子类中调用。


解决方案:

您需要执行以下操作:

我们有一个名为ImagePicker的类,用于从GalleryCameraDelete中选择图像。如果用户想要删除图像,则此类需要调用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();
    }
}

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

最后,我们需要使这些委托方法被调用,在show()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
    }
}

最终,我们拥有了一个class,它可以调用你的Activity中的方法,而不是onActivityResult。但在onActivityResult中获取结果时,你需要在那个class中进行处理。


1
这是关于SO上所有类似问题的正确答案,应该有更多的赞。 - Manuel

1

我正在这样使用它,这可能对其他人有帮助

在我的片段中,我有

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

    }
});

然后在片段中像这样调用结果

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

支持这些的公共类/函数为:

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

完美的答案! - Harvi Sirja

1
当您使用startActivityForResult方法从一个activity启动另一个activity时,只有调用者会收到结果。因此,您可以处理结果并将其传递给任务或更新该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);
     }
}

1

您需要为此类注册一个Activity,然后使用OnActivityResult()来处理该活动。


-3

最终我得到了我需要的东西,也找到了这个问题的解决方案。

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

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

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

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


12
onActivityResult方法在哪里? - Danilo Raspa
1
这似乎是一段未完成的代码。从你的问题中可以理解到,你需要"OnActivityResult"方法,它在你的答案中在哪里? - Itai Spector

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接