简体   繁体   中英

startActivityForResult migration, call registerForActivityResult outside activity

In my android/java application (personal use) which dates back a few years, I have to migrate many startActivityForResult calls to registerForActivityResult (gallery pickup, photo taking, scanner etc...) but, despite many hours spent, I can't do it alone. I'm very far from being a confirmed developer and I'm lost. If I could manage to have a working example I think I would manage to adapt it, but even the simplest example doesn't work in my context. Obviously, I would like to avoid too in-depth modifications that I would be unable to implement.

Here is one of the an examples:

I have a RanktActivity.java activity with a menu. An option (add) from this menu opens a popup (using the RangtInputDialog class) in which I create an article, and I associate an image from the gallery (which I normally resize then I save). Here is the original code that I tried to simplify as much as possible:

activity:

public class RangtActivity extends AppCompatActivity implements RangtCalls.CallbacksAll, RangtCalls.CallbacksDelete, RangtCalls.CallbacksAllImages,
        ProductCalls.CallbacksAll, ProductCalls.CallbacksAllImages, SyncCalls.CallbacksUpload, SyncCalls.CallbacksDownload {
    private RangtInputDialog mRangtInputDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // initializations
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_add) {
            mRangtInputDialog = new RangtInputDialog(this);
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case Consts.RESULT_RANGT_REQUEST_GALLERY:
                    // image processing, resize, save...
                    break;
            }
        }
    }
}

class:

public class RangtInputDialog implements RangtCalls.CallbacksByTitle, RangtCalls.CallbacksCreate, RangtCalls.CallbacksUpdate {
    private final Context mContext;
    private AlertDialog mInputDialog;
    private View mPromptsView;

    public RangtInputDialog(Context context) {
        mContext = context;
        this.init();
    }
    private void init() {
        LayoutInflater li = LayoutInflater.from(this.mContext);
        mPromptsView = li.inflate(R.layout.text_input_rangt, nullParent);
        final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this.mContext);
        alertDialogBuilder.setView(mPromptsView);
        final ImageButton imgButtonGal = mPromptsView.findViewById(R.id.addGal);

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton(android.R.string.ok, null)
                .setNegativeButton(android.R.string.cancel,
                        (dialog, id) -> {
                            // some treatments
                            dialog.cancel();
                        });

        this.mInputDialog = alertDialogBuilder.create();

        // traitement imageButton Gallerie
        imgButtonGal.setOnClickListener(view -> {
            int resultCode = mEditMode ? Consts.RESULT_RANGT_EDIT_REQUEST_GALLERY : Consts.RESULT_RANGT_REQUEST_GALLERY;
            Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            ((Activity) mContext).startActivityForResult(galleryIntent, resultCode);
        });
        init();
    }
}

I try to follow the example of https://apktutor.com/android-pick-image-and-display-in-imageview/ but

  1. if i put "ActivityResultLauncher mGetContent=..." in the onCreate of activity, i don't know how to call it from RangtInputDialog class. I tried with ((Activity) mContext).mGetContent.launch("image/*"); without success
  2. and if I put it in RangtInputDialog (which anyway doesn't seem possible to me) registerForActivityResult is not recognized since it's not an activity.

I really need help, as detailed as possible please, because I've been on it for 15 days, and I can't get anywhere.

One solution couldn't be:

public class RangtActivity extends AppCompatActivity {
    private ActivityResultLauncher<String> mBackFunctionGallery;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mBackFunctionGallery = registerForActivityResult(new ActivityResultContracts.GetContent(),
            new ActivityResultCallback<Uri>() {
                @Override
                public void onActivityResult(Uri uri) {
                    ...
                }
            });

    if (id == R.id.action_add) {
        mRangtInputDialog = new RangtInputDialog(this, mBackFunctionGallery);
        return true;
    }

and in RangtInputDialog class, just initialize:

public RangtInputDialog(Context context, ActivityResultLauncher<String> backFunctionGallerie
) {
    mContext = context;
    mBackFunctionGallery = backFunctionGallerie;
    this.init();
}

and call:

    imgButtonGal.setOnClickListener(view -> {
        mBackFunctionGallery.launch("image/*");
    }

? Is it a clean solution or is there a better way and it should be avoided?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM