Brian
Brian

Reputation: 1989

How can I capture data coming into my Android app from the standard input (stdin)?

I am writing an app that uses an external USB barcode/RFID scanner. The scanner is a standard HID, and works well on my Android devices. I plug it in, hit the scan button, and data pops up in a text editing app. The same can be said for a standard USB keyboard. I plug it in, start typing, and data shows up in a text editing app.

Here is where I need assistance. What I need to do is manipulate the data coming into my app, from the scanner or external keyboard, before I can place it into the correct form fields of the app.

At this point, I thought I could just intercept the data at the standard input, so this is what I came up with:

activity_main.xml

<LinearLayout>
    <EditText android:id="@+id/scan_data" />
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    EditText scannedInput = (EditText)findViewById(R.id.scan_data);

    BufferedReader scanner = new BufferedReader(new InputStreamReader(System.in));

    StringBuilder sBuilder = new StringBuilder();
    String buffer;

    while((buffer = scanner.readLine()) != null){
        sBuilder.append(buffer);
    }

    String[] dataPoints = sBuilder.toString().split("\u003D|\u0026");

    scannedInput.setTextColor(Color.RED);
    scannedInput.setTextSize(34f);
    scannedInput.setText(dataPoints[0]); // or dataPoints[1], dataPoints[2], etc.
}

I wrote this, hooked up my scanner, and scanned an RFID tag. To my surprise, the entire scanned string showed up in my EditText field, and not just a part. After some debugging, I found out I could delete all code after setContentView() and the entire string still shows up in my EditText field.

So, what I need to know is, how I can capture the stdin from any external source (e.g., scanner, keyboard, etc.), and manipulate it before placing it where I want it (form field, database, etc.).

How can I go about doing this?

Upvotes: 1

Views: 663

Answers (1)

Larry Schiefer
Larry Schiefer

Reputation: 15775

The short answer is that you can't access stdin, there is no such animal in Android for apps. The text is being injected into the active EditText because the RFID / USB device you are using is presenting itself as a HID device. These are automatically picked up by the Android subsystem as an input source and their input routed to the active view as if it came from a keyboard.

All is not lost, however. What you can do is attach a TextWatcher to your EditText and manipulate the text in the Editable:

EditText et = (EditText)findViewById(R.id.whatever_your_id);
et.addTextChangedListener(new TextWatcher() {
        @Override
        void afterTextChanged (Editable s) {
            //  Make your changes to 's' here, carefully as your changes will
            //  cause this method to be called again!
        }

        @Override
        void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //  Nothing to do here
        }

        @Override
        void onTextChanged(CharSequence s, int start, int before, int count) {
            //  Nothing to do here
        }
    });

Upvotes: 1

Related Questions