需要帮助获取Android TextWatcher以处理传入的复合条形码数据

时间:2017-03-02 20:38:20

标签: android textwatcher

我正在编写一个使用和外部连接USB条形码/ RFID扫描仪的应用程序。正在扫描的数据是"复合"数据。这是一个例子:

=+03000=W12560712345600=%2800&>0090452359

那是来自复合数据扫描。数据中的分隔符是等号(=)或&符号(&)。第一位=+03000表示扫描中有三个数据部分:

=W12560712345600

=%2800

&>0090452359

此数据可以包含从1到N的任意数量的数据部分。

在我的Android应用中,我有一个包含三个EditText元素的表单。我需要对这个复合扫描数据做的是使用分隔符将其分解,并将每个数据粘贴到正确的EditText字段中。

经过多次痛苦之后,我已经意识到我不能只操纵标准输入,并且我需要在我的TextWatcher个字段之一上使用EditText来捕获扫描数据所以我可以操纵它。

我的问题是我无法弄清楚如何做到这一点。这就是我所拥有的:

activity_main.xml中

<LinearLayout>
    <TextView />
    <EditText android:id="@+id/datafield01" />
    <EditText android:id="@+id/datafield02" />
    <EditText android:id="@+id/datafield03" />
    <Button />
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText dataField01 = (EditText)findViewById(R.id.datafield01);
        EditText dataField02 = (EditText)findViewById(R.id.datafield02);
        EditText dataField02 = (EditText)findViewById(R.id.datafield03);

        dataField01.addTextChangedListener(editTextWatcher);
    }

    TextWatcher editTextWatcher = new TextWatcher(){
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count){
        }

        @Override
        public void afterTextChanged(CharSequence s){
        }
    };
}

我尝试将CharSequence捕获到StringBuffer - 使用before,on和afterTextChanged - 所以我可以操纵它并将其放入正确的EditText元素中,但我有没有成功。

修改后的MainActivity.java

public class MainActivity extends AppCompatActivity {
    private StringBuffer stringBuffer;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        stringBuffer = new StringBuffer();

        EditText dataField01 = (EditText)findViewById(R.id.datafield01);
        EditText dataField02 = (EditText)findViewById(R.id.datafield02);
        EditText dataField02 = (EditText)findViewById(R.id.datafield03);
        dataField01.addTextChangedListener(editTextWatcher);

        System.out.println(stringBuffer.toString());
    }

    TextWatcher editTextWatcher = new TextWatcher(){
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count){
            stringBuffer.append(s);
        }

        @Override
        public void afterTextChanged(CharSequence s){
        }
    };
}

每当我尝试System.out.println(stringbuffer);时,那里什么都没有。

扫描的代码没有给出换行符或任何其他类型的分隔符,它已经结束,数据部分的数量可以是1到N,但每个数据部分确实具有已知的固定长度。

必须有其他人做这样的事情,但我的谷歌搜索没有结果。

那么,有没有办法完成我想要做的事情,或者我完全没有运气?

感谢。

3 个答案:

答案 0 :(得分:0)

我确信有一些方法可以通过一些TextWatcher实现来执行此操作;当你看到分隔符char等时切换焦点

但是当我知道您拥有条形码扫描仪的所有输入时,我认为它更容易处理。然后,您可以简单地解析数据并将其放在适当的位置。

所以诀窍就是弄明白你何时拥有所有扫描仪输入,以便你可以解析它。

这里有一些代码使用了我从查看适用的Android Filter类中学到的技巧。对于多个快速按键,只有一次过滤延迟机制。 (可悲的是,它是谷歌的私人所以我们凡人都不应该使用这个有用的功能。)

由于您的扫描仪看起来像键盘,因此按键暂停应表示扫描仪已完成输入。让我们用它来确定扫描何时完成。

首先,我们定义一个回调接口只是因为我是一个IoC类型的人:

    interface ScanProcessor {

       void process(CharSequence input);
    }

现在我们定义一个Handler类。这个处理程序将在主(UI)线程上运行,因此我们不能在处理器中忙碌。

    public static class InputDelayHandler extends Handler {

       private static final int INPUT_MESSAGE = 0x20170308;

       private static final int PROCESS_MESSAGE = 0x20170309;

       // You'll have to tweak this value to ensure all input is entered, 
       // while the app remains responsive to the scan
       private static final long DELAY_MS = 250;

       private CharSequence mInput;

       private ScanProcessor mScanProcessor;

       InputDelayHandler(ScanProcessor scanProcessor) {
           super();  // associate the handler with the Looper for the current thread
           mScanProcessor = scanProcessor;
       }

       void setInput(CharSequence input) {

           // removing this message is the key to how this works
           // since it's delayed, we can cancel before input is complete.
           removeMessages(PROCESS_MESSAGE);
           removeMessages(INPUT_MESSAGE);
           Message inputMessage = obtainMessage(INPUT_MESSAGE);
           inputMessage.obj = input;
           sendMessage(inputMessage);
           Message startMessage = obtainMessage(PROCESS_MESSAGE);
           sendMessageDelayed(startMessage, DELAY_MS);
       }

       @Override
       public void handleMessage(Message msg) {

           switch (msg.what) {
           case INPUT_MESSAGE:
               // remember the last input
               mInput = (CharSequence) msg.obj;
               break;
           case PROCESS_MESSAGE:
               // callback
               if (/*mInput looks like valid scan data*/) {
                   mScanProcessor.process(mInput);
               }
               break;
           }
       }
   }

