I am using Android Studio and I am a little stuck on `AsyncTask`

My Application is meant to run on RFID scanner and one of the features is to find one specific tag in a warehouse full of tagged items. 

So I need to be able to continuously scan and read tags as the device moves around the warehouse and when a match is found, the device makes a sound to alert the user. I get this to work with a loop, but the problem is that I need to allow the user to cancel out of this on the click of a button, which would suggest moving the searching of the tag to an async task. 

What I am currently doing is in an onKeyDown event, fire the code that does the reading of tag and update a variable with the tagNumber, then put a loop around the change listener of this variable to to pull the tag number on this event, if the result is unsuccessful (no match) call re-fire the keydown event and repeat the process until a match is found. 

```
public boolean onKeyDown(int keyCode, KeyEvent event) {

    while (Scan.equals("true")) {
        try {
            // ReadAction.onStart();
            if ((keyCode == KeyEvent.KEYCODE_SOFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
                    || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
                    || keyCode == KeyEvent.KEYCODE_F7 || keyCode == KeyEvent.KEYCODE_F8) && event.getRepeatCount() <= 0
                    && ReadAction.mReader.getAction() == ActionState.Stop && ReadAction.mReader.getState() == ConnectionState.Connected) {

                ATLog.i(TAG, "INFO. onKeyDown(%d, %d)", keyCode, event.getAction());

                mElapsedTick = SystemClock.elapsedRealtime() - mTick;
                if (mTick == 0 || mElapsedTick > SKIP_KEY_EVENT_TIME) {
                    startAction();
                    mTick = SystemClock.elapsedRealtime();
                } else {
                    ATLog.e(TAG, "INFO. Skip key down event(elapsed:" + mElapsedTick + ")");

                    return super.onKeyDown(keyCode, event);
                }
                final String SearchedTagNo = getScannedTag();
                ReadAction.setListener(new BaseReadAction.ChangeListener() {
                    @Override
                    public void onChange() {
                        if (Scan.equals("true")) {
                            String scannedTag= ReadAction.getEpcNo();
                            if (!SearchedTagNo .equals(scannedTag)) {
                                onKeyDown(2, keyEvent);
                            } else if (SearchedTagEPC.equals(EPCTag)) {

                                //indicate success to user on screen and by sound
                                mSound.playSuccess();
                                txtSearchResult.setText(" Found in this Area");
                            }
                        }

                    }
                });

                return true;
            }
        } catch (Exception e) {
            logWork.AppendLog("ERROR: " + e.getMessage() + " m_KeyDown(), a_AssignTag");
            Toast.makeText(Search_Activity.this, e.getMessage().toString(),
                    Toast.LENGTH_LONG).show();
        }

    }
    return super.onKeyDown(keyCode, event);
}

```

I wanted to call this onKeyDown method/event from the doInBackground method in the async class, but it failed and from what I read it is not possible to access UI items in an async task/method

Alternatives that I have read up on were to put it in the onProgressUpdate method of the `AsyncTask` class and call publish progress from doInBackground, but that did not work for me either. 

```
class AsyncSearch extends AsyncTask <Void, Void, Void> {
    KeyEvent keyEvent;
    Search_Activity searchActivity = new Search_Activity(); //thinking this is causing the problem

    public AsyncSearch() {
        keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, 2);
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            //calling onProgressUpdate to fire, and placing code that needs access to UI thread in the onProgressUpdate method
            //because you cannot instantiate a class in a background worker.
            publishProgress();
        } catch (Exception e) {
            throw e;
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {

        //calls the onKeyDown event in Search_Activity Asynchornously
        searchActivity.onKeyDown(2, keyEvent);
    }

```

There is no equivalent for IsInvokeRequired like one would use in .net, that I could find anyway... 

Is there a workaround I have not yet stumbled across? should I just change the approach to this problem altogether? Not sure how I can keep this search running and listen to the Cancel click event to cancel out of this search "loop"