多个蓝牙插座连接/关闭操作重启Android手机

时间:2011-06-17 02:55:21

标签: android bluetooth

我们正在使用Android手机通过蓝牙与传感器进行通信。手机需要定期连接传感器以收集生理数据,并且在两个连接之间可以自动关闭传感器以节省电力。

现在问题是:大约500次后,系统重新启动。然后我们编写了一小段测试程序来模拟整个过程。小测试程序也崩溃了Android手机。

有人可以帮帮我吗?谢谢!这是一个小测试程序。

package zhb.test.MhubTestBtConnect;

import java.io.IOException;
import java.util.Date;
import java.util.UUID;


import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MhubTestBtConnect extends Activity implements OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btnStart = (Button) findViewById(R.id.btn_start_test);
        btnStart.setOnClickListener(this);
        Button btnStop = (Button) findViewById(R.id.btn_stop_test);
        btnStop.setOnClickListener(this);

        fBeginView = (TextView) findViewById(R.id.begin_time);
        fBeginView.setText("off line");
        fEndView = (TextView) findViewById(R.id.end_time);
        fEndView.setText("off line");
        fShowView = (TextView) findViewById(R.id.show_status);
        fShowView.setText("off line");

        fShowRunTimesView = (TextView) findViewById(R.id.show_times_status);
        fShowRunTimesView.setText("off line");


        fInputMac = (EditText) findViewById(R.id.edit_add_mac);
        fInputMac.setText("00:19:5D:24:CB:A9");
        fDisconnectGap = (EditText) findViewById(R.id.edit_disconnect_gap);
        fDisconnectGap.setText("500");
        fconnectGap = (EditText) findViewById(R.id.edit_connect_gap);
        fconnectGap.setText("1000");

        fRunning = false;        
    }

    @Override
    public void onClick(View v)
    {
        switch ( v.getId() )
        {
            case R.id.btn_start_test:
                start();
                break;
            case R.id.btn_stop_test:
                stop();
                break;
            default:
                break;
        }       
    }

    private synchronized void start()
    {
        if ( fRunning == false )
        {
            fRunning = true;            


            fMac = fInputMac.getText().toString().toUpperCase();
            fConnectRunnable = new ConnectRunnable();           
            fBeginView.setText(new Date().toLocaleString());

            fConnectTimes = 0;
            fRunOkTimes = 0;
            new Thread(fConnectRunnable).start();
        }
    }

    private synchronized void stop()
    {
        if ( fRunning == true )
        {
            fRunning = false;

            fConnectRunnable.cancel();
            try
            {
                Thread.sleep(500);
            }
            catch (InterruptedException exception)
            {
                exception.printStackTrace();
            }


            fEndView.setText(new Date().toLocaleString());
        }
    }   

    private void connect()
    {
        Log.d(TAG,"---------- run "+fConnectTimes++ +" times");
        String UUID_STRING = "00001101-0000-1000-8000-00805F9B34FB";
        // may throws exception
        UUID uuid = UUID.fromString(UUID_STRING);

        // get adapter
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();        

        // get remote device
        BluetoothDevice btDevice = adapter.getRemoteDevice(fMac);
        if ( btDevice == null )
        {
            Log.e(TAG,"can't get remote device from given MAC : " + fMac);
            return;
        }
        int runResult = 0;
        // may throws exception
        fBtSocket = null;
        try
        {
            fBtSocket = btDevice.createRfcommSocketToServiceRecord(uuid);
            if ( adapter.isDiscovering() == true ) 
            {
                adapter.cancelDiscovery();
                Log.d(TAG,"cancel discover");
            }

            fBtSocket.connect();
            runResult = 1;
            Log.d(TAG,"connect socket OK");
            Log.d(TAG,"---------- run OK "+fRunOkTimes++ +" times");
        }
        catch (IOException exception)
        {       
            //adapter.cancelDiscovery();
            Log.d(TAG,"connect socket error",exception);
            if ( fBtSocket != null )
            {
                try
                {
                    fBtSocket.close();
                }
                catch (IOException exception1)
                {
                    Log.d(TAG,"close socket error",exception1);
                }
            }
            else
            {
                Log.d(TAG,"create socket NULL");
            }

            btDevice = null;
            //update ui
            Message msgRun = new Message();
            msgRun.what = R.id.show_status;
            msgRun.arg1 = SV_START_RUN;
            msgRun.arg2 = runResult;
            fMessHandler.sendMessage(msgRun);
        }

        //Note: You should always ensure that the device is not performing device discovery when you call connect(). 
        //If discovery is in progress, then the connection attempt will be significantly slowed and is more likely to fail.
        //adapter.cancelDiscovery();
    }
    private void close()
    {
        //update ui
        Message msgShut = new Message();
        msgShut.what = R.id.show_status;
        msgShut.arg1 = SV_SHUT_DOWN;
        fMessHandler.sendMessage(msgShut);

        if ( fBtSocket != null )
        {
            Log.d(TAG,"close socket");
            try
            {
                fBtSocket.close();
            }
            catch (IOException exception1)
            {
                Log.d(TAG,"close socket error",exception1);
            }
            fBtSocket = null;
        }
    }   
    private Handler fMessHandler = new Handler()
    {
        public void handleMessage(android.os.Message msg)
        {
            switch ( msg.what )
            {
                case R.id.show_status:
                    if ( msg.arg1 == SV_START_RUN )
                    {
                        if ( msg.arg2 == 1)
                            fShowView.setText("run OK");
                        else 
                            fShowView.setText("run Failed");

                        fShowRunTimesView.setText("run "+fConnectTimes+", OK "+fRunOkTimes);
                    }
                    else if ( msg.arg1 == SV_SHUT_DOWN )
                        fShowView.setText("shut down ...");

                    break;

                default:
                    break;
            }
        };
    };

    private long fConnectTimes;
    private long fRunOkTimes;
    private static final String TAG = "..MhubTestBtConnect";
    private BluetoothSocket fBtSocket;

    private ConnectRunnable fConnectRunnable;
    private String fMac;
    private boolean fRunning;

    private TextView fBeginView;
    private TextView fEndView;
    private TextView fShowView;
    private TextView fShowRunTimesView;
    private EditText fInputMac;
    private EditText fDisconnectGap;
    private EditText fconnectGap;

    private static final int SV_START_RUN = 1;
    private static final int SV_SHUT_DOWN = 2;

    private class ConnectRunnable implements Runnable
    {
        public ConnectRunnable()
        {           
            fCancelled = false;
        }
        @Override
        public void run()
        {           
            if (Looper.myLooper() == null) {
                Looper.prepare();
            }

            long afterConnectSleep = 500;
            long afterCloseSleep = 1000;
            try
            {
                afterCloseSleep = Integer.parseInt(fconnectGap.getText().toString());
                afterConnectSleep = Integer.parseInt(fDisconnectGap.getText().toString());
            }
            catch(Exception exception)
            {
                afterConnectSleep = 500;
                afterCloseSleep = 1000;
            }
            while ( fCancelled == false )
            {               
                connect();
                try
                {
                    Thread.sleep(afterConnectSleep);
                }
                catch (InterruptedException exception)
                {
                    exception.printStackTrace();
                }

                close();
                try
                {
                    Thread.sleep(afterCloseSleep);
                }
                catch (InterruptedException exception)
                {
                    exception.printStackTrace();
                }
            }
        }

        public void cancel()
        {
            fCancelled = true;
        }
        private boolean fCancelled;

    }
}

1 个答案:

答案 0 :(得分:0)

这是我在一段时间后报告的关于蓝牙连接失败(确切地说是512)和内存泄漏导致“引用程序溢出”的错误。当我回到我的PC时,我会挖掘链接=)< / p>

链接:http://code.google.com/p/android/issues/detail?id=8676

解决方案:首先通过执行蓝牙发现来查看设备是否在范围内,以避免蓝牙连接失败。如果是,请取消发现并连接到它。