具有EditText字段的类应该保留对处理程序的引用。

        private InputDelayHandler mHandler;

现在你的TextWatcher只需要告诉处理程序发生的事情:

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            mHandler.setInput(s);
        }

这将它们联系在一起:

            mHandler = new InputDelayHandler(new ScanProcessor() {

                @Override void process(CharSequence input) {

                    // parse the input, set the EditText fields, etc.
                }
            });

答案 1 :(得分:0)

首先,您应该将TextWatcher设置为所有3个字段,这样哪个字段具有焦点是不重要的。然后只关注afterTextChanged

 <table id = "datatable" class="table table-striped table-bordered"  style="font-size: 85%">
                    <thead>
                    <tr>
                        <th class="bg-primary col-sm-2" >
                            <font size="4">
                                Employee
                            </font>
                        </th>
                        {{--<th class="bg-danger">--}}
                            {{--<font size="4">--}}
                                {{--Company--}}
                            {{--</font>--}}
                        {{--</th>--}}
                        {{--<th class="bg-success">--}}
                            {{--<font size="4">--}}
                               {{--Category--}}
                            {{--</font>--}}
                        {{--</th>--}}
                        {{--<th class="bg-warning">--}}
                            {{--<font size="4">--}}
                                {{--Task--}}
                            {{--</font>--}}
                        {{--</th>--}}
                    </tr>
                    </thead>
                    <tbody>
                    @foreach ($report_table_all as $report)
                        <?php
                        $name = $report[0]['user_name'];
                        $user_designation = $report[0]['user_designation'];
                        ?>
                        <tr>
                            <td>
                                {{--<font size="2">--}}
                                <strong>{{$name}}</strong></br>
                                {{--</font>--}}
                                <font size="1">
                                    {{$user_designation}}
                                </font>
                            </td>
                            <td>

                                @foreach ( $report as $daily_report )

                                    <table class="table table-striped table-bordered datatable" style="font-size: 85%">
                                        <thead>
                                        <tr class="primary" style="font-size: 15px;">

                                            <th class="bg-info">Concern</th>
                                            <th class="bg-warning">Category</th>
                                            <th class="bg-success">Task</th>
                                            <th class="bg-danger">Date</th>

                                        </tr>
                                        </thead>
                                        <?php
                                        $total = 0;
                                        $sn = 1;
                                        $sn_total = '*';
                                        ?>
                                        @foreach($daily_report['user_task_lists'] as $user_task)
                                            <tr>


                                                <td style="background-color: rgba(227, 255, 140, 0.98); ">
                                                    <center>{{$user_task->workfor_name}}</center>
                                                </td>
                                                <td>
                                                    <table class="table table-striped table-bordered datatable" style="font-size: 85%">
                                                        <tr>
                                                            <td style="font-size: 13px;background-color: rgba(19, 214, 255, 0.98)">
                                                                {{$sn}}.{{ $user_task->taskcategory_name }}
                                                                <?php $sn += floatval(1) ?>
                                                            </td>
                                                        </tr>

                                                    </table>
                                                </td>
                                                <td style="font-size: 12px;">
                                                    {{ $user_task->description}}

                                                </td>
                                                <td>
                                                    {{date('d-M-Y',strtotime($user_task->task_date))}}
                                                </td>


                                            </tr>

                                        @endforeach

                                    </table>

                            </td>

                            @endforeach




                        </tr>

                    @endforeach

                    </tbody>
                </table>

答案 2 :(得分:0)

这里你真正想做的事情包括几个部分:

  1. 从rfid中读取数据:
  2. 实现这一点的正确方法首先是添加正确的权限:

    <uses-permission android:name="android.permission.NFC" />
    <uses-sdk android:minSdkVersion="10"/>
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    

    然后,添加您的意图,“知道”如何处理扫描数据:

    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain" />
    </intent-filter>
    

    然后,您希望在单独的res xml文件中添加您的应用支持的NFC技术:

    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
        <tech-list>
            <tech>android.nfc.tech.IsoDep</tech>
            <tech>android.nfc.tech.NfcA</tech>
            <tech>android.nfc.tech.NfcB</tech>
            <tech>android.nfc.tech.NfcF</tech>
            <tech>android.nfc.tech.NfcV</tech>
            <tech>android.nfc.tech.Ndef</tech>
            <tech>android.nfc.tech.NdefFormatable</tech>
            <tech>android.nfc.tech.MifareClassic</tech>
            <tech>android.nfc.tech.MifareUltralight</tech>
        </tech-list>
    </resources>
    

    最后,将您的活动绑定到AndroidManifest.xml文件中的intent:

    <activity>
    ...
    <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED"/>
    </intent-filter>
    
    <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
        android:resource="@xml/nfc_tech_filter" />
    ...
    </activity>
    
    1. 收到数据后,您希望将消息分成3个部分,如您所示,除以'='符号或'&amp;'签名:

      Parcelable [] rawMsgs = intent.getParcelableArrayExtra(         NfcAdapter.EXTRA_NDEF_MESSAGES);

      NdefMessage msg =(NdefMessage)rawMsgs [0]; String st = new String(msg.getRecords()[0] .getPayload()); ST。 String [] tokens = st.split(“= |&amp;”);

    2. 完成后,令牌数组应保留您的消息。

      https://developer.android.com/guide/topics/connectivity/nfc/nfc.html#tag-dispatch