0

我是 Android 开发新手,目前我正在使用 STM32 板和 Android 手机之间的蓝牙串行通信,我参考了这些项目Simple Android Bluetooth Application with Arduino Example和蓝牙聊天示例。我的项目有单独的 connectedThread 类、一个 MainActivity 和 Bluetoothactivity 来处理数据和蓝牙连接。BluetoothActivity 可以连接到连接到 stm32 的 HC-06 并接收数据,但是一旦我在 Mainactivity 和 BluetoothActivity 之间切换,连接就会丢失,而且我无法连接到同一设备,我会收到“连接失败”的消息。我已经阅读了很多关于同一问题的问题,即在 BluetoothSocket 关闭活动之间切换时,一些解决方案暗示使用服务,但事情是我不知道如何使用服务或什么是服务。我希望应用程序即使在活动之间切换时也能保持连接请为此提出解决方案。

我的课程如下: MainActivity

public class MainActivity extends AppCompatActivity {
    public static final String EXTRA_NAME = "com.example.firstmultiscreen.extra.NAME";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    //Go to BluetoothActivity on Button Press
    public void Test_window(View v){
        Toast.makeText(this, "Opening Bluetooth Activity", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(this, BluetoothActivity.class);
        startActivity(intent);
    }
}

ConnectedThread a、b 和 c 变量用于数据包同步

 public class ConnectedThread extends Thread {

    private  BluetoothSocket mmSocket;
    private  InputStream mmInStream;
    private  OutputStream mmOutStream;
    private final Handler mHandler;
    private static final String TAG = "MainActivity";
    byte[] buffer_L1 = new byte[2148];  // buffer store for the stream
    private static int a,b,c;

    public ConnectedThread(BluetoothSocket socket, Handler handler) {

        mmSocket = socket;
        mHandler = handler;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
     }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void run() {

        // Keep listening to the InputStream until an exception occurs
        while (true)
        {
            try
            {
                a=mmInStream.read();
                if(a==9)
                {
                    b=mmInStream.read();
                    if(b==9)
                    {
                       c=mmInStream.read();
                        if(c==9)
                        {
                            mmInStream.read(buffer_L1,0,496);
                            mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, 248, -1, buffer_L1).sendToTarget();
                            try{
                                Thread.sleep(63);
                            }catch (Exception e){

                            }
                        }
                    }
                }
            }
            catch (Exception e) {
                e.printStackTrace();
                break;
            }
        }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(String input) {
        byte[] bytes = input.getBytes();           //converts entered String into bytes
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }

    private void resetConnection() {
      //  setState(STATE_NONE);
        Log.d(TAG, "reset connection");
        if (mmInStream != null) {
        try {
            mmInStream.close();
        } catch (Exception e) {
            Log.d(TAG,"exception in closing inputstream - " + e.getMessage());
        }
        mmInStream = null;
    }
        if (mmOutStream != null) {
        try {
            mmOutStream.close();
        } catch (Exception e) {
            Log.d(TAG,"exception in closing outputstream - " + e.getMessage());
        }
        mmOutStream = null;
    }
        if (mmSocket != null) {
        try {
            mmSocket.close();
        } catch (Exception e) {
            Log.d(TAG,"exception in closing socket - " + e.getMessage());
        }
        mmSocket = null;
    }
}

}

蓝牙活动

 public class BluetoothActivity extends Activity implements PopupMenu.OnMenuItemClickListener {

    byte[] Buffer = new byte[500];
    private final String TAG = MainActivity.class.getSimpleName();
    private static final UUID BT_MODULE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // "random" unique identifier

    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
    public final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
    private final static int CONNECTING_STATUS = 3; // used in bluetooth handler to identify message status

    // GUI Components
    private TextView mBluetoothStatus,mReadBuffer;

    private BluetoothAdapter mBTAdapter;
    private Set<BluetoothDevice> mPairedDevices;
    private ArrayAdapter<String> mBTArrayAdapter;
    private Handler mHandler; // Our main handler that will receive callback notifications
    private com.example.cme.ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
    private BluetoothSocket mBTSocket = null; // bi-directional client-to-client data path

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mBluetoothStatus = (TextView) findViewById(R.id.bluetooth_status);
        mReadBuffer = (TextView) findViewById(R.id.read_buffer);

        mBTArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio

        // Ask for location permission if not already allowed
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);

        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == MESSAGE_READ)
                {
                    String readMessage = null;
                    try
                    {
                          readMessage = new String((byte[]) msg.obj, "UTF-8");
                        Buffer = (byte[]) msg.obj;
                        mReadBuffer.setText(readMessage);
                    } catch (Exception e)
                    {
                        e.printStackTrace();
                    }

                }

                if (msg.what == CONNECTING_STATUS) {
                    if (msg.arg1 == 1)
                        mBluetoothStatus.setText("Connected to Device: " + msg.obj);
                    else
                        mBluetoothStatus.setText("Connection Failed");
                }
            }
        };

        if (mBTArrayAdapter == null) {
            // Device does not support Bluetooth
            mBluetoothStatus.setText("Status: Bluetooth not found");
            Toast.makeText(getApplicationContext(), "Bluetooth device not found!", Toast.LENGTH_SHORT).show();
        }
    }

    public void showMenu(View v) {
        PopupMenu popup = new PopupMenu(this, v);

        // This activity implements OnMenuItemClickListener
        popup.setOnMenuItemClickListener(this);
        popup.inflate(R.menu.example_menu);
        popup.show();
    }

    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                bluetoothOn();
                return true;
            case R.id.item2:
                bluetoothOff();
                return true;
            case R.id.item3:
                //listPairedDevices1();
                // Initializing a new alert dialog
                if (mBTAdapter.isEnabled())
                {
                    ListView listView = new ListView(this);
                    listView.setAdapter(mBTArrayAdapter); // assign model to view
                    listView.setOnItemClickListener(mDeviceClickListener);
                    listPairedDevices();
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setCancelable(true);
                    builder.setView(listView);
                    final AlertDialog dialog = builder.create();
                    dialog.show();
                } else {
                    Toast.makeText(this, "Bluetooth is off!!", Toast.LENGTH_SHORT).show();
                }
                return true;
            case R.id.item4:
                discover();
                return true;
            case R.id.item5:
                //mConnectedThread.
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void bluetoothOn(){
        if (!mBTAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            mBluetoothStatus.setText("Bluetooth enabled");
            Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();

        }
        else{
            Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
        }
    }

    // Enter here after user selects "yes" or "no" to enabling radio
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent Data) {
        // Check which request we're responding to
        super.onActivityResult(requestCode, resultCode, Data);
        if (requestCode == REQUEST_ENABLE_BT) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                // The user picked a contact.
                // The Intent's data Uri identifies which contact was selected.
                mBluetoothStatus.setText("Enabled");
            } else
                mBluetoothStatus.setText("Disabled");
        }
    }

    private void bluetoothOff(){
        mBTAdapter.disable(); // turn off
        mBluetoothStatus.setText("Bluetooth disabled");
        Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
    }

    private void discover(){
        // Check if the device is already discovering
        if(mBTAdapter.isDiscovering()){
            mBTAdapter.cancelDiscovery();
            Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
        }
        else{
            if(mBTAdapter.isEnabled()) {
                mBTArrayAdapter.clear(); // clear items
                mBTAdapter.startDiscovery();
                Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
                registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
            }
            else{
                Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
            }
        }
    }

    final BroadcastReceiver blReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // add the name to the list
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                mBTArrayAdapter.notifyDataSetChanged();
            }
        }
    };

    private void listPairedDevices(){
        mBTArrayAdapter.clear();
        mPairedDevices = mBTAdapter.getBondedDevices();
        if(mBTAdapter.isEnabled()) {
            // put it's one to the adapter
            for (BluetoothDevice device : mPairedDevices)
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());

            Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
        }
        else
            Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
    }

    private final AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            if(!mBTAdapter.isEnabled()) {
                Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
                return;
            }

            mBluetoothStatus.setText("Connecting...");
            // Get the device MAC address, which is the last 17 chars in the View
            String info = ((TextView) view).getText().toString();
            final String address = info.substring(info.length() - 17);
            final String name = info.substring(0,info.length() - 17);

            // Spawn a new thread to avoid blocking the GUI one
            new Thread()
            {
                @Override
                public void run() {
                    boolean fail = false;

                    BluetoothDevice device = mBTAdapter.getRemoteDevice(address);

                    try {
                        mBTSocket = createBluetoothSocket(device);
                    } catch (IOException e) {
                        fail = true;
                        Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
                    }
                    // Establish the Bluetooth socket connection.
                    try {
                        mBTSocket.connect();
                    } catch (IOException e) {
                        try {
                            fail = true;
                            mBTSocket.close();
                            mHandler.obtainMessage(CONNECTING_STATUS, -1, -1)
                                    .sendToTarget();
                        } catch (IOException e2) {
                            //insert code to deal with this
                            Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                    if(!fail) {
                        mConnectedThread = new com.example.cme.ConnectedThread(mBTSocket, mHandler);
                        mConnectedThread.start();

                        mHandler.obtainMessage(CONNECTING_STATUS, 1, -1, name)
                                .sendToTarget();
                    }
                }
            }.start();
        }
    };

    private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
        try {
            final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
            return (BluetoothSocket) m.invoke(device, BT_MODULE_UUID);
        } catch (Exception e) {
            Log.e(TAG, "Could not create Insecure RFComm Connection",e);
        }
        return  device.createRfcommSocketToServiceRecord(BT_MODULE_UUID);
    }
}

4

0 回答 0