花费太多时间来显示等待蓝牙输入的页面

时间:2014-04-28 04:44:15

标签: android asynchronous bluetooth arduino handler

如果我从通过蓝牙连接的arduino设备获得某个输入,我想显示一个红色按钮。我的代码如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }

    blueconnect(); //creates my bluetooth connection

    if (waitarrival() == 1)
        Global.fullpaper = 1;


    if (Global.fullpaper == 1) {
        View paperbutton = findViewById(R.id.buttonPaper);
        paperbutton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);}


}

public int waitarrival()
{
    byte[] buffer = new byte[1024];  // buffer store for the stream
    int bytes; // bytes returned from read()

    // Keep listening to the InputStream until an exception occurs
    while (true) {
        try {
            // Read from the InputStream
            bytes = Global.mmInStream.read(buffer);
            if (bytes ==  30) //send 30 when trashcan finishes the movement sequence
                return 1;
        } catch (IOException e) {
            break;
        }
    }

    return 0;
}   

和我的arduino代码简单:

void setup() {
Serial.begin (9600);
}
void loop() 
{
  Serial.write(30);
}

当我第一次启动我的代码时,它只显示一个白色屏幕。如果我等待足够长的时间(例如10秒),实际上会显示红色按钮。然而,这是太多的等待时间...我该如何解决这个问题?在这一点上,任何帮助将非常感激。提前谢谢。

编辑:============================================= ==========================

我创建了AsyncTask类:

private class switchcolors extends AsyncTask<Void, Void, Integer>
{
    protected Integer doInBackground(Void...params) 
    {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()
        long targetTime = System.currentTimeMillis() + 50000; //wait for 50s


        while( System.currentTimeMillis() < targetTime ) 
        {
            try 
            {
                bytes = Global.mmInStream.read(buffer);
                if (bytes > 0)
                {
                    if (buffer[0] == 30) //send 30 from arduino ( Serial.write(30) )
                        return 1;
                }
            } 
            catch (IOException e) {}
        }

        return 0;
    }


    protected void onPostExecute(Integer result) 
    {
        if (result == 1)
        {
            View paperbutton = findViewById(R.id.buttonPaper);
            paperbutton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);           
        }
    }
}

并在onCreate()方法中使用此类:

new switchcolors().execute();

页面显示正确,但未显示红色按钮...我可以获得一些帮助吗?

编辑2 ============================================= === 没关系。以上作品!我的蓝牙设备出现了连接问题

1 个答案:

答案 0 :(得分:1)

这里的问题是waitarrival()阻止了你的ui线程,特别是对read()的调用。

您要做的是:

public int waitarrival() {
    while( Global.mmInStream.available() > 1 ) { // at least one byte available
        byte data = Global.mmInStream.read(); // read just one byte, that's all we need
        if( data == 30 ) {
            return 1; // if we received the '30' we were looking for, then we're good to go.
        }
    }
    return 0; // this is returned in all other cases -- i.e. no byte available, or no 30s.
}  

完成后,您可能需要定期检查以确定是否有来自蓝牙设备的反应。您可以查看Android蓝牙聊天示例,了解如何将整个事物正确地放在后台线程上 - 这是首选模式。

如果您真的想等待这个并处理自己的超时,可以将整个方法包装成AsyncTask,类似这样 -

protected Integer doInBackGround( Integer[] timeout ) {
    long targetTime = System.CurrentTimeMillis() + timeout[0] * 1000; // time out in seconds...

    while( System.CurrentTimeMillis() < targetTime ) {
       if( waitforarrival() == 1 )
           return 1;
       Thread.sleep(100); // sleep 1/10th of a second
    }

    return 0;
}

然后,您的onPostExecute()会根据结果更新用户界面。

然后你就像onCreate()那样调用它:

myTask.execute( 60 ); // wait for arrival for a minute